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