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 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
36 #include "ca_adapter_net_ssl.h"
37 #endif // __WITH_DTLS__ or __WITH_TLS__
40 #include "catcpadapter.h"
43 CAGlobals_t caglobals = { .clientFlags = 0,
46 #define TAG "OIC_CA_CONN_MGR"
48 static bool g_isInitialized = false;
50 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
51 // Taking callback all the way through adapters not the right approach, hence calling here.
52 extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
53 extern void CAsetPskCredentialsCallback(CAgetPskCredentialsHandler credCallback);
54 extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
55 #endif // __WITH_DTLS__ or __WITH_TLS__
58 CAResult_t CAInitialize(CATransportAdapter_t transportType)
60 OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
61 OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
65 CAResult_t res = CAInitializeMessageHandler(transportType);
66 if (res != CA_STATUS_OK)
68 OIC_LOG(ERROR, TAG, "CAInitialize has failed");
69 CATerminateMessageHandler();
72 g_isInitialized = true;
80 OIC_LOG(DEBUG, TAG, "CATerminate");
84 CATerminateMessageHandler();
85 CATerminateNetworkType();
87 g_isInitialized = false;
91 CAResult_t CAStartListeningServer()
93 OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
97 return CA_STATUS_NOT_INITIALIZED;
100 return CAStartListeningServerAdapters();
103 CAResult_t CAStopListeningServer()
105 OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
107 if (!g_isInitialized)
109 return CA_STATUS_NOT_INITIALIZED;
112 return CAStopListeningServerAdapters();
115 CAResult_t CAStartDiscoveryServer()
117 OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
119 if (!g_isInitialized)
121 return CA_STATUS_NOT_INITIALIZED;
124 return CAStartDiscoveryServerAdapters();
127 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
128 CAErrorCallback ErrorHandler)
130 OIC_LOG(DEBUG, TAG, "CARegisterHandler");
132 if (!g_isInitialized)
134 OIC_LOG(DEBUG, TAG, "CA is not initialized");
138 CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
141 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
142 #ifdef MULTIPLE_OWNER
143 const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
145 OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
147 if (!g_isInitialized)
149 OIC_LOG(DEBUG, TAG, "CA is not initialized");
153 OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
154 return GetCASecureEndpointData(peer);
156 #endif //MULTIPLE_OWNER
158 bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t attribute)
160 bool success = false;
161 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
163 if (!g_isInitialized)
165 OIC_LOG(DEBUG, TAG, "CA is not initialized");
169 success = SetCASecureEndpointAttribute(peer, attribute);
172 OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
176 bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* attributes)
178 bool success = false;
179 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
181 if (!g_isInitialized)
183 OIC_LOG(DEBUG, TAG, "CA is not initialized");
187 success = GetCASecureEndpointAttributes(peer, attributes);
190 OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
194 CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
196 OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
200 return CA_STATUS_NOT_INITIALIZED;
203 CAsetSslHandshakeCallback(tlsHandshakeCallback);
207 CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
209 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
211 if (!g_isInitialized)
213 return CA_STATUS_NOT_INITIALIZED;
215 CAsetPskCredentialsCallback(getTlsCredentialsHandler);
216 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
220 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
222 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
224 if (!g_isInitialized)
226 return CA_STATUS_NOT_INITIALIZED;
228 CAsetPkixInfoCallback(getPkixInfoHandler);
229 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
233 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
235 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
237 if (!g_isInitialized)
239 return CA_STATUS_NOT_INITIALIZED;
241 CAsetCredentialTypesCallback(getCredTypesHandler);
242 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
245 #endif // __WITH_DTLS__ or __WITH_TLS__
247 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
248 CATransportAdapter_t adapter,
251 CAEndpoint_t **object)
255 OIC_LOG(ERROR, TAG, "Invalid Parameter");
256 return CA_STATUS_INVALID_PARAM;
259 CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
262 return CA_STATUS_FAILED;
268 void CADestroyEndpoint(CAEndpoint_t *rep)
270 OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
275 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
277 OIC_LOG(DEBUG, TAG, "CAGenerateToken");
279 return CAGenerateTokenInternal(token, tokenLength);
282 void CADestroyToken(CAToken_t token)
284 OIC_LOG(DEBUG, TAG, "CADestroyToken");
286 CADestroyTokenInternal(token);
288 OIC_LOG(DEBUG, TAG, "OUT");
291 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
293 OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
295 if (!g_isInitialized)
297 return CA_STATUS_NOT_INITIALIZED;
300 return CAGetNetworkInformationInternal(info, size);
303 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
304 CADataType_t dataType)
306 OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
308 CATransportAdapter_t connTypes[] = {
311 ,CA_ADAPTER_GATT_BTLE
314 ,CA_ADAPTER_RFCOMM_BTEDR
320 ,CA_ADAPTER_REMOTE_ACCESS
327 CAEndpoint_t *cloneEp = CACloneEndpoint(object);
330 OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
331 return CA_MEMORY_ALLOC_FAILED;
334 CAResult_t ret = CA_STATUS_OK;
335 size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
337 for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
339 cloneEp->adapter = connTypes[i];
340 ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
342 CAFreeEndpoint(cloneEp);
346 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
348 OIC_LOG(DEBUG, TAG, "CASendRequest");
350 if (!g_isInitialized)
352 return CA_STATUS_NOT_INITIALIZED;
355 if (requestInfo && requestInfo->isMulticast &&
356 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
358 return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
362 return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
366 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
368 OIC_LOG(DEBUG, TAG, "CASendResponse");
370 if (!g_isInitialized)
372 return CA_STATUS_NOT_INITIALIZED;
375 if (!responseInfo || !object)
377 return CA_STATUS_INVALID_PARAM;
380 if (responseInfo->isMulticast &&
381 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
383 return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
387 return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
391 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
393 if (!g_isInitialized)
395 return CA_STATUS_NOT_INITIALIZED;
398 CAResult_t res = CA_STATUS_OK;
400 if (interestedNetwork & CA_ADAPTER_IP)
402 res = CAAddNetworkType(CA_ADAPTER_IP);
403 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
405 else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
407 res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
408 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
410 else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
412 res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
413 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
417 else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
419 res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
420 OIC_LOG_V(DEBUG, TAG,
421 "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
426 else if (interestedNetwork & CA_ADAPTER_TCP)
428 res = CAAddNetworkType(CA_ADAPTER_TCP);
429 OIC_LOG_V(DEBUG, TAG,
430 "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
433 else if (interestedNetwork & CA_ADAPTER_NFC)
435 res = CAAddNetworkType(CA_ADAPTER_NFC);
436 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
440 res = CA_NOT_SUPPORTED;
445 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
447 OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
449 if (!g_isInitialized)
451 return CA_STATUS_NOT_INITIALIZED;
454 CAResult_t res = CA_STATUS_OK;
456 if (nonInterestedNetwork & CA_ADAPTER_IP)
458 res = CARemoveNetworkType(CA_ADAPTER_IP);
459 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
461 else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
463 res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
464 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
466 else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
468 res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
469 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
472 else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
474 res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
475 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
482 else if (nonInterestedNetwork & CA_ADAPTER_TCP)
484 res = CARemoveNetworkType(CA_ADAPTER_TCP);
485 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
492 res = CA_STATUS_FAILED;
497 CAResult_t CAHandleRequestResponse()
499 if (!g_isInitialized)
501 OIC_LOG(ERROR, TAG, "not initialized");
502 return CA_STATUS_NOT_INITIALIZED;
505 CAHandleRequestResponseCallbacks();
510 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
512 (void)(adapter); // prevent unused-parameter warning when building release variant
513 OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
514 OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
515 CAResult_t res = CA_STATUS_FAILED;
516 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
517 res = CAsetTlsCipherSuite(cipher);
518 if (CA_STATUS_OK != res)
520 OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
523 (void)(cipher); // prevent unused-parameter warning
524 OIC_LOG(ERROR, TAG, "Method not supported");
526 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
530 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
532 OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
533 CAResult_t res = CA_STATUS_FAILED;
534 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
535 // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 0xFF00 replaces 0xC018
536 res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
537 if (CA_STATUS_OK != res)
539 OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
542 (void)(enable); // prevent unused-parameter compiler warning
543 OIC_LOG(ERROR, TAG, "Method not supported");
545 OIC_LOG_V(ERROR, TAG, "Out %s", __func__);
549 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
550 const uint8_t* label, const size_t labelLen,
551 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
552 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
553 uint8_t* ownerPSK, const size_t ownerPskSize)
555 OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
556 CAResult_t res = CA_STATUS_FAILED;
557 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
558 //newOwnerLabel and prevOwnerLabe can be NULL
559 if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
561 return CA_STATUS_INVALID_PARAM;
564 res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
565 rsrcServerDeviceID, rsrcServerDeviceIDLen,
566 provServerDeviceID, provServerDeviceIDLen,
567 ownerPSK, ownerPskSize);
568 if (CA_STATUS_OK != res)
570 OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
573 (void)(endpoint); // prevent unused-parameter compiler warnings
576 (void)(rsrcServerDeviceID);
577 (void)(rsrcServerDeviceIDLen);
578 (void)(provServerDeviceID);
579 (void)(provServerDeviceIDLen);
581 (void)(ownerPskSize);
582 OIC_LOG(ERROR, TAG, "Method not supported");
584 OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
588 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
590 OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
591 CAResult_t res = CA_STATUS_FAILED;
592 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
595 return CA_STATUS_INVALID_PARAM;
598 res = CAinitiateSslHandshake(endpoint);
599 if (CA_STATUS_OK != res)
601 OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
604 (void)(endpoint); // prevent unused-parameter compiler warning
605 OIC_LOG(ERROR, TAG, "Method not supported");
607 OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
611 CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
613 OIC_LOG_V(DEBUG, TAG, "IN : CAcloseSslSession");
614 CAResult_t res = CA_STATUS_FAILED;
615 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
618 return CA_STATUS_INVALID_PARAM;
621 res = CAcloseSslConnection(endpoint);
622 if (CA_STATUS_OK != res)
624 OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
627 (void)(endpoint); // prevent unused-parameter compiler warning
628 OIC_LOG(ERROR, TAG, "Method not supported");
630 OIC_LOG_V(DEBUG, TAG, "OUT : CAcloseSslSession");
635 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
637 CATCPSetKeepAliveCallbacks(ConnHandler);