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 ******************************************************************/
28 #include "cainterface.h"
29 #include "caremotehandler.h"
30 #include "camessagehandler.h"
31 #include "caprotocolmessage.h"
32 #include "canetworkconfigurator.h"
33 #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 extern void CAsetSetupPkContextCallback(CAsetupPkContextHandler setupPkCtxCallback);
56 #endif // __WITH_DTLS__ or __WITH_TLS__
59 CAResult_t CAInitialize(CATransportAdapter_t transportType)
61 OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
62 OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
66 if (0 != OCSeedRandom())
68 OIC_LOG(ERROR, TAG, "Seed Random Failed");
71 CAResult_t res = CAInitializeMessageHandler(transportType);
72 if (res != CA_STATUS_OK)
74 OIC_LOG(ERROR, TAG, "CAInitialize has failed");
75 CATerminateMessageHandler();
78 g_isInitialized = true;
86 OIC_LOG(DEBUG, TAG, "CATerminate");
90 CATerminateMessageHandler();
91 CATerminateNetworkType();
93 g_isInitialized = false;
97 CAResult_t CAStartListeningServer()
99 OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
101 if (!g_isInitialized)
103 return CA_STATUS_NOT_INITIALIZED;
106 return CAStartListeningServerAdapters();
109 CAResult_t CAStopListeningServer()
111 OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
113 if (!g_isInitialized)
115 return CA_STATUS_NOT_INITIALIZED;
118 return CAStopListeningServerAdapters();
121 CAResult_t CAStartDiscoveryServer()
123 OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
125 if (!g_isInitialized)
127 return CA_STATUS_NOT_INITIALIZED;
130 return CAStartDiscoveryServerAdapters();
133 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
134 CAErrorCallback ErrorHandler)
136 OIC_LOG(DEBUG, TAG, "CARegisterHandler");
138 if (!g_isInitialized)
140 OIC_LOG(DEBUG, TAG, "CA is not initialized");
144 CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
147 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
148 #ifdef MULTIPLE_OWNER
149 const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
151 OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
153 if (!g_isInitialized)
155 OIC_LOG(DEBUG, TAG, "CA is not initialized");
159 OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
160 return GetCASecureEndpointData(peer);
162 #endif //MULTIPLE_OWNER
164 CAResult_t CASetSecureEndpointUuid(const CAEndpoint_t *peer, const char *uuid)
166 OIC_LOG(DEBUG, TAG, "IN CASetSecureEndpointUuid");
168 if (!g_isInitialized)
170 OIC_LOG(DEBUG, TAG, "CA is not initialized");
171 return CA_STATUS_NOT_INITIALIZED;
174 OIC_LOG(DEBUG, TAG, "OUT CASetSecureEndpointUuid");
175 return SetCASecureEndpointUuid(peer, uuid);
178 CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
180 OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
183 return CA_STATUS_NOT_INITIALIZED;
186 CAsetSslHandshakeCallback(tlsHandshakeCallback);
190 CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
192 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
194 if (!g_isInitialized)
196 return CA_STATUS_NOT_INITIALIZED;
198 CAsetPskCredentialsCallback(getTlsCredentialsHandler);
199 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
203 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
205 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
207 if (!g_isInitialized)
209 return CA_STATUS_NOT_INITIALIZED;
211 CAsetPkixInfoCallback(getPkixInfoHandler);
212 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
216 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
218 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
220 if (!g_isInitialized)
222 return CA_STATUS_NOT_INITIALIZED;
224 CAsetCredentialTypesCallback(getCredTypesHandler);
225 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
229 CAResult_t CAregisterSetupPkContextHandler(CAsetupPkContextHandler setupPkContextCallback)
231 OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
233 if (!g_isInitialized)
235 return CA_STATUS_NOT_INITIALIZED;
237 CAsetSetupPkContextCallback(setupPkContextCallback);
238 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
241 #endif // __WITH_DTLS__ or __WITH_TLS__
243 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
244 CATransportAdapter_t adapter,
247 CAEndpoint_t **object)
251 OIC_LOG(ERROR, TAG, "Invalid Parameter");
252 return CA_STATUS_INVALID_PARAM;
255 CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
258 return CA_STATUS_FAILED;
264 void CADestroyEndpoint(CAEndpoint_t *rep)
266 OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
271 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
273 OIC_LOG(DEBUG, TAG, "CAGenerateToken");
275 return CAGenerateTokenInternal(token, tokenLength);
278 void CADestroyToken(CAToken_t token)
280 OIC_LOG(DEBUG, TAG, "CADestroyToken");
282 CADestroyTokenInternal(token);
284 OIC_LOG(DEBUG, TAG, "OUT");
287 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
289 OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
291 if (!g_isInitialized)
293 return CA_STATUS_NOT_INITIALIZED;
296 return CAGetNetworkInformationInternal(info, size);
299 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
300 CADataType_t dataType)
302 OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
304 CATransportAdapter_t connTypes[] = {
307 ,CA_ADAPTER_GATT_BTLE
310 ,CA_ADAPTER_RFCOMM_BTEDR
316 ,CA_ADAPTER_REMOTE_ACCESS
323 CAEndpoint_t *cloneEp = CACloneEndpoint(object);
326 OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
327 return CA_MEMORY_ALLOC_FAILED;
330 CAResult_t ret = CA_STATUS_OK;
331 size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
333 for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
335 cloneEp->adapter = connTypes[i];
336 ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
338 CAFreeEndpoint(cloneEp);
342 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
344 OIC_LOG(DEBUG, TAG, "CASendRequest");
346 if (!g_isInitialized)
348 return CA_STATUS_NOT_INITIALIZED;
351 if (requestInfo && requestInfo->isMulticast &&
352 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
354 return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
356 else if (requestInfo && requestInfo->info.event == CA_REQ_DISCONNECT &&
357 (object->adapter == CA_ADAPTER_TCP || object->adapter == CA_ALL_ADAPTERS))
359 return CADetachSendNetworkReqMessage(object, requestInfo->info.event, CA_NETWORK_COMMAND);
363 return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
367 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
369 OIC_LOG(DEBUG, TAG, "CASendResponse");
371 if (!g_isInitialized)
373 return CA_STATUS_NOT_INITIALIZED;
376 if (!responseInfo || !object)
378 return CA_STATUS_INVALID_PARAM;
381 if (responseInfo->isMulticast &&
382 (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
384 return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
388 return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
392 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
394 if (!g_isInitialized)
396 return CA_STATUS_NOT_INITIALIZED;
399 CAResult_t res = CA_STATUS_OK;
401 if (interestedNetwork & CA_ADAPTER_IP)
403 res = CAAddNetworkType(CA_ADAPTER_IP);
404 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
406 else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
408 res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
409 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
411 else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
413 res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
414 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
418 else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
420 res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
421 OIC_LOG_V(DEBUG, TAG,
422 "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
427 else if (interestedNetwork & CA_ADAPTER_TCP)
429 res = CAAddNetworkType(CA_ADAPTER_TCP);
430 OIC_LOG_V(DEBUG, TAG,
431 "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
434 else if (interestedNetwork & CA_ADAPTER_NFC)
436 res = CAAddNetworkType(CA_ADAPTER_NFC);
437 OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
441 res = CA_NOT_SUPPORTED;
446 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
448 OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
450 if (!g_isInitialized)
452 return CA_STATUS_NOT_INITIALIZED;
455 CAResult_t res = CA_STATUS_OK;
457 if (nonInterestedNetwork & CA_ADAPTER_IP)
459 res = CARemoveNetworkType(CA_ADAPTER_IP);
460 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
462 else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
464 res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
465 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
467 else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
469 res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
470 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
473 else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
475 res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
476 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
483 else if (nonInterestedNetwork & CA_ADAPTER_TCP)
485 res = CARemoveNetworkType(CA_ADAPTER_TCP);
486 OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
493 res = CA_STATUS_FAILED;
498 CAResult_t CAHandleRequestResponse()
500 if (!g_isInitialized)
502 OIC_LOG(ERROR, TAG, "not initialized");
503 return CA_STATUS_NOT_INITIALIZED;
506 CAHandleRequestResponseCallbacks();
511 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
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 OIC_LOG(ERROR, TAG, "Method not supported");
525 OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
529 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
531 OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
532 CAResult_t res = CA_STATUS_FAILED;
533 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
534 // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 0xFF00 replaces 0xC018
535 res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
536 if (CA_STATUS_OK != res)
538 OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
541 OIC_LOG(ERROR, TAG, "Method not supported");
543 OIC_LOG_V(ERROR, TAG, "Out %s", __func__);
547 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
548 const uint8_t* label, const size_t labelLen,
549 const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
550 const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
551 uint8_t* ownerPSK, const size_t ownerPskSize)
553 OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
554 CAResult_t res = CA_STATUS_FAILED;
555 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
556 //newOwnerLabel and prevOwnerLabe can be NULL
557 if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
559 return CA_STATUS_INVALID_PARAM;
562 res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
563 rsrcServerDeviceID, rsrcServerDeviceIDLen,
564 provServerDeviceID, provServerDeviceIDLen,
565 ownerPSK, ownerPskSize);
566 if (CA_STATUS_OK != res)
568 OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
571 OIC_LOG(ERROR, TAG, "Method not supported");
573 OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
577 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
579 OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
580 CAResult_t res = CA_STATUS_FAILED;
581 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
584 return CA_STATUS_INVALID_PARAM;
587 res = CAinitiateSslHandshake(endpoint);
588 if (CA_STATUS_OK != res)
590 OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
593 OIC_LOG(ERROR, TAG, "Method not supported");
595 OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
599 CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
601 OIC_LOG_V(DEBUG, TAG, "IN : CAcloseSslSession");
602 CAResult_t res = CA_STATUS_FAILED;
603 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
606 return CA_STATUS_INVALID_PARAM;
609 res = CAcloseSslConnection(endpoint);
610 if (CA_STATUS_OK != res)
612 OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
615 OIC_LOG(ERROR, TAG, "Method not supported");
617 OIC_LOG_V(DEBUG, TAG, "OUT : CAcloseSslSession");
622 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
624 CATCPSetKeepAliveCallbacks(ConnHandler);
628 #ifdef WITH_PROCESS_EVENT
629 void CARegisterProcessEvent(oc_event event)
631 CARegisterMessageProcessEvent(event);
633 #endif // WITH_PROCESS_EVENT