#include <stdint.h>
#include <stdbool.h>
+#include "octypes.h"
+#include "ocrandom.h"
#include "cainterface.h"
#include "caremotehandler.h"
#include "camessagehandler.h"
#include "canetworkconfigurator.h"
#include "cainterfacecontroller.h"
#include "logger.h"
-#ifdef __WITH_DTLS__
-#include "caadapternetdtls.h"
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "ca_adapter_net_ssl.h"
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+#ifdef TCP_ADAPTER
+#include "catcpadapter.h"
#endif
-CAGlobals_t caglobals = { 0 };
+CAGlobals_t caglobals = { .clientFlags = 0,
+ .serverFlags = 0, };
-#define TAG "CA_CONN_MGR"
+#define TAG "OIC_CA_CONN_MGR"
static bool g_isInitialized = false;
-#ifdef __WITH_DTLS__
-// CAAdapterNetDTLS will register the callback.
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
// Taking callback all the way through adapters not the right approach, hence calling here.
-extern void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback);
-#endif
+extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
+extern void CAsetPskCredentialsCallback(CAgetPskCredentialsHandler credCallback);
+extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
+extern void CAsetSetupPkContextCallback(CAsetupPkContextHandler setupPkCtxCallback);
+#endif // __WITH_DTLS__ or __WITH_TLS__
-#ifdef __WITH_X509__
-// CAAdapterNetDTLS will register the callback.
-// Taking callback all the way through adapters not the right approach, hence calling here.
-extern void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback);
-extern void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback);
-#endif
-CAResult_t CAInitialize()
+CAResult_t CAInitialize(CATransportAdapter_t transportType)
{
- OIC_LOG(DEBUG, TAG, "CAInitialize");
+ OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
+ OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
if (!g_isInitialized)
{
- CAResult_t res = CAInitializeMessageHandler();
+ if (0 != OCSeedRandom())
+ {
+ OIC_LOG(ERROR, TAG, "Seed Random Failed");
+ }
+
+ CAResult_t res = CAInitializeMessageHandler(transportType);
if (res != CA_STATUS_OK)
{
OIC_LOG(ERROR, TAG, "CAInitialize has failed");
+ CATerminateMessageHandler();
return res;
}
g_isInitialized = true;
}
+
return CA_STATUS_OK;
}
{
OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
return CAStartListeningServerAdapters();
}
+CAResult_t CAStopListeningServer()
+{
+ OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
+
+ if (!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
+ return CAStopListeningServerAdapters();
+}
+
CAResult_t CAStartDiscoveryServer()
{
OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
{
OIC_LOG(DEBUG, TAG, "CARegisterHandler");
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
OIC_LOG(DEBUG, TAG, "CA is not initialized");
return;
CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
}
-#ifdef __WITH_DTLS__
-CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSCredentialsHandler)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#ifdef MULTIPLE_OWNER
+const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
{
- OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
+ OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
+ if (!g_isInitialized)
+ {
+ OIC_LOG(DEBUG, TAG, "CA is not initialized");
+ return NULL;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
+ return GetCASecureEndpointData(peer);
+}
+#endif //MULTIPLE_OWNER
+
+CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
+{
+ OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
if(!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
- CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
+ CAsetSslHandshakeCallback(tlsHandshakeCallback);
return CA_STATUS_OK;
}
-#endif //__WITH_DTLS__
-#ifdef __WITH_X509__
-CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
+CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
{
- OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
+ CAsetPskCredentialsCallback(getTlsCredentialsHandler);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
+{
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
- CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
+ if (!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+ CAsetPkixInfoCallback(getPkixInfoHandler);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return CA_STATUS_OK;
}
-CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
+CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
{
- OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
+ CAsetCredentialTypesCallback(getCredTypesHandler);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAregisterSetupPkContextHandler(CAsetupPkContextHandler setupPkContextCallback)
+{
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
- CADTLSSetCrlCallback(GetDTLSCrlHandler);
+ if (!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+ CAsetSetupPkContextCallback(setupPkContextCallback);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return CA_STATUS_OK;
}
-#endif //__WITH_X509__
+#endif // __WITH_DTLS__ or __WITH_TLS__
CAResult_t CACreateEndpoint(CATransportFlags_t flags,
CATransportAdapter_t adapter,
{
OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
return CAGetNetworkInformationInternal(info, size);
}
-CAResult_t CASendRequest(const CAEndpoint_t *object,const CARequestInfo_t *requestInfo)
+static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
+ CADataType_t dataType)
{
- OIC_LOG(DEBUG, TAG, "CASendGetRequest");
+ OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
- if(!g_isInitialized)
+ CATransportAdapter_t connTypes[] = {
+ CA_ADAPTER_IP
+#ifdef LE_ADAPTER
+ ,CA_ADAPTER_GATT_BTLE
+#endif
+#ifdef EDR_ADAPTER
+ ,CA_ADAPTER_RFCOMM_BTEDR
+#endif
+#ifdef NFC_ADAPTER
+ ,CA_ADAPTER_NFC
+#endif
+#ifdef RA_ADAPTER
+ ,CA_ADAPTER_REMOTE_ACCESS
+#endif
+#ifdef TCP_ADAPTER
+ ,CA_ADAPTER_TCP
+#endif
+ };
+
+ CAEndpoint_t *cloneEp = CACloneEndpoint(object);
+ if (!cloneEp)
{
- return CA_STATUS_NOT_INITIALIZED;
+ OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
+ return CA_MEMORY_ALLOC_FAILED;
}
- return CADetachRequestMessage(object, requestInfo);
+ CAResult_t ret = CA_STATUS_OK;
+ size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
+
+ for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
+ {
+ cloneEp->adapter = connTypes[i];
+ ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
+ }
+ CAFreeEndpoint(cloneEp);
+ return ret;
}
-CAResult_t CASendNotification(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
+CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
{
- OIC_LOG(DEBUG, TAG, "CASendNotification");
+ OIC_LOG(DEBUG, TAG, "CASendRequest");
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
- return CADetachResponseMessage(object, responseInfo);
+ if (requestInfo && requestInfo->isMulticast &&
+ (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
+ {
+ return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
+ }
+ else if (requestInfo && requestInfo->info.event == CA_REQ_DISCONNECT &&
+ (object->adapter == CA_ADAPTER_TCP || object->adapter == CA_ALL_ADAPTERS))
+ {
+ return CADetachSendNetworkReqMessage(object, requestInfo->info.event, CA_NETWORK_COMMAND);
+ }
+ else
+ {
+ return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
+ }
}
CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
{
OIC_LOG(DEBUG, TAG, "CASendResponse");
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
- return CADetachResponseMessage(object, responseInfo);
+ if (!responseInfo || !object)
+ {
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ if (responseInfo->isMulticast &&
+ (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
+ {
+ return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
+ }
+ else
+ {
+ return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
+ }
}
CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
{
- OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
-
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
if (interestedNetwork & CA_ADAPTER_IP)
{
res = CAAddNetworkType(CA_ADAPTER_IP);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns error : %d", res);
+ OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
}
else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
{
res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns error : %d", res);
+ OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
}
else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
{
res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
+ OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
}
- #ifdef RA_ADAPTER
+#ifdef RA_ADAPTER
else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
{
res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
- res);
+ OIC_LOG_V(DEBUG, TAG,
+ "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
+ }
+#endif
+
+#ifdef TCP_ADAPTER
+ else if (interestedNetwork & CA_ADAPTER_TCP)
+ {
+ res = CAAddNetworkType(CA_ADAPTER_TCP);
+ OIC_LOG_V(DEBUG, TAG,
+ "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
+ }
+#endif
+ else if (interestedNetwork & CA_ADAPTER_NFC)
+ {
+ res = CAAddNetworkType(CA_ADAPTER_NFC);
+ OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
}
- #endif
else
{
res = CA_NOT_SUPPORTED;
{
OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
- if(!g_isInitialized)
+ if (!g_isInitialized)
{
return CA_STATUS_NOT_INITIALIZED;
}
if (nonInterestedNetwork & CA_ADAPTER_IP)
{
res = CARemoveNetworkType(CA_ADAPTER_IP);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns error : %d", res);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
}
else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
{
res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns error : %d", res);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
}
else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
{
res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
}
- #ifdef RA_ADAPTER
+#ifdef RA_ADAPTER
else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
{
res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
- res);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
+ res);
+ }
+#endif
+
+
+#ifdef TCP_ADAPTER
+ else if (nonInterestedNetwork & CA_ADAPTER_TCP)
+ {
+ res = CARemoveNetworkType(CA_ADAPTER_TCP);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
+ res);
}
- #endif
+#endif
+
else
{
res = CA_STATUS_FAILED;
return CA_STATUS_OK;
}
-#ifdef __WITH_DTLS__
-
-CAResult_t CASelectCipherSuite(const uint16_t cipher)
+CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
{
- OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
-
- return CADtlsSelectCipherSuite(cipher);
+ OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+ OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
+ CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
+ res = CAsetTlsCipherSuite(cipher);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
+ }
+#else
+ OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+ return res;
}
CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
{
OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
-
- return CADtlsEnableAnonECDHCipherSuite(enable);
+ CAResult_t res = CA_STATUS_FAILED;
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 0xFF00 replaces 0xC018
+ res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
+ }
+#else
+ OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+ OIC_LOG_V(ERROR, TAG, "Out %s", __func__);
+ return res;
}
CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
const uint8_t* label, const size_t labelLen,
const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
- uint8_t* ownerPSK, const size_t ownerPSKSize)
+ uint8_t* ownerPSK, const size_t ownerPskSize)
{
OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
-
- CAResult_t res = CA_STATUS_OK;
-
+ CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
//newOwnerLabel and prevOwnerLabe can be NULL
- if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
+ if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
{
return CA_STATUS_INVALID_PARAM;
}
- res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
- rsrcServerDeviceID, rsrcServerDeviceIDLen,
- provServerDeviceID, provServerDeviceIDLen,
- ownerPSK, ownerPSKSize);
+ res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
+ rsrcServerDeviceID, rsrcServerDeviceIDLen,
+ provServerDeviceID, provServerDeviceIDLen,
+ ownerPSK, ownerPskSize);
if (CA_STATUS_OK != res)
{
OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
}
-
+#else
+ OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
-
return res;
}
CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
{
OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
- CAResult_t res = CA_STATUS_OK;
-
+ CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
if (!endpoint)
{
return CA_STATUS_INVALID_PARAM;
}
- res = CADtlsInitiateHandshake(endpoint);
+ res = CAinitiateSslHandshake(endpoint);
if (CA_STATUS_OK != res)
{
- OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
+ OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
}
-
+#else
+ OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
-
return res;
}
-CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
+CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
{
- OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
- CAResult_t res = CA_STATUS_OK;
-
+ OIC_LOG_V(DEBUG, TAG, "IN : CAcloseSslSession");
+ CAResult_t res = CA_STATUS_FAILED;
+#if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
if (!endpoint)
{
return CA_STATUS_INVALID_PARAM;
}
- res = CADtlsClose(endpoint);
+ res = CAcloseSslConnection(endpoint);
if (CA_STATUS_OK != res)
{
- OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
+ OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
}
-
- OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
-
+#else
+ OIC_LOG(ERROR, TAG, "Method not supported");
+#endif
+ OIC_LOG_V(DEBUG, TAG, "OUT : CAcloseSslSession");
return res;
}
-#endif /* __WITH_DTLS__ */
+#ifdef TCP_ADAPTER
+void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
+{
+ CATCPSetKeepAliveCallbacks(ConnHandler);
+}
+#endif