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