Merge branch '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 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
214 {
215     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
216
217     if (!g_isInitialized)
218     {
219         return CA_STATUS_NOT_INITIALIZED;
220     }
221     CAsetPkixInfoCallback(getPkixInfoHandler);
222     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
223     return CA_STATUS_OK;
224 }
225 #endif
226
227 #ifdef __WITH_X509__
228 CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
229 {
230     OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
231
232     if (!g_isInitialized)
233     {
234         return CA_STATUS_NOT_INITIALIZED;
235     }
236
237     CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
238     return CA_STATUS_OK;
239 }
240
241 CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
242 {
243     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
244
245     if (!g_isInitialized)
246     {
247         return CA_STATUS_NOT_INITIALIZED;
248     }
249
250     CADTLSSetCrlCallback(GetDTLSCrlHandler);
251     return CA_STATUS_OK;
252 }
253 #endif //__WITH_X509__
254
255 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
256                             CATransportAdapter_t adapter,
257                             const char *addr,
258                             uint16_t port,
259                             CAEndpoint_t **object)
260 {
261     if (!object)
262     {
263         OIC_LOG(ERROR, TAG, "Invalid Parameter");
264         return CA_STATUS_INVALID_PARAM;
265     }
266
267     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
268     if (!endpoint)
269     {
270         return CA_STATUS_FAILED;
271     }
272     *object = endpoint;
273     return CA_STATUS_OK;
274 }
275
276 void CADestroyEndpoint(CAEndpoint_t *rep)
277 {
278     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
279
280     CAFreeEndpoint(rep);
281 }
282
283 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
284 {
285     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
286
287     return CAGenerateTokenInternal(token, tokenLength);
288 }
289
290 void CADestroyToken(CAToken_t token)
291 {
292     OIC_LOG(DEBUG, TAG, "CADestroyToken");
293
294     CADestroyTokenInternal(token);
295
296     OIC_LOG(DEBUG, TAG, "OUT");
297 }
298
299 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
300 {
301     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
302
303     if (!g_isInitialized)
304     {
305         return CA_STATUS_NOT_INITIALIZED;
306     }
307
308     return CAGetNetworkInformationInternal(info, size);
309 }
310
311 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
312                                             CADataType_t dataType)
313 {
314     OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
315
316     CATransportAdapter_t connTypes[] = {
317             CA_ADAPTER_IP
318 #ifdef LE_ADAPTER
319             ,CA_ADAPTER_GATT_BTLE
320 #endif
321 #ifdef EDR_ADAPTER
322             ,CA_ADAPTER_RFCOMM_BTEDR
323 #endif
324 #ifdef NFC_ADAPTER
325             ,CA_ADAPTER_NFC
326 #endif
327 #ifdef RA_ADAPTER
328             ,CA_ADAPTER_REMOTE_ACCESS
329 #endif
330 #ifdef TCP_ADAPTER
331             ,CA_ADAPTER_TCP
332 #endif
333         };
334
335     CAEndpoint_t *cloneEp = CACloneEndpoint(object);
336     if (!cloneEp)
337     {
338         OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
339         return CA_MEMORY_ALLOC_FAILED;
340     }
341
342     CAResult_t ret = CA_STATUS_OK;
343     size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
344
345     for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
346     {
347         cloneEp->adapter = connTypes[i];
348         ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
349     }
350     CAFreeEndpoint(cloneEp);
351     return ret;
352 }
353
354 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
355 {
356     OIC_LOG(DEBUG, TAG, "CASendRequest");
357
358     if (!g_isInitialized)
359     {
360         return CA_STATUS_NOT_INITIALIZED;
361     }
362
363     if (requestInfo && requestInfo->isMulticast &&
364             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
365     {
366         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
367     }
368     else
369     {
370         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
371     }
372 }
373
374 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
375 {
376     OIC_LOG(DEBUG, TAG, "CASendResponse");
377
378     if (!g_isInitialized)
379     {
380         return CA_STATUS_NOT_INITIALIZED;
381     }
382
383     if (!responseInfo || !object)
384     {
385         return CA_STATUS_INVALID_PARAM;
386     }
387
388     if (responseInfo->isMulticast &&
389             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
390     {
391         return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
392     }
393     else
394     {
395         return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
396     }
397 }
398
399 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
400 {
401     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
402
403     if (!g_isInitialized)
404     {
405         return CA_STATUS_NOT_INITIALIZED;
406     }
407
408     CAResult_t res = CA_STATUS_OK;
409
410     if (interestedNetwork & CA_ADAPTER_IP)
411     {
412         res = CAAddNetworkType(CA_ADAPTER_IP);
413         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
414     }
415     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
416     {
417         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
418         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
419     }
420     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
421     {
422         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
423         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
424     }
425
426 #ifdef RA_ADAPTER
427     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
428     {
429         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
430         OIC_LOG_V(DEBUG, TAG,
431                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
432     }
433 #endif
434
435 #ifdef TCP_ADAPTER
436     else if (interestedNetwork & CA_ADAPTER_TCP)
437     {
438         res = CAAddNetworkType(CA_ADAPTER_TCP);
439         OIC_LOG_V(DEBUG, TAG,
440                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
441     }
442 #endif
443     else if (interestedNetwork & CA_ADAPTER_NFC)
444     {
445         res = CAAddNetworkType(CA_ADAPTER_NFC);
446         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
447     }
448     else
449     {
450         res = CA_NOT_SUPPORTED;
451     }
452     return res;
453 }
454
455 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
456 {
457     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
458
459     if (!g_isInitialized)
460     {
461         return CA_STATUS_NOT_INITIALIZED;
462     }
463
464     CAResult_t res = CA_STATUS_OK;
465
466     if (nonInterestedNetwork & CA_ADAPTER_IP)
467     {
468         res = CARemoveNetworkType(CA_ADAPTER_IP);
469         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
470     }
471     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
472     {
473         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
474         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
475     }
476     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
477     {
478         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
479         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
480     }
481 #ifdef RA_ADAPTER
482     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
483     {
484         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
485         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
486                   res);
487     }
488 #endif
489
490
491 #ifdef TCP_ADAPTER
492     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
493     {
494         res = CARemoveNetworkType(CA_ADAPTER_TCP);
495         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
496                   res);
497     }
498 #endif
499
500     else
501     {
502         res = CA_STATUS_FAILED;
503     }
504     return res;
505 }
506
507 CAResult_t CAHandleRequestResponse()
508 {
509     if (!g_isInitialized)
510     {
511         OIC_LOG(ERROR, TAG, "not initialized");
512         return CA_STATUS_NOT_INITIALIZED;
513     }
514
515     CAHandleRequestResponseCallbacks();
516
517     return CA_STATUS_OK;
518 }
519
520 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
521 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
522 {
523     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
524     if(CA_ADAPTER_IP == adapter)
525     {
526         if (CA_STATUS_OK != CADtlsSelectCipherSuite(cipher))
527         {
528             return CA_STATUS_FAILED;
529         }
530     }
531 #ifdef __WITH_TLS__
532     else if(CA_ADAPTER_TCP == adapter)
533     {
534         if (CA_STATUS_OK != CAsetTlsCipherSuite(cipher))
535         {
536             return CA_STATUS_FAILED;
537         }
538     }
539 #endif
540     return CA_STATUS_OK;
541 }
542
543 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
544 {
545     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
546
547 #ifdef __WITH_DTLS__
548     if (CA_STATUS_OK != CADtlsEnableAnonECDHCipherSuite(enable))
549     {
550         return CA_STATUS_FAILED;
551     }
552 #endif
553 #ifdef __WITH_TLS__
554     // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
555     // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037
556     if (CA_STATUS_OK != CAsetTlsCipherSuite(enable ? 0xFF00 : 0xC037))
557     {
558         return CA_STATUS_FAILED;
559     }
560 #endif
561     return CA_STATUS_OK;
562 }
563
564 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
565                     const uint8_t* label, const size_t labelLen,
566                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
567                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
568                     uint8_t* ownerPSK, const size_t ownerPSKSize)
569 {
570     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
571
572     CAResult_t res = CA_STATUS_OK;
573
574     //newOwnerLabel and prevOwnerLabe can be NULL
575     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
576     {
577         return CA_STATUS_INVALID_PARAM;
578     }
579
580     if(CA_ADAPTER_IP == endpoint->adapter)
581     {
582         res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
583                                       rsrcServerDeviceID, rsrcServerDeviceIDLen,
584                                       provServerDeviceID, provServerDeviceIDLen,
585                                       ownerPSK, ownerPSKSize);
586     }
587 #ifdef __WITH_TLS__
588     else
589     {
590         res = CAtlsGenerateOwnerPSK(endpoint, ownerPSK, ownerPSKSize,
591                 rsrcServerDeviceID, rsrcServerDeviceIDLen);
592     }
593 #endif
594     if (CA_STATUS_OK != res)
595     {
596         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
597     }
598
599     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
600
601     return res;
602 }
603
604 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
605 {
606     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
607     CAResult_t res = CA_STATUS_OK;
608
609     if (!endpoint)
610     {
611         return CA_STATUS_INVALID_PARAM;
612     }
613
614     res = CADtlsInitiateHandshake(endpoint);
615     if (CA_STATUS_OK != res)
616     {
617         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
618     }
619
620     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
621
622     return res;
623 }
624
625 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
626 {
627     OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
628     CAResult_t res = CA_STATUS_OK;
629
630     if (!endpoint)
631     {
632         return CA_STATUS_INVALID_PARAM;
633     }
634
635     res = CADtlsClose(endpoint);
636     if (CA_STATUS_OK != res)
637     {
638         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
639     }
640
641     OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
642
643     return res;
644 }
645
646 #endif /* __WITH_DTLS__ */
647
648 #ifdef TCP_ADAPTER
649 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
650 {
651     CATCPSetKeepAliveCallbacks(ConnHandler);
652 }
653 #endif