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