ThingWorx Edge C SDK > How to Set Up an Application > Initializing the Tunnel Manager (Optional)
  
Initializing the Tunnel Manager (Optional)
If using the tunneling capability of the C SDK, you must create #define ENABLE_TUNNELING. When you initialize the API, a tunnel manager singleton is automatically created for you. If you wish to disable tunneling for any reason you can call twTunnelManager_Delete(). The tunnel manager can be started up again by calling twTunnelManager_Create(). Once the tunnel manager is running you can register any callback functions. Passing a NULL for the id parameter when registering a callback results in callbacks for all tunnel events.
/* Register the tunnel callback function */
twTunnelManager_RegisterTunnelCallback(tunnelCallbackFunc, NULL, NULL);
When new tunnels are requested by the ThingWorx Platform, the tunnel manager creates a new tunnel. These tunnels establish an independent WebSocket back to the platform. By default these WebSockets connect back to the same host/port that the API’s WebSocket uses and they use the same TLS certificate validation criteria. You can override these defaults by using the built-in tunnel manager functions as found in the file, twTunnelManager.h:
int twTunnelManager_UpdateTunnelServerInfo(char * host,
uint16_t port, appKeyCallback);
void twTunnelManager_SetProxyInfo(char * proxyHost, uint16_t proxyPort,
char * proxyUser, twPasswdCallbackFunction proxyPassCallback);
void twTunnelManager_SetSelfSignedOk(char state);
void twTunnelManager_EnableFipsMode(char state);
void twTunnelManager_DisableCertValidation(char state);
void twTunnelManager_DisableEncryption(char state);
void twTunnelManager_SetX509Fields(char * subject_cn, char * subject_o,
char * subject_ou, char * issuer_cn,
char * issuer_o, char * issuer_ou);
void twTunnelManager_LoadCACert(const char *file, int type);
void twTunnelManager_LoadClientCert(char *file);
void twTunnelManager_SetClientKey(const char *file, clientKeyPassphrase, int type);
Notice that output of the appKeyCallback() and twPasswdCallbackFunction functions is used by the TunnelManager for security:
The twTunnelManager_UpdateTunnelServerInfo() function uses the output of the appKeyCallback() function, which is represented as appKeyCallback.
The twTunnelManager_setProxyInfo() function uses the output of the twPasswdCallbackFunction, which is represented by proxyPassCallback.
The twTunnelManager_SetClientKey() function uses the output of the twPasswdCallbackFunction, which is represented by clientKeyPassphrase.
This change is present in v.2.2.0 and later versions of the C SDK. For details about the appKeyCallback function, refer to the explanation of the first code sample of “Innitializing the API Singleton”. The password callback is explained in the section, Password Callback Functions (C SDK 2.2.0 and later).
Using the Built-in Tasker Function
If you are using the built-in tasker, continue to the next section. However, if you are not using the built-in tasker, you must call the function twTunnelManager_TaskerFunction frequently. The examples default to every 5 milliseconds. The setting to use here depends on the use case and environment. Before using this function, read the section, . twTunnelManager_TaskerFunction and Tick Resolution.
Connection Information for the Tunnel Manager
By default the twTunnelManager uses the same twConnectionInfo structure as twApi so that all twConnectionInfo settings should be shared by twApi and twTunnelManager.
twTunnelManager_TaskerFunction and Tick Resolution
Tunnel performance can be greatly affected by the thread’s tick_resolution of the twTunnelManager_TaskerFunction. When the tunnel manager thread is being created, the tick resolution determines how fast a tunnel manager checks the status of its managed tunnels. The smaller this value, the faster the tunnel responds. Tick resolution is especially important when running multiple tunnels concurrently, but be aware that a smaller tick resolution consumes more CPU resources. For an example, refer to the example application called “SteamSensorWithThreads.” Refer to Running the C SDK on Windows-based Operating Systems
Tunneling and Proxy Servers
When using a proxy server, you must set both the initial proxy with twApi_SetProxyInfo and the proxy for tunneling with twTunnelManager_SetProxyInfo. Both proxies are required; otherwise, the tunneling will fail. To set up the initial proxy, refer to Proxy Server Authentication.
Use the following function to set up communication through a proxy server for tunneling:
twTunnelManager_SetProxyInfo(char * proxyHost, uint16_t proxyPort,
char * proxyUser, twPasswdCallbackFunction proxyPassCallback);
The following table describes the parameters you can specify:
Parameter
Description
proxyHost
The IP address or host name of the proxy server to use for tunneling.
proxyPort
The number of the port on the proxy server to use.
proxyUser
If the proxy server requires Basic or Digest authentication, use the callback function, twPassword
passwdCallback
For a password, you must provide a password callback function so the ThingWorx SDK can obtain a copy of the tunnel password from your application.
Refer to the next section for more information about passwords and the password callback functions.
Password Callback Functions (C SDK 2.2.0 and later)
As of v.2.2.0 of the C SDK, password protection is your responsibility. For the C SDK to use a password such as a proxy password or a passphrase, you need to develop a way for the password to be provided securely to the following callback function:
typedef void (*twPasswdCallbackFunction)(char * passwdBuffer, unsigned int maxPasswdSize);
For example, the TunnelManager uses the output of twPasswdCallbackFunction for a proxy password and a client key passphrase. This callback function is called when the C SDK requires the current password for a proxy server user or a digest to authenticate with the ThingWorx Platform.
* 
In production, this callback should obtain a password or a digest from a secure source.
Tunnel Manager and OpenSSL
When the tunnel manager is initialized, it points its {{tm->info}} struct at {{tw_api->connectionInfo}}, so that any API settings are realized in the tunnel manager. However, if you call any functions that set tunnel manager settings, such as {{twTunnelManager_DisableCertValidation()}}, then the C SDK actually creates a new struct to set the tunnel manager specific settings, and any subsequent calls to set API connection information (like loading a cert) will no longer be realized in the tunnel manager. Refer to the API documentation for the C SDK.