#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <stdbool.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"
+#endif
+
+#ifdef TCP_ADAPTER
+#include "catcpadapter.h"
+#endif
+
+CAGlobals_t caglobals = { .clientFlags = 0,
+ .serverFlags = 0, };
+
+#define TAG "OIC_CA_CONN_MGR"
-#define TAG PCF("CA")
+static bool g_isInitialized = false;
#ifdef __WITH_DTLS__
// CAAdapterNetDTLS will register the callback.
// Taking callback all the way through adapters not the right approach, hence calling here.
-extern void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback);
+extern void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
+#endif
+
+#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()
{
+ OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
OIC_LOG(DEBUG, TAG, "CAInitialize");
- return CAInitializeMessageHandler();;
+ if (!g_isInitialized)
+ {
+ if (0 != OCSeedRandom())
+ {
+ OIC_LOG(ERROR, TAG, "Seed Random Failed");
+ }
+
+ CAResult_t res = CAInitializeMessageHandler();
+ if (res != CA_STATUS_OK)
+ {
+ OIC_LOG(ERROR, TAG, "CAInitialize has failed");
+ return res;
+ }
+ g_isInitialized = true;
+ }
+
+ return CA_STATUS_OK;
}
void CATerminate()
{
OIC_LOG(DEBUG, TAG, "CATerminate");
- CATerminateMessageHandler();
+ if (g_isInitialized)
+ {
+ CATerminateMessageHandler();
+ CATerminateNetworkType();
- CATerminateNetworkType();
+ g_isInitialized = false;
+ }
}
CAResult_t CAStartListeningServer()
{
OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
+ 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)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
return CAStartDiscoveryServerAdapters();
}
-void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
+ CAErrorCallback ErrorHandler)
{
OIC_LOG(DEBUG, TAG, "CARegisterHandler");
- CASetRequestResponseCallbacks(ReqHandler, RespHandler);
+ if(!g_isInitialized)
+ {
+ OIC_LOG(DEBUG, TAG, "CA is not initialized");
+ return;
+ }
+
+ CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
}
#ifdef __WITH_DTLS__
-CAResult_t CARegisterDTLSCredentialsHandler(
- CAGetDTLSCredentialsHandler GetDTLSCredentialsHandler)
+CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
+{
+ OIC_LOG(DEBUG, TAG, "CARegisterDTLSHandshakeCallback");
+
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
+ CADTLSSetHandshakeCallback(dtlsHandshakeCallback);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
{
OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
+
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
return CA_STATUS_OK;
}
#endif //__WITH_DTLS__
-CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, const CATransportType_t transportType,
- CARemoteEndpoint_t **remoteEndpoint)
+#ifdef __WITH_X509__
+CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
{
- OIC_LOG(DEBUG, TAG, "CACreateRemoteEndpoint");
+ OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
- CARemoteEndpoint_t *remote = CACreateRemoteEndpointUriInternal(uri, transportType);
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
- if (remote == NULL)
+ CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
+{
+ OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
+
+ if(!g_isInitialized)
{
- OIC_LOG(DEBUG, TAG, "remote is NULL!");
- return CA_STATUS_FAILED;
+ return CA_STATUS_NOT_INITIALIZED;
}
- *remoteEndpoint = remote;
+ CADTLSSetCrlCallback(GetDTLSCrlHandler);
+ return CA_STATUS_OK;
+}
+#endif //__WITH_X509__
+
+CAResult_t CACreateEndpoint(CATransportFlags_t flags,
+ CATransportAdapter_t adapter,
+ const char *addr,
+ uint16_t port,
+ CAEndpoint_t **object)
+{
+ if (!object)
+ {
+ OIC_LOG(ERROR, TAG, "Invalid Parameter");
+ return CA_STATUS_INVALID_PARAM;
+ }
+ CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
+ if (!endpoint)
+ {
+ return CA_STATUS_FAILED;
+ }
+ *object = endpoint;
return CA_STATUS_OK;
}
-void CADestroyRemoteEndpoint(CARemoteEndpoint_t *rep)
+void CADestroyEndpoint(CAEndpoint_t *rep)
{
- OIC_LOG(DEBUG, TAG, "CADestroyRemoteEndpoint");
+ OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
- CADestroyRemoteEndpointInternal(rep);
+ CAFreeEndpoint(rep);
}
CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
OIC_LOG(DEBUG, TAG, "CADestroyToken");
CADestroyTokenInternal(token);
+
+ OIC_LOG(DEBUG, TAG, "OUT");
}
-CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size)
+CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
{
OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
return CAGetNetworkInformationInternal(info, size);
}
-CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token, uint8_t tokenLength)
+static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
+ CADataType_t dataType)
{
- OIC_LOG(DEBUG, TAG, "CAFindResource");
+ OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
- return CADetachMessageResourceUri(resourceUri, token, tokenLength, NULL, 0);
+ 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)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
-CAResult_t CASendRequest(const CARemoteEndpoint_t *object,const CARequestInfo_t *requestInfo)
-{
- OIC_LOG(DEBUG, TAG, "CASendGetRequest");
+ CAResult_t ret = CA_STATUS_OK;
+ size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
- return CADetachRequestMessage(object, requestInfo);
+ 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 CASendRequestToAll(const CAGroupEndpoint_t *object,
- const CARequestInfo_t *requestInfo)
+CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
{
- OIC_LOG(DEBUG, TAG, "CASendRequestToAll");
+ OIC_LOG(DEBUG, TAG, "CASendRequest");
- return CADetachRequestToAllMessage(object, requestInfo);
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
+ if (requestInfo && requestInfo->isMulticast &&
+ (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
+ {
+ return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
+ }
+ else
+ {
+ return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
+ }
}
-CAResult_t CASendNotification(const CARemoteEndpoint_t *object,
- const CAResponseInfo_t *responseInfo)
+CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
{
- OIC_LOG(DEBUG, TAG, "CASendNotification");
+ OIC_LOG(DEBUG, TAG, "CASendResponse");
- return CADetachResponseMessage(object, responseInfo);
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+ if (responseInfo && responseInfo->isMulticast &&
+ (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
+ {
+ return CASendMessageMultiAdapter(object, responseInfo, CA_RESPONSE_DATA);
+ }
+ else
+ {
+ return CADetachSendMessage(object, responseInfo, CA_RESPONSE_DATA);
+ }
}
-CAResult_t CASendResponse(const CARemoteEndpoint_t *object,
- const CAResponseInfo_t *responseInfo)
+CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
{
- OIC_LOG(DEBUG, TAG, "CASendResponse");
+ OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
- return CADetachResponseMessage(object, responseInfo);
+ if(!g_isInitialized)
+ {
+ return CA_STATUS_NOT_INITIALIZED;
+ }
-}
+ CAResult_t res = CA_STATUS_OK;
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri,const CAToken_t token,
- uint8_t tokenLength, const CAHeaderOption_t *options,
- const uint8_t numOptions)
-{
- OIC_LOG(DEBUG, TAG, "CAAdvertiseResource");
+ if (interestedNetwork & CA_ADAPTER_IP)
+ {
+ res = CAAddNetworkType(CA_ADAPTER_IP);
+ 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(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(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
+ }
- return CADetachMessageResourceUri(resourceUri, token, tokenLength, options, numOptions);
+#ifdef RA_ADAPTER
+ else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
+ {
+ res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
+ 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);
+ }
+ else
+ {
+ res = CA_NOT_SUPPORTED;
+ }
+ return res;
}
-CAResult_t CASelectNetwork(const uint32_t interestedNetwork)
+CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
{
- OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
+ OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
- if (!(interestedNetwork & 0xf))
+ if(!g_isInitialized)
{
- return CA_NOT_SUPPORTED;
+ return CA_STATUS_NOT_INITIALIZED;
}
CAResult_t res = CA_STATUS_OK;
- if (interestedNetwork & CA_IPV4)
+ if (nonInterestedNetwork & CA_ADAPTER_IP)
{
- res = CAAddNetworkType(CA_IPV4);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_IPV4) function returns error : %d", res);
+ res = CARemoveNetworkType(CA_ADAPTER_IP);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
}
-
- if (interestedNetwork & CA_EDR)
+ else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
{
- res = CAAddNetworkType(CA_EDR);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_EDR) function returns error : %d", res);
+ res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
+ 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(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
+ }
+#ifdef RA_ADAPTER
+ else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
+ {
+ res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
+ res);
+ }
+#endif
+
- if (interestedNetwork & CA_LE)
+#ifdef TCP_ADAPTER
+ else if (nonInterestedNetwork & CA_ADAPTER_TCP)
{
- res = CAAddNetworkType(CA_LE);
- OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_LE) function returns error : %d", res);
+ res = CARemoveNetworkType(CA_ADAPTER_TCP);
+ OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
+ res);
}
+#endif
+ else
+ {
+ res = CA_STATUS_FAILED;
+ }
return res;
}
-CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork)
+CAResult_t CAHandleRequestResponse()
{
- OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
-
- if (!(nonInterestedNetwork & 0xf))
+ if (!g_isInitialized)
{
- return CA_NOT_SUPPORTED;
+ OIC_LOG(ERROR, TAG, "not initialized");
+ return CA_STATUS_NOT_INITIALIZED;
}
+ CAHandleRequestResponseCallbacks();
+
+ return CA_STATUS_OK;
+}
+
+#ifdef __WITH_DTLS__
+CAResult_t CASelectCipherSuite(const uint16_t cipher)
+{
+ OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
+
+ return CADtlsSelectCipherSuite(cipher);
+}
+
+CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
+{
+ OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
+
+ return CADtlsEnableAnonECDHCipherSuite(enable);
+}
+
+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)
+{
+ OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
+
CAResult_t res = CA_STATUS_OK;
- if (nonInterestedNetwork & CA_IPV4)
+ //newOwnerLabel and prevOwnerLabe can be NULL
+ if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
{
- res = CARemoveNetworkType(CA_IPV4);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_IPV4) function returns error : %d", res);
+ return CA_STATUS_INVALID_PARAM;
}
- if (nonInterestedNetwork & CA_EDR)
+ res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
+ rsrcServerDeviceID, rsrcServerDeviceIDLen,
+ provServerDeviceID, provServerDeviceIDLen,
+ ownerPSK, ownerPSKSize);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
+ }
+
+ 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;
+
+ if (!endpoint)
{
- res = CARemoveNetworkType(CA_EDR);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_EDR) function returns error : %d", res);
+ return CA_STATUS_INVALID_PARAM;
}
- if (nonInterestedNetwork & CA_LE)
+ res = CADtlsInitiateHandshake(endpoint);
+ if (CA_STATUS_OK != res)
{
- res = CARemoveNetworkType(CA_LE);
- OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_LE) function returns error : %d", res);
+ OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
}
+ OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
+
return res;
}
-CAResult_t CAHandleRequestResponse()
+CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
{
- OIC_LOG(DEBUG, TAG, "CAHandleRequestResponse");
+ OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
+ CAResult_t res = CA_STATUS_OK;
- CAHandleRequestResponseCallbacks();
+ if (!endpoint)
+ {
+ return CA_STATUS_INVALID_PARAM;
+ }
- return CA_STATUS_OK;
+ res = CADtlsClose(endpoint);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
+
+ return res;
}
+#endif /* __WITH_DTLS__ */
+#ifdef TCP_ADAPTER
+void CARegisterKeepAliveHandler(CAKeepAliveConnectedCallback ConnHandler,
+ CAKeepAliveDisconnectedCallback DisconnHandler)
+{
+ CATCPSetKeepAliveCallbacks(ConnHandler, DisconnHandler);
+}
+#endif