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);
68 extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
72 CAResult_t CAInitialize()
74 OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
75 OIC_LOG(DEBUG, TAG, "CAInitialize");
79 if (0 != OCSeedRandom())
81 OIC_LOG(ERROR, TAG, "Seed Random Failed");
84 CAResult_t res = CAInitializeMessageHandler();
85 if (res != CA_STATUS_OK)
87 OIC_LOG(ERROR, TAG, "CAInitialize has failed");
90 g_isInitialized = true;
98 OIC_LOG(DEBUG, TAG, "CATerminate");
102 CATerminateMessageHandler();
103 CATerminateNetworkType();
105 g_isInitialized = false;
109 CAResult_t CAStartListeningServer()
111 OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
113 if (!g_isInitialized)
115 return CA_STATUS_NOT_INITIALIZED;
118 return CAStartListeningServerAdapters();
121 CAResult_t CAStopListeningServer()
123 OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
125 if (!g_isInitialized)
127 return CA_STATUS_NOT_INITIALIZED;
130 return CAStopListeningServerAdapters();
133 CAResult_t CAStartDiscoveryServer()
135 OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
137 if (!g_isInitialized)
139 return CA_STATUS_NOT_INITIALIZED;
142 return CAStartDiscoveryServerAdapters();
145 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
146 CAErrorCallback ErrorHandler)
148 OIC_LOG(DEBUG, TAG, "CARegisterHandler");
150 if (!g_isInitialized)
152 OIC_LOG(DEBUG, TAG, "CA is not initialized");
156 CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
160 CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
162 OIC_LOG(DEBUG, TAG, "CARegisterDTLSHandshakeCallback");
164 if (!g_isInitialized)
166 return CA_STATUS_NOT_INITIALIZED;
169 CADTLSSetHandshakeCallback(dtlsHandshakeCallback);
174 CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
176 OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
178 if (!g_isInitialized)
180 return CA_STATUS_NOT_INITIALIZED;
183 CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
186 #endif //__WITH_DTLS__
188 CAResult_t CAregisterTlsHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
190 OIC_LOG(DEBUG, TAG, "CARegisterTlsHandshakeCallback");
194 return CA_STATUS_NOT_INITIALIZED;
197 CAsetTlsHandshakeCallback(tlsHandshakeCallback);
201 CAResult_t CAregisterTlsCredentialsHandler(CAGetDTLSPskCredentialsHandler getTlsCredentialsHandler)
203 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
205 if (!g_isInitialized)
207 return CA_STATUS_NOT_INITIALIZED;
209 CAsetTlsCredentialsCallback(getTlsCredentialsHandler);
210 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
214 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
216 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
218 if (!g_isInitialized)
220 return CA_STATUS_NOT_INITIALIZED;
222 CAsetPkixInfoCallback(getPkixInfoHandler);
223 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
227 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
229 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
231 if (!g_isInitialized)
233 return CA_STATUS_NOT_INITIALIZED;
235 CAsetCredentialTypesCallback(getCredTypesHandler);
236 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
242 CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
244 OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
246 if (!g_isInitialized)
248 return CA_STATUS_NOT_INITIALIZED;
251 CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
255 CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
257 OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
259 if (!g_isInitialized)
261 return CA_STATUS_NOT_INITIALIZED;
264 CADTLSSetCrlCallback(GetDTLSCrlHandler);
267 #endif //__WITH_X509__
269 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
270 CATransportAdapter_t adapter,
273 CAEndpoint_t **object)
277 OIC_LOG(ERROR, TAG, "Invalid Parameter");
278 return CA_STATUS_INVALID_PARAM;
281 CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
284 return CA_STATUS_FAILED;
290 void CADestroyEndpoint(CAEndpoint_t *rep)
292 OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
297 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
299 OIC_LOG(DEBUG, TAG, "CAGenerateToken");
301 return CAGenerateTokenInternal(token, tokenLength);
304 void CADestroyToken(CAToken_t token)
306 OIC_LOG(DEBUG, TAG, "CADestroyToken");
308 CADestroyTokenInternal(token);
310 OIC_LOG(DEBUG, TAG, "OUT");
313 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
315 OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
317 if (!g_isInitialized)
319 return CA_STATUS_NOT_INITIALIZED;
322 return CAGetNetworkInformationInternal(info, size);
325 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
326 CADataType_t dataType)
328 OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
330 CATransportAdapter_t connTypes[] = {
333 ,CA_ADAPTER_GATT_BTLE
336 ,CA_ADAPTER_RFCOMM_BTEDR
342 ,CA_ADAPTER_REMOTE_ACCESS
349 CAEndpoint_t *cloneEp = CACloneEndpoint(object);
352 OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
353 return CA_MEMORY_ALLOC_FAILED;
356 CAResult_t ret = CA_STATUS_OK;
357 size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
359 for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
361 cloneEp->adapter = connTypes[i];
362 ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
364 CAFreeEndpoint(cloneEp);
368 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
370 OIC_LOG(DEBUG, TAG, "CASendRequest");
372 if (!g_isInitialized)
374 return CA_STATUS_NOT_INITIALIZED;
377 if (requestInfo && requestInfo->isMulticast &&
378 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
380 return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
384 return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
388 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
390 OIC_LOG(DEBUG, TAG, "CASendResponse");
392 if (!g_isInitialized)
394 return CA_STATUS_NOT_INITIALIZED;
397 if (!responseInfo || !object)
399 return CA_STATUS_INVALID_PARAM;
402 if (responseInfo->isMulticast &&
403 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
405 return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
409 return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
413 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
415 OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
417 if (!g_isInitialized)
419 return CA_STATUS_NOT_INITIALIZED;
422 CAResult_t res = CA_STATUS_OK;
424 if (interestedNetwork & CA_ADAPTER_IP)
426 res = CAAddNetworkType(CA_ADAPTER_IP);
427 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
429 else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
431 res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
432 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
434 else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
436 res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
437 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
441 else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
443 res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
444 OIC_LOG_V(DEBUG, TAG,
445 "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
450 else if (interestedNetwork & CA_ADAPTER_TCP)
452 res = CAAddNetworkType(CA_ADAPTER_TCP);
453 OIC_LOG_V(DEBUG, TAG,
454 "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
457 else if (interestedNetwork & CA_ADAPTER_NFC)
459 res = CAAddNetworkType(CA_ADAPTER_NFC);
460 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
464 res = CA_NOT_SUPPORTED;
469 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
471 OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
473 if (!g_isInitialized)
475 return CA_STATUS_NOT_INITIALIZED;
478 CAResult_t res = CA_STATUS_OK;
480 if (nonInterestedNetwork & CA_ADAPTER_IP)
482 res = CARemoveNetworkType(CA_ADAPTER_IP);
483 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
485 else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
487 res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
488 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
490 else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
492 res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
493 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
496 else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
498 res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
499 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
506 else if (nonInterestedNetwork & CA_ADAPTER_TCP)
508 res = CARemoveNetworkType(CA_ADAPTER_TCP);
509 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
516 res = CA_STATUS_FAILED;
521 CAResult_t CAHandleRequestResponse()
523 if (!g_isInitialized)
525 OIC_LOG(ERROR, TAG, "not initialized");
526 return CA_STATUS_NOT_INITIALIZED;
529 CAHandleRequestResponseCallbacks();
534 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
535 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
537 OIC_LOG_V(DEBUG, TAG, "IN CASelectCipherSuite");
538 OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d",cipher, adapter);
539 if(CA_ADAPTER_IP == adapter)
541 if (CA_STATUS_OK != CADtlsSelectCipherSuite(cipher))
543 OIC_LOG_V(DEBUG, TAG, "CADtlsSelectCipherSuite failed");
544 return CA_STATUS_FAILED;
548 else if(CA_ADAPTER_TCP == adapter)
550 if (CA_STATUS_OK != CAsetTlsCipherSuite(cipher))
552 OIC_LOG_V(DEBUG, TAG, "CAsetTlsCipherSuite failed");
553 return CA_STATUS_FAILED;
557 OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite OK");
561 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
563 OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
566 if (CA_STATUS_OK != CADtlsEnableAnonECDHCipherSuite(enable))
568 return CA_STATUS_FAILED;
572 // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 0xFF00 replaces 0xC018
573 // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037
574 if (CA_STATUS_OK != CAsetTlsCipherSuite(enable ? 0xFF00 : 0xC037))
576 return CA_STATUS_FAILED;
582 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
583 const uint8_t* label, const size_t labelLen,
584 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
585 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
586 uint8_t* ownerPSK, const size_t ownerPSKSize)
588 OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
590 CAResult_t res = CA_STATUS_OK;
592 //newOwnerLabel and prevOwnerLabe can be NULL
593 if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
595 return CA_STATUS_INVALID_PARAM;
598 if(CA_ADAPTER_IP == endpoint->adapter)
600 res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
601 rsrcServerDeviceID, rsrcServerDeviceIDLen,
602 provServerDeviceID, provServerDeviceIDLen,
603 ownerPSK, ownerPSKSize);
608 res = CAtlsGenerateOwnerPSK(endpoint, ownerPSK, ownerPSKSize,
609 rsrcServerDeviceID, rsrcServerDeviceIDLen);
612 if (CA_STATUS_OK != res)
614 OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
617 OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
622 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
624 OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
625 CAResult_t res = CA_STATUS_OK;
629 return CA_STATUS_INVALID_PARAM;
632 res = CADtlsInitiateHandshake(endpoint);
633 if (CA_STATUS_OK != res)
635 OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
638 OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
643 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
645 OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
646 CAResult_t res = CA_STATUS_OK;
650 return CA_STATUS_INVALID_PARAM;
653 res = CADtlsClose(endpoint);
654 if (CA_STATUS_OK != res)
656 OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
659 OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
664 #endif /* __WITH_DTLS__ */
667 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
669 CATCPSetKeepAliveCallbacks(ConnHandler);