3f49c301acc12a92f43d283a53a12c54c25071a0
[iotivity.git] / resource / csdk / connectivity / src / caconnectivitymanager.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25
26 #include "experimental/ocrandom.h"
27 #include "cainterface.h"
28 #include "caremotehandler.h"
29 #include "camessagehandler.h"
30 #include "caprotocolmessage.h"
31 #include "canetworkconfigurator.h"
32 #include "cainterfacecontroller.h"
33 #include "experimental/logger.h"
34
35 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
36 #include "ca_adapter_net_ssl.h"
37 #endif // __WITH_DTLS__ or __WITH_TLS__
38
39 #ifdef TCP_ADAPTER
40 #include "catcpadapter.h"
41 #endif
42
43 CAGlobals_t caglobals = { .clientFlags = 0,
44                           .serverFlags = 0, };
45
46 #define TAG "OIC_CA_CONN_MGR"
47
48 static bool g_isInitialized = false;
49
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__
56
57
58 CAResult_t CAInitialize(CATransportAdapter_t transportType)
59 {
60     OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
61
62     if (!g_isInitialized)
63     {
64         CAResult_t res = CAInitializeMessageHandler(transportType);
65         if (res != CA_STATUS_OK)
66         {
67             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
68             CATerminateMessageHandler();
69             return res;
70         }
71         g_isInitialized = true;
72     }
73
74     return CA_STATUS_OK;
75 }
76
77 void CATerminate()
78 {
79     OIC_LOG(DEBUG, TAG, "CATerminate");
80
81     if (g_isInitialized)
82     {
83         CATerminateMessageHandler();
84         CATerminateNetworkType();
85
86         g_isInitialized = false;
87     }
88 }
89
90 CAResult_t CAStartListeningServer()
91 {
92     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
93
94     if (!g_isInitialized)
95     {
96         return CA_STATUS_NOT_INITIALIZED;
97     }
98
99     return CAStartListeningServerAdapters();
100 }
101
102 CAResult_t CAStopListeningServer()
103 {
104     OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
105
106     if (!g_isInitialized)
107     {
108         return CA_STATUS_NOT_INITIALIZED;
109     }
110
111     return CAStopListeningServerAdapters();
112 }
113
114 CAResult_t CAStartDiscoveryServer()
115 {
116     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
117
118     if (!g_isInitialized)
119     {
120         return CA_STATUS_NOT_INITIALIZED;
121     }
122
123     return CAStartDiscoveryServerAdapters();
124 }
125
126 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
127                        CAErrorCallback ErrorHandler)
128 {
129     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
130
131     if (!g_isInitialized)
132     {
133         OIC_LOG(DEBUG, TAG, "CA is not initialized");
134         return;
135     }
136
137     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
138 }
139
140 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
141
142 CAResult_t CAGetSecureEndpointData(const CAEndpoint_t *peer, CASecureEndpoint_t *sep)
143 {
144     OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
145
146     if (!g_isInitialized)
147     {
148         OIC_LOG(DEBUG, TAG, "CA is not initialized");
149         return CA_STATUS_NOT_INITIALIZED;
150     }
151
152     OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
153     return GetCASecureEndpointData(peer, sep);
154 }
155
156 bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t attribute)
157 {
158     bool success = false;
159     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
160
161     if (!g_isInitialized)
162     {
163         OIC_LOG(DEBUG, TAG, "CA is not initialized");
164     }
165     else
166     {
167         success = SetCASecureEndpointAttribute(peer, attribute);
168     }
169
170     OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
171     return success;
172 }
173
174 bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* attributes)
175 {
176     bool success = false;
177     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
178
179     if (!g_isInitialized)
180     {
181         OIC_LOG(DEBUG, TAG, "CA is not initialized");
182     }
183     else
184     {
185         success = GetCASecureEndpointAttributes(peer, attributes);
186     }
187
188     OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
189     return success;
190 }
191
192 CAResult_t CAregisterSslHandshakeCallback(CAHandshakeErrorCallback tlsHandshakeCallback)
193 {
194     OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
195
196     if(!g_isInitialized)
197     {
198         return CA_STATUS_NOT_INITIALIZED;
199     }
200
201     CAsetSslHandshakeCallback(tlsHandshakeCallback);
202     return CA_STATUS_OK;
203 }
204
205 CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
206 {
207     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
208
209     if (!g_isInitialized)
210     {
211         return CA_STATUS_NOT_INITIALIZED;
212     }
213     CAsetPskCredentialsCallback(getTlsCredentialsHandler);
214     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
215     return CA_STATUS_OK;
216 }
217
218 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
219 {
220     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
221
222     if (!g_isInitialized)
223     {
224         return CA_STATUS_NOT_INITIALIZED;
225     }
226     CAsetPkixInfoCallback(getPkixInfoHandler);
227     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
228     return CA_STATUS_OK;
229 }
230
231 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
232 {
233     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
234
235     if (!g_isInitialized)
236     {
237         return CA_STATUS_NOT_INITIALIZED;
238     }
239     CAsetCredentialTypesCallback(getCredTypesHandler);
240     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
241     return CA_STATUS_OK;
242 }
243 #endif // __WITH_DTLS__ or __WITH_TLS__
244
245 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
246                             CATransportAdapter_t adapter,
247                             const char *addr,
248                             uint16_t port,
249                             CAEndpoint_t **object)
250 {
251     if (!object)
252     {
253         OIC_LOG(ERROR, TAG, "Invalid Parameter");
254         return CA_STATUS_INVALID_PARAM;
255     }
256
257     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
258     if (!endpoint)
259     {
260         return CA_STATUS_FAILED;
261     }
262     *object = endpoint;
263     return CA_STATUS_OK;
264 }
265
266 void CADestroyEndpoint(CAEndpoint_t *rep)
267 {
268     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
269
270     CAFreeEndpoint(rep);
271 }
272
273 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
274 {
275     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
276
277     return CAGenerateTokenInternal(token, tokenLength);
278 }
279
280 void CADestroyToken(CAToken_t token)
281 {
282     OIC_LOG(DEBUG, TAG, "CADestroyToken");
283
284     CADestroyTokenInternal(token);
285
286     OIC_LOG(DEBUG, TAG, "OUT");
287 }
288
289 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, size_t *size)
290 {
291     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
292
293     if (!g_isInitialized)
294     {
295         return CA_STATUS_NOT_INITIALIZED;
296     }
297
298     return CAGetNetworkInformationInternal(info, size);
299 }
300
301 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
302                                             CADataType_t dataType)
303 {
304     OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
305
306     CATransportAdapter_t connTypes[] = {
307             CA_ADAPTER_IP
308 #ifdef LE_ADAPTER
309             ,CA_ADAPTER_GATT_BTLE
310 #endif
311 #ifdef EDR_ADAPTER
312             ,CA_ADAPTER_RFCOMM_BTEDR
313 #endif
314 #ifdef NFC_ADAPTER
315             ,CA_ADAPTER_NFC
316 #endif
317 #ifdef RA_ADAPTER
318             ,CA_ADAPTER_REMOTE_ACCESS
319 #endif
320 #ifdef TCP_ADAPTER
321             ,CA_ADAPTER_TCP
322 #endif
323         };
324
325     CAEndpoint_t *cloneEp = CACloneEndpoint(object);
326     if (!cloneEp)
327     {
328         OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
329         return CA_MEMORY_ALLOC_FAILED;
330     }
331
332     CAResult_t ret = CA_STATUS_OK;
333     size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
334
335     for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
336     {
337         cloneEp->adapter = connTypes[i];
338         ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
339     }
340     CAFreeEndpoint(cloneEp);
341     return ret;
342 }
343
344 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
345 {
346     OIC_LOG(DEBUG, TAG, "CASendRequest");
347
348     if (!g_isInitialized)
349     {
350         return CA_STATUS_NOT_INITIALIZED;
351     }
352
353     if (requestInfo && requestInfo->isMulticast &&
354             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
355     {
356         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
357     }
358     else
359     {
360         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
361     }
362 }
363
364 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
365 {
366     OIC_LOG(DEBUG, TAG, "CASendResponse");
367
368     if (!g_isInitialized)
369     {
370         return CA_STATUS_NOT_INITIALIZED;
371     }
372
373     if (!responseInfo || !object)
374     {
375         return CA_STATUS_INVALID_PARAM;
376     }
377
378     if (responseInfo->isMulticast &&
379             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
380     {
381         return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
382     }
383     else
384     {
385         return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
386     }
387 }
388
389 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
390 {
391     if (!g_isInitialized)
392     {
393         return CA_STATUS_NOT_INITIALIZED;
394     }
395
396     CAResult_t res = CA_STATUS_OK;
397
398     if (interestedNetwork & CA_ADAPTER_IP)
399     {
400         res = CAAddNetworkType(CA_ADAPTER_IP);
401         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
402     }
403     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
404     {
405         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
406         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
407     }
408     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
409     {
410         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
411         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
412     }
413
414 #ifdef RA_ADAPTER
415     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
416     {
417         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
418         OIC_LOG_V(DEBUG, TAG,
419                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
420     }
421 #endif
422
423 #ifdef TCP_ADAPTER
424     else if (interestedNetwork & CA_ADAPTER_TCP)
425     {
426         res = CAAddNetworkType(CA_ADAPTER_TCP);
427         OIC_LOG_V(DEBUG, TAG,
428                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
429     }
430 #endif
431     else if (interestedNetwork & CA_ADAPTER_NFC)
432     {
433         res = CAAddNetworkType(CA_ADAPTER_NFC);
434         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
435     }
436     else
437     {
438         res = CA_NOT_SUPPORTED;
439     }
440     return res;
441 }
442
443 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
444 {
445     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
446
447     if (!g_isInitialized)
448     {
449         return CA_STATUS_NOT_INITIALIZED;
450     }
451
452     CAResult_t res = CA_STATUS_OK;
453
454     if (nonInterestedNetwork & CA_ADAPTER_IP)
455     {
456         res = CARemoveNetworkType(CA_ADAPTER_IP);
457         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
458     }
459     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
460     {
461         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
462         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
463     }
464     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
465     {
466         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
467         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
468     }
469 #ifdef RA_ADAPTER
470     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
471     {
472         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
473         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
474                   res);
475     }
476 #endif
477
478
479 #ifdef TCP_ADAPTER
480     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
481     {
482         res = CARemoveNetworkType(CA_ADAPTER_TCP);
483         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
484                   res);
485     }
486 #endif
487
488     else
489     {
490         res = CA_STATUS_FAILED;
491     }
492     return res;
493 }
494
495 CAResult_t CAHandleRequestResponse()
496 {
497     if (!g_isInitialized)
498     {
499         OIC_LOG(ERROR, TAG, "not initialized");
500         return CA_STATUS_NOT_INITIALIZED;
501     }
502
503     CAHandleRequestResponseCallbacks();
504
505     return CA_STATUS_OK;
506 }
507
508 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
509 {
510     (void)(adapter); // prevent unused-parameter warning when building release variant
511     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
512     OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
513     CAResult_t res = CA_STATUS_FAILED;
514 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
515     res = CAsetTlsCipherSuite(cipher);
516     if (CA_STATUS_OK != res)
517     {
518         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
519     }
520 #else
521     (void)(cipher); // prevent unused-parameter warning
522     OIC_LOG(ERROR, TAG, "Method not supported");
523 #endif
524     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
525     return res;
526 }
527
528 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
529 {
530     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
531     CAResult_t res = CA_STATUS_FAILED;
532 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
533     // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
534     res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
535     if (CA_STATUS_OK != res)
536     {
537         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
538     }
539 #else
540     (void)(enable); // prevent unused-parameter compiler warning
541     OIC_LOG(ERROR, TAG, "Method not supported");
542 #endif
543     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
544     return res;
545 }
546
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)
552 {
553     OIC_LOG(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)
558     {
559         return CA_STATUS_INVALID_PARAM;
560     }
561
562     res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
563                                       rsrcServerDeviceID, rsrcServerDeviceIDLen,
564                                       provServerDeviceID, provServerDeviceIDLen,
565                                       ownerPSK, ownerPskSize);
566     if (CA_STATUS_OK != res)
567     {
568         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
569     }
570 #else
571     (void)(endpoint); // prevent unused-parameter compiler warnings
572     (void)(label);
573     (void)(labelLen);
574     (void)(rsrcServerDeviceID);
575     (void)(rsrcServerDeviceIDLen);
576     (void)(provServerDeviceID);
577     (void)(provServerDeviceIDLen);
578     (void)(ownerPSK);
579     (void)(ownerPskSize);
580     OIC_LOG(ERROR, TAG, "Method not supported");
581 #endif
582     OIC_LOG(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
583     return res;
584 }
585
586 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
587 {
588     OIC_LOG(DEBUG, TAG, "IN : CAInitiateHandshake");
589     CAResult_t res = CA_STATUS_FAILED;
590 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
591     if (!endpoint)
592     {
593         return CA_STATUS_INVALID_PARAM;
594     }
595
596     res = CAinitiateSslHandshake(endpoint);
597     if (CA_STATUS_OK != res)
598     {
599         OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
600     }
601 #else
602     (void)(endpoint); // prevent unused-parameter compiler warning
603     OIC_LOG(ERROR, TAG, "Method not supported");
604 #endif
605     OIC_LOG(DEBUG, TAG, "OUT : CAInitiateHandshake");
606     return res;
607 }
608
609 CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
610 {
611     OIC_LOG(DEBUG, TAG, "IN : CAcloseSslSession");
612     CAResult_t res = CA_STATUS_FAILED;
613 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
614     if (!endpoint)
615     {
616         return CA_STATUS_INVALID_PARAM;
617     }
618
619     res = CAcloseSslConnection(endpoint);
620     if (CA_STATUS_OK != res)
621     {
622         OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
623     }
624 #else
625     (void)(endpoint); // prevent unused-parameter compiler warning
626     OIC_LOG(ERROR, TAG, "Method not supported");
627 #endif
628     OIC_LOG(DEBUG, TAG, "OUT : CAcloseSslSession");
629     return res;
630 }
631
632 #ifdef TCP_ADAPTER
633 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
634 {
635     CATCPSetKeepAliveCallbacks(ConnHandler);
636 }
637 #endif