Merge remote-tracking branch 'origin/master' into notification-service
[platform/upstream/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 "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 "logger.h"
34 #ifdef __WITH_DTLS__
35 #include "caadapternetdtls.h"
36 #endif
37
38 #ifdef TCP_ADAPTER
39 #include "catcpadapter.h"
40 #ifdef __WITH_TLS__
41 #include "ca_adapter_net_tls.h"
42 #endif
43 #endif
44
45 CAGlobals_t caglobals = { .clientFlags = 0,
46                           .serverFlags = 0, };
47
48 #define TAG "OIC_CA_CONN_MGR"
49
50 static bool g_isInitialized = false;
51
52 #ifdef __WITH_DTLS__
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);
56 #endif
57
58 #ifdef __WITH_X509__
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);
63 #endif
64
65 #ifdef __WITH_TLS__
66 extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
67 extern void CAsetTlsCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
68 #endif
69
70
71 CAResult_t CAInitialize()
72 {
73     OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
74     OIC_LOG(DEBUG, TAG, "CAInitialize");
75
76     if (!g_isInitialized)
77     {
78         if (0 != OCSeedRandom())
79         {
80             OIC_LOG(ERROR, TAG, "Seed Random Failed");
81         }
82
83         CAResult_t res = CAInitializeMessageHandler();
84         if (res != CA_STATUS_OK)
85         {
86             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
87             return res;
88         }
89         g_isInitialized = true;
90     }
91
92     return CA_STATUS_OK;
93 }
94
95 void CATerminate()
96 {
97     OIC_LOG(DEBUG, TAG, "CATerminate");
98
99     if (g_isInitialized)
100     {
101         CATerminateMessageHandler();
102         CATerminateNetworkType();
103
104         g_isInitialized = false;
105     }
106 }
107
108 CAResult_t CAStartListeningServer()
109 {
110     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
111
112     if (!g_isInitialized)
113     {
114         return CA_STATUS_NOT_INITIALIZED;
115     }
116
117     return CAStartListeningServerAdapters();
118 }
119
120 CAResult_t CAStopListeningServer()
121 {
122     OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
123
124     if (!g_isInitialized)
125     {
126         return CA_STATUS_NOT_INITIALIZED;
127     }
128
129     return CAStopListeningServerAdapters();
130 }
131
132 CAResult_t CAStartDiscoveryServer()
133 {
134     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
135
136     if (!g_isInitialized)
137     {
138         return CA_STATUS_NOT_INITIALIZED;
139     }
140
141     return CAStartDiscoveryServerAdapters();
142 }
143
144 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
145                        CAErrorCallback ErrorHandler)
146 {
147     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
148
149     if (!g_isInitialized)
150     {
151         OIC_LOG(DEBUG, TAG, "CA is not initialized");
152         return;
153     }
154
155     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
156 }
157
158 #ifdef __WITH_DTLS__
159 CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
160 {
161     OIC_LOG(DEBUG, TAG, "CARegisterDTLSHandshakeCallback");
162
163     if (!g_isInitialized)
164     {
165         return CA_STATUS_NOT_INITIALIZED;
166     }
167
168     CADTLSSetHandshakeCallback(dtlsHandshakeCallback);
169
170     return CA_STATUS_OK;
171 }
172
173 CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
174 {
175     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
176
177     if (!g_isInitialized)
178     {
179         return CA_STATUS_NOT_INITIALIZED;
180     }
181
182     CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
183     return CA_STATUS_OK;
184 }
185 #endif //__WITH_DTLS__
186 #ifdef __WITH_TLS__
187 CAResult_t CAregisterTlsHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
188 {
189     OIC_LOG(DEBUG, TAG, "CARegisterTlsHandshakeCallback");
190
191     if(!g_isInitialized)
192     {
193         return CA_STATUS_NOT_INITIALIZED;
194     }
195
196     CAsetTlsHandshakeCallback(tlsHandshakeCallback);
197     return CA_STATUS_OK;
198 }
199
200 CAResult_t CAregisterTlsCredentialsHandler(CAGetDTLSPskCredentialsHandler getTlsCredentialsHandler)
201 {
202     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
203
204     if (!g_isInitialized)
205     {
206         return CA_STATUS_NOT_INITIALIZED;
207     }
208     CAsetTlsCredentialsCallback(getTlsCredentialsHandler);
209     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
210     return CA_STATUS_OK;
211 }
212
213 void GetPkixInfo(PkiInfo_t * inf)
214 {
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__);
221 }
222
223 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
224 {
225     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
226
227     if (!g_isInitialized)
228     {
229         return CA_STATUS_NOT_INITIALIZED;
230     }
231     CAsetPkixInfoCallback(getPkixInfoHandler);
232     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
233     return CA_STATUS_OK;
234 }
235 #endif
236
237 #ifdef __WITH_X509__
238 CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
239 {
240     OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
241
242     if (!g_isInitialized)
243     {
244         return CA_STATUS_NOT_INITIALIZED;
245     }
246
247     CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
248     return CA_STATUS_OK;
249 }
250
251 CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
252 {
253     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
254
255     if (!g_isInitialized)
256     {
257         return CA_STATUS_NOT_INITIALIZED;
258     }
259
260     CADTLSSetCrlCallback(GetDTLSCrlHandler);
261     return CA_STATUS_OK;
262 }
263 #endif //__WITH_X509__
264
265 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
266                             CATransportAdapter_t adapter,
267                             const char *addr,
268                             uint16_t port,
269                             CAEndpoint_t **object)
270 {
271     if (!object)
272     {
273         OIC_LOG(ERROR, TAG, "Invalid Parameter");
274         return CA_STATUS_INVALID_PARAM;
275     }
276
277     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
278     if (!endpoint)
279     {
280         return CA_STATUS_FAILED;
281     }
282     *object = endpoint;
283     return CA_STATUS_OK;
284 }
285
286 void CADestroyEndpoint(CAEndpoint_t *rep)
287 {
288     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
289
290     CAFreeEndpoint(rep);
291 }
292
293 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
294 {
295     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
296
297     return CAGenerateTokenInternal(token, tokenLength);
298 }
299
300 void CADestroyToken(CAToken_t token)
301 {
302     OIC_LOG(DEBUG, TAG, "CADestroyToken");
303
304     CADestroyTokenInternal(token);
305
306     OIC_LOG(DEBUG, TAG, "OUT");
307 }
308
309 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
310 {
311     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
312
313     if (!g_isInitialized)
314     {
315         return CA_STATUS_NOT_INITIALIZED;
316     }
317
318     return CAGetNetworkInformationInternal(info, size);
319 }
320
321 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
322                                             CADataType_t dataType)
323 {
324     OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
325
326     CATransportAdapter_t connTypes[] = {
327             CA_ADAPTER_IP
328 #ifdef LE_ADAPTER
329             ,CA_ADAPTER_GATT_BTLE
330 #endif
331 #ifdef EDR_ADAPTER
332             ,CA_ADAPTER_RFCOMM_BTEDR
333 #endif
334 #ifdef NFC_ADAPTER
335             ,CA_ADAPTER_NFC
336 #endif
337 #ifdef RA_ADAPTER
338             ,CA_ADAPTER_REMOTE_ACCESS
339 #endif
340 #ifdef TCP_ADAPTER
341             ,CA_ADAPTER_TCP
342 #endif
343         };
344
345     CAEndpoint_t *cloneEp = CACloneEndpoint(object);
346     if (!cloneEp)
347     {
348         OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
349         return CA_MEMORY_ALLOC_FAILED;
350     }
351
352     CAResult_t ret = CA_STATUS_OK;
353     size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
354
355     for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
356     {
357         cloneEp->adapter = connTypes[i];
358         ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
359     }
360     CAFreeEndpoint(cloneEp);
361     return ret;
362 }
363
364 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
365 {
366     OIC_LOG(DEBUG, TAG, "CASendRequest");
367
368     if (!g_isInitialized)
369     {
370         return CA_STATUS_NOT_INITIALIZED;
371     }
372
373     if (requestInfo && requestInfo->isMulticast &&
374             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
375     {
376         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
377     }
378     else
379     {
380         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
381     }
382 }
383
384 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
385 {
386     OIC_LOG(DEBUG, TAG, "CASendResponse");
387
388     if (!g_isInitialized)
389     {
390         return CA_STATUS_NOT_INITIALIZED;
391     }
392
393     if (!responseInfo || !object)
394     {
395         return CA_STATUS_INVALID_PARAM;
396     }
397
398     if (responseInfo->isMulticast &&
399             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
400     {
401         return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
402     }
403     else
404     {
405         return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
406     }
407 }
408
409 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
410 {
411     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
412
413     if (!g_isInitialized)
414     {
415         return CA_STATUS_NOT_INITIALIZED;
416     }
417
418     CAResult_t res = CA_STATUS_OK;
419
420     if (interestedNetwork & CA_ADAPTER_IP)
421     {
422         res = CAAddNetworkType(CA_ADAPTER_IP);
423         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
424     }
425     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
426     {
427         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
428         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
429     }
430     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
431     {
432         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
433         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
434     }
435
436 #ifdef RA_ADAPTER
437     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
438     {
439         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
440         OIC_LOG_V(DEBUG, TAG,
441                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
442     }
443 #endif
444
445 #ifdef TCP_ADAPTER
446     else if (interestedNetwork & CA_ADAPTER_TCP)
447     {
448         res = CAAddNetworkType(CA_ADAPTER_TCP);
449         OIC_LOG_V(DEBUG, TAG,
450                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
451     }
452 #endif
453     else if (interestedNetwork & CA_ADAPTER_NFC)
454     {
455         res = CAAddNetworkType(CA_ADAPTER_NFC);
456         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
457     }
458     else
459     {
460         res = CA_NOT_SUPPORTED;
461     }
462     return res;
463 }
464
465 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
466 {
467     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
468
469     if (!g_isInitialized)
470     {
471         return CA_STATUS_NOT_INITIALIZED;
472     }
473
474     CAResult_t res = CA_STATUS_OK;
475
476     if (nonInterestedNetwork & CA_ADAPTER_IP)
477     {
478         res = CARemoveNetworkType(CA_ADAPTER_IP);
479         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
480     }
481     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
482     {
483         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
484         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
485     }
486     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
487     {
488         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
489         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
490     }
491 #ifdef RA_ADAPTER
492     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
493     {
494         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
495         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
496                   res);
497     }
498 #endif
499
500
501 #ifdef TCP_ADAPTER
502     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
503     {
504         res = CARemoveNetworkType(CA_ADAPTER_TCP);
505         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
506                   res);
507     }
508 #endif
509
510     else
511     {
512         res = CA_STATUS_FAILED;
513     }
514     return res;
515 }
516
517 CAResult_t CAHandleRequestResponse()
518 {
519     if (!g_isInitialized)
520     {
521         OIC_LOG(ERROR, TAG, "not initialized");
522         return CA_STATUS_NOT_INITIALIZED;
523     }
524
525     CAHandleRequestResponseCallbacks();
526
527     return CA_STATUS_OK;
528 }
529
530 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
531 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
532 {
533     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
534     if(CA_ADAPTER_IP == adapter)
535     {
536         if (CA_STATUS_OK != CADtlsSelectCipherSuite(cipher))
537         {
538             return CA_STATUS_FAILED;
539         }
540     }
541 #ifdef __WITH_TLS__
542     else if(CA_ADAPTER_TCP == adapter)
543     {
544         if (CA_STATUS_OK != CAsetTlsCipherSuite(cipher))
545         {
546             return CA_STATUS_FAILED;
547         }
548     }
549 #endif
550     return CA_STATUS_OK;
551 }
552
553 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
554 {
555     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
556
557 #ifdef __WITH_DTLS__
558     if (CA_STATUS_OK != CADtlsEnableAnonECDHCipherSuite(enable))
559     {
560         return CA_STATUS_FAILED;
561     }
562 #endif
563 #ifdef __WITH_TLS__
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))
567     {
568         return CA_STATUS_FAILED;
569     }
570 #endif
571     return CA_STATUS_OK;
572 }
573
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)
579 {
580     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
581
582     CAResult_t res = CA_STATUS_OK;
583
584     //newOwnerLabel and prevOwnerLabe can be NULL
585     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
586     {
587         return CA_STATUS_INVALID_PARAM;
588     }
589
590     if(CA_ADAPTER_IP == endpoint->adapter)
591     {
592         res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
593                                       rsrcServerDeviceID, rsrcServerDeviceIDLen,
594                                       provServerDeviceID, provServerDeviceIDLen,
595                                       ownerPSK, ownerPSKSize);
596     }
597 #ifdef __WITH_TLS__
598     else
599     {
600         res = CAtlsGenerateOwnerPSK(endpoint, ownerPSK, ownerPSKSize,
601                 rsrcServerDeviceID, rsrcServerDeviceIDLen);
602     }
603 #endif
604     if (CA_STATUS_OK != res)
605     {
606         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
607     }
608
609     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
610
611     return res;
612 }
613
614 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
615 {
616     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
617     CAResult_t res = CA_STATUS_OK;
618
619     if (!endpoint)
620     {
621         return CA_STATUS_INVALID_PARAM;
622     }
623
624     res = CADtlsInitiateHandshake(endpoint);
625     if (CA_STATUS_OK != res)
626     {
627         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
628     }
629
630     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
631
632     return res;
633 }
634
635 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
636 {
637     OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
638     CAResult_t res = CA_STATUS_OK;
639
640     if (!endpoint)
641     {
642         return CA_STATUS_INVALID_PARAM;
643     }
644
645     res = CADtlsClose(endpoint);
646     if (CA_STATUS_OK != res)
647     {
648         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
649     }
650
651     OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
652
653     return res;
654 }
655
656 #endif /* __WITH_DTLS__ */
657
658 #ifdef TCP_ADAPTER
659 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
660 {
661     CATCPSetKeepAliveCallbacks(ConnHandler);
662 }
663 #endif