1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
27 #include "cainterface.h"
28 #include "caremotehandler.h"
29 #include "camessagehandler.h"
30 #include "caprotocolmessage.h"
31 #include "canetworkconfigurator.h"
32 #include "cainterfacecontroller.h"
35 #include "caadapternetdtls.h"
39 #include "catcpadapter.h"
41 #include "ca_adapter_net_tls.h"
45 CAGlobals_t caglobals = { .clientFlags = 0,
48 #define TAG "OIC_CA_CONN_MGR"
50 static bool g_isInitialized = false;
53 // CAAdapterNetDTLS will register the callback.
54 // Taking callback all the way through adapters not the right approach, hence calling here.
55 extern void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
59 // CAAdapterNetDTLS will register the callback.
60 // Taking callback all the way through adapters not the right approach, hence calling here.
61 extern void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback);
62 extern void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback);
66 extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
67 extern void CAsetTlsCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
71 CAResult_t CAInitialize()
73 OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
74 OIC_LOG(DEBUG, TAG, "CAInitialize");
78 if (0 != OCSeedRandom())
80 OIC_LOG(ERROR, TAG, "Seed Random Failed");
83 CAResult_t res = CAInitializeMessageHandler();
84 if (res != CA_STATUS_OK)
86 OIC_LOG(ERROR, TAG, "CAInitialize has failed");
89 g_isInitialized = true;
97 OIC_LOG(DEBUG, TAG, "CATerminate");
101 CATerminateMessageHandler();
102 CATerminateNetworkType();
104 g_isInitialized = false;
108 CAResult_t CAStartListeningServer()
110 OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
112 if (!g_isInitialized)
114 return CA_STATUS_NOT_INITIALIZED;
117 return CAStartListeningServerAdapters();
120 CAResult_t CAStopListeningServer()
122 OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
124 if (!g_isInitialized)
126 return CA_STATUS_NOT_INITIALIZED;
129 return CAStopListeningServerAdapters();
132 CAResult_t CAStartDiscoveryServer()
134 OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
136 if (!g_isInitialized)
138 return CA_STATUS_NOT_INITIALIZED;
141 return CAStartDiscoveryServerAdapters();
144 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
145 CAErrorCallback ErrorHandler)
147 OIC_LOG(DEBUG, TAG, "CARegisterHandler");
149 if (!g_isInitialized)
151 OIC_LOG(DEBUG, TAG, "CA is not initialized");
155 CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
159 CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
161 OIC_LOG(DEBUG, TAG, "CARegisterDTLSHandshakeCallback");
163 if (!g_isInitialized)
165 return CA_STATUS_NOT_INITIALIZED;
168 CADTLSSetHandshakeCallback(dtlsHandshakeCallback);
173 CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
175 OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
177 if (!g_isInitialized)
179 return CA_STATUS_NOT_INITIALIZED;
182 CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
185 #endif //__WITH_DTLS__
187 CAResult_t CAregisterTlsHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
189 OIC_LOG(DEBUG, TAG, "CARegisterTlsHandshakeCallback");
193 return CA_STATUS_NOT_INITIALIZED;
196 CAsetTlsHandshakeCallback(tlsHandshakeCallback);
200 CAResult_t CAregisterTlsCredentialsHandler(CAGetDTLSPskCredentialsHandler getTlsCredentialsHandler)
202 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
204 if (!g_isInitialized)
206 return CA_STATUS_NOT_INITIALIZED;
208 CAsetTlsCredentialsCallback(getTlsCredentialsHandler);
209 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
213 void GetPkixInfo(PkiInfo_t * inf)
215 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
216 GetDerOwnCert(&inf->crt);
217 GetDerKey(&inf->key);
218 GetDerCaCert(&inf->ca);
219 GetDerCrl(&inf->crl);
220 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
223 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
225 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
227 if (!g_isInitialized)
229 return CA_STATUS_NOT_INITIALIZED;
231 CAsetPkixInfoCallback(getPkixInfoHandler);
232 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
238 CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
240 OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
242 if (!g_isInitialized)
244 return CA_STATUS_NOT_INITIALIZED;
247 CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
251 CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
253 OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
255 if (!g_isInitialized)
257 return CA_STATUS_NOT_INITIALIZED;
260 CADTLSSetCrlCallback(GetDTLSCrlHandler);
263 #endif //__WITH_X509__
265 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
266 CATransportAdapter_t adapter,
269 CAEndpoint_t **object)
273 OIC_LOG(ERROR, TAG, "Invalid Parameter");
274 return CA_STATUS_INVALID_PARAM;
277 CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
280 return CA_STATUS_FAILED;
286 void CADestroyEndpoint(CAEndpoint_t *rep)
288 OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
293 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
295 OIC_LOG(DEBUG, TAG, "CAGenerateToken");
297 return CAGenerateTokenInternal(token, tokenLength);
300 void CADestroyToken(CAToken_t token)
302 OIC_LOG(DEBUG, TAG, "CADestroyToken");
304 CADestroyTokenInternal(token);
306 OIC_LOG(DEBUG, TAG, "OUT");
309 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
311 OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
313 if (!g_isInitialized)
315 return CA_STATUS_NOT_INITIALIZED;
318 return CAGetNetworkInformationInternal(info, size);
321 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
322 CADataType_t dataType)
324 OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
326 CATransportAdapter_t connTypes[] = {
329 ,CA_ADAPTER_GATT_BTLE
332 ,CA_ADAPTER_RFCOMM_BTEDR
338 ,CA_ADAPTER_REMOTE_ACCESS
345 CAEndpoint_t *cloneEp = CACloneEndpoint(object);
348 OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
349 return CA_MEMORY_ALLOC_FAILED;
352 CAResult_t ret = CA_STATUS_OK;
353 size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
355 for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
357 cloneEp->adapter = connTypes[i];
358 ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
360 CAFreeEndpoint(cloneEp);
364 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
366 OIC_LOG(DEBUG, TAG, "CASendRequest");
368 if (!g_isInitialized)
370 return CA_STATUS_NOT_INITIALIZED;
373 if (requestInfo && requestInfo->isMulticast &&
374 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
376 return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
380 return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
384 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
386 OIC_LOG(DEBUG, TAG, "CASendResponse");
388 if (!g_isInitialized)
390 return CA_STATUS_NOT_INITIALIZED;
393 if (!responseInfo || !object)
395 return CA_STATUS_INVALID_PARAM;
398 if (responseInfo->isMulticast &&
399 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
401 return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
405 return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
409 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
411 OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
413 if (!g_isInitialized)
415 return CA_STATUS_NOT_INITIALIZED;
418 CAResult_t res = CA_STATUS_OK;
420 if (interestedNetwork & CA_ADAPTER_IP)
422 res = CAAddNetworkType(CA_ADAPTER_IP);
423 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
425 else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
427 res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
428 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
430 else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
432 res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
433 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
437 else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
439 res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
440 OIC_LOG_V(DEBUG, TAG,
441 "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
446 else if (interestedNetwork & CA_ADAPTER_TCP)
448 res = CAAddNetworkType(CA_ADAPTER_TCP);
449 OIC_LOG_V(DEBUG, TAG,
450 "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
453 else if (interestedNetwork & CA_ADAPTER_NFC)
455 res = CAAddNetworkType(CA_ADAPTER_NFC);
456 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
460 res = CA_NOT_SUPPORTED;
465 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
467 OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
469 if (!g_isInitialized)
471 return CA_STATUS_NOT_INITIALIZED;
474 CAResult_t res = CA_STATUS_OK;
476 if (nonInterestedNetwork & CA_ADAPTER_IP)
478 res = CARemoveNetworkType(CA_ADAPTER_IP);
479 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
481 else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
483 res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
484 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
486 else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
488 res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
489 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
492 else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
494 res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
495 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
502 else if (nonInterestedNetwork & CA_ADAPTER_TCP)
504 res = CARemoveNetworkType(CA_ADAPTER_TCP);
505 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
512 res = CA_STATUS_FAILED;
517 CAResult_t CAHandleRequestResponse()
519 if (!g_isInitialized)
521 OIC_LOG(ERROR, TAG, "not initialized");
522 return CA_STATUS_NOT_INITIALIZED;
525 CAHandleRequestResponseCallbacks();
530 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
531 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
533 OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
534 if(CA_ADAPTER_IP == adapter)
536 if (CA_STATUS_OK != CADtlsSelectCipherSuite(cipher))
538 return CA_STATUS_FAILED;
542 else if(CA_ADAPTER_TCP == adapter)
544 if (CA_STATUS_OK != CAsetTlsCipherSuite(cipher))
546 return CA_STATUS_FAILED;
553 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
555 OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
558 if (CA_STATUS_OK != CADtlsEnableAnonECDHCipherSuite(enable))
560 return CA_STATUS_FAILED;
564 // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 0xFF00 replaces 0xC018
565 // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037
566 if (CA_STATUS_OK != CAsetTlsCipherSuite(enable ? 0xFF00 : 0xC037))
568 return CA_STATUS_FAILED;
574 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
575 const uint8_t* label, const size_t labelLen,
576 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
577 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
578 uint8_t* ownerPSK, const size_t ownerPSKSize)
580 OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
582 CAResult_t res = CA_STATUS_OK;
584 //newOwnerLabel and prevOwnerLabe can be NULL
585 if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
587 return CA_STATUS_INVALID_PARAM;
590 if(CA_ADAPTER_IP == endpoint->adapter)
592 res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
593 rsrcServerDeviceID, rsrcServerDeviceIDLen,
594 provServerDeviceID, provServerDeviceIDLen,
595 ownerPSK, ownerPSKSize);
600 res = CAtlsGenerateOwnerPSK(endpoint, ownerPSK, ownerPSKSize,
601 rsrcServerDeviceID, rsrcServerDeviceIDLen);
604 if (CA_STATUS_OK != res)
606 OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
609 OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
614 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
616 OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
617 CAResult_t res = CA_STATUS_OK;
621 return CA_STATUS_INVALID_PARAM;
624 res = CADtlsInitiateHandshake(endpoint);
625 if (CA_STATUS_OK != res)
627 OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
630 OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
635 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
637 OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
638 CAResult_t res = CA_STATUS_OK;
642 return CA_STATUS_INVALID_PARAM;
645 res = CADtlsClose(endpoint);
646 if (CA_STATUS_OK != res)
648 OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
651 OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
656 #endif /* __WITH_DTLS__ */
659 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
661 CATCPSetKeepAliveCallbacks(ConnHandler);