f430de28d4757787f8540b6f97ca08990fb0c9e9
[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 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
144 CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
145 {
146     OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
147
148     if(!g_isInitialized)
149     {
150         return CA_STATUS_NOT_INITIALIZED;
151     }
152
153     CAsetSslHandshakeCallback(tlsHandshakeCallback);
154     return CA_STATUS_OK;
155 }
156
157 CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
158 {
159     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
160
161     if (!g_isInitialized)
162     {
163         return CA_STATUS_NOT_INITIALIZED;
164     }
165     CAsetPskCredentialsCallback(getTlsCredentialsHandler);
166     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
167     return CA_STATUS_OK;
168 }
169
170 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
171 {
172     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
173
174     if (!g_isInitialized)
175     {
176         return CA_STATUS_NOT_INITIALIZED;
177     }
178     CAsetPkixInfoCallback(getPkixInfoHandler);
179     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
180     return CA_STATUS_OK;
181 }
182
183 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
184 {
185     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
186
187     if (!g_isInitialized)
188     {
189         return CA_STATUS_NOT_INITIALIZED;
190     }
191     CAsetCredentialTypesCallback(getCredTypesHandler);
192     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
193     return CA_STATUS_OK;
194 }
195 #endif // __WITH_DTLS__ or __WITH_TLS__
196
197 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
198                             CATransportAdapter_t adapter,
199                             const char *addr,
200                             uint16_t port,
201                             CAEndpoint_t **object)
202 {
203     if (!object)
204     {
205         OIC_LOG(ERROR, TAG, "Invalid Parameter");
206         return CA_STATUS_INVALID_PARAM;
207     }
208
209     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
210     if (!endpoint)
211     {
212         return CA_STATUS_FAILED;
213     }
214     *object = endpoint;
215     return CA_STATUS_OK;
216 }
217
218 void CADestroyEndpoint(CAEndpoint_t *rep)
219 {
220     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
221
222     CAFreeEndpoint(rep);
223 }
224
225 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
226 {
227     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
228
229     return CAGenerateTokenInternal(token, tokenLength);
230 }
231
232 void CADestroyToken(CAToken_t token)
233 {
234     OIC_LOG(DEBUG, TAG, "CADestroyToken");
235
236     CADestroyTokenInternal(token);
237
238     OIC_LOG(DEBUG, TAG, "OUT");
239 }
240
241 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
242 {
243     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
244
245     if (!g_isInitialized)
246     {
247         return CA_STATUS_NOT_INITIALIZED;
248     }
249
250     return CAGetNetworkInformationInternal(info, size);
251 }
252
253 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
254                                             CADataType_t dataType)
255 {
256     OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
257
258     CATransportAdapter_t connTypes[] = {
259             CA_ADAPTER_IP
260 #ifdef LE_ADAPTER
261             ,CA_ADAPTER_GATT_BTLE
262 #endif
263 #ifdef EDR_ADAPTER
264             ,CA_ADAPTER_RFCOMM_BTEDR
265 #endif
266 #ifdef NFC_ADAPTER
267             ,CA_ADAPTER_NFC
268 #endif
269 #ifdef RA_ADAPTER
270             ,CA_ADAPTER_REMOTE_ACCESS
271 #endif
272 #ifdef TCP_ADAPTER
273             ,CA_ADAPTER_TCP
274 #endif
275         };
276
277     CAEndpoint_t *cloneEp = CACloneEndpoint(object);
278     if (!cloneEp)
279     {
280         OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
281         return CA_MEMORY_ALLOC_FAILED;
282     }
283
284     CAResult_t ret = CA_STATUS_OK;
285     size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
286
287     for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
288     {
289         cloneEp->adapter = connTypes[i];
290         ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
291     }
292     CAFreeEndpoint(cloneEp);
293     return ret;
294 }
295
296 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
297 {
298     OIC_LOG(DEBUG, TAG, "CASendRequest");
299
300     if (!g_isInitialized)
301     {
302         return CA_STATUS_NOT_INITIALIZED;
303     }
304
305     if (requestInfo && requestInfo->isMulticast &&
306             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
307     {
308         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
309     }
310     else
311     {
312         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
313     }
314 }
315
316 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
317 {
318     OIC_LOG(DEBUG, TAG, "CASendResponse");
319
320     if (!g_isInitialized)
321     {
322         return CA_STATUS_NOT_INITIALIZED;
323     }
324
325     if (!responseInfo || !object)
326     {
327         return CA_STATUS_INVALID_PARAM;
328     }
329
330     if (responseInfo->isMulticast &&
331             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
332     {
333         return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
334     }
335     else
336     {
337         return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
338     }
339 }
340
341 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
342 {
343     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
344
345     if (!g_isInitialized)
346     {
347         return CA_STATUS_NOT_INITIALIZED;
348     }
349
350     CAResult_t res = CA_STATUS_OK;
351
352     if (interestedNetwork & CA_ADAPTER_IP)
353     {
354         res = CAAddNetworkType(CA_ADAPTER_IP);
355         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
356     }
357     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
358     {
359         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
360         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
361     }
362     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
363     {
364         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
365         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
366     }
367
368 #ifdef RA_ADAPTER
369     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
370     {
371         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
372         OIC_LOG_V(DEBUG, TAG,
373                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
374     }
375 #endif
376
377 #ifdef TCP_ADAPTER
378     else if (interestedNetwork & CA_ADAPTER_TCP)
379     {
380         res = CAAddNetworkType(CA_ADAPTER_TCP);
381         OIC_LOG_V(DEBUG, TAG,
382                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
383     }
384 #endif
385     else if (interestedNetwork & CA_ADAPTER_NFC)
386     {
387         res = CAAddNetworkType(CA_ADAPTER_NFC);
388         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
389     }
390     else
391     {
392         res = CA_NOT_SUPPORTED;
393     }
394     return res;
395 }
396
397 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
398 {
399     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
400
401     if (!g_isInitialized)
402     {
403         return CA_STATUS_NOT_INITIALIZED;
404     }
405
406     CAResult_t res = CA_STATUS_OK;
407
408     if (nonInterestedNetwork & CA_ADAPTER_IP)
409     {
410         res = CARemoveNetworkType(CA_ADAPTER_IP);
411         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
412     }
413     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
414     {
415         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
416         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
417     }
418     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
419     {
420         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
421         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
422     }
423 #ifdef RA_ADAPTER
424     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
425     {
426         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
427         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
428                   res);
429     }
430 #endif
431
432
433 #ifdef TCP_ADAPTER
434     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
435     {
436         res = CARemoveNetworkType(CA_ADAPTER_TCP);
437         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
438                   res);
439     }
440 #endif
441
442     else
443     {
444         res = CA_STATUS_FAILED;
445     }
446     return res;
447 }
448
449 CAResult_t CAHandleRequestResponse()
450 {
451     if (!g_isInitialized)
452     {
453         OIC_LOG(ERROR, TAG, "not initialized");
454         return CA_STATUS_NOT_INITIALIZED;
455     }
456
457     CAHandleRequestResponseCallbacks();
458
459     return CA_STATUS_OK;
460 }
461
462 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
463 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
464 {
465     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
466     OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
467     if (CA_STATUS_OK != CAsetTlsCipherSuite(cipher))
468     {
469         OIC_LOG_V(ERROR, TAG, "Out %s", __func__);
470         return CA_STATUS_FAILED;
471     }
472     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
473     return CA_STATUS_OK;
474 }
475
476 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
477 {
478     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
479
480 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
481     // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
482     // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037
483     if (CA_STATUS_OK != CAsetTlsCipherSuite(enable ? 0xFF00 : 0xC037))
484     {
485         return CA_STATUS_FAILED;
486     }
487 #endif
488     return CA_STATUS_OK;
489 }
490
491 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
492                     const uint8_t* label, const size_t labelLen,
493                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
494                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
495                     uint8_t* ownerPSK, const size_t ownerPskSize)
496 {
497     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
498
499     CAResult_t res = CA_STATUS_OK;
500
501     //newOwnerLabel and prevOwnerLabe can be NULL
502     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
503     {
504         return CA_STATUS_INVALID_PARAM;
505     }
506
507     res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
508                                       rsrcServerDeviceID, rsrcServerDeviceIDLen,
509                                       provServerDeviceID, provServerDeviceIDLen,
510                                       ownerPSK, ownerPskSize);
511
512     if (CA_STATUS_OK != res)
513     {
514         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
515     }
516
517     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
518
519     return res;
520 }
521
522 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
523 {
524     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
525     CAResult_t res = CA_STATUS_OK;
526
527     if (!endpoint)
528     {
529         return CA_STATUS_INVALID_PARAM;
530     }
531
532     res = CAinitiateSslHandshake(endpoint);
533     if (CA_STATUS_OK != res)
534     {
535         OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
536     }
537
538     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
539
540     return res;
541 }
542
543 CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
544 {
545     OIC_LOG_V(DEBUG, TAG, "IN : CAcloseSslSession");
546     CAResult_t res = CA_STATUS_OK;
547
548     if (!endpoint)
549     {
550         return CA_STATUS_INVALID_PARAM;
551     }
552
553     res = CAcloseSslConnection(endpoint);
554     if (CA_STATUS_OK != res)
555     {
556         OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
557     }
558
559     OIC_LOG_V(DEBUG, TAG, "OUT : CAcloseSslSession");
560
561     return res;
562 }
563
564 #endif /* __WITH_DTLS__ */
565
566 #ifdef TCP_ADAPTER
567 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
568 {
569     CATCPSetKeepAliveCallbacks(ConnHandler);
570 }
571 #endif