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