Merge branch 'master' into simulator.
[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 "cainterface.h"
27 #include "caremotehandler.h"
28 #include "camessagehandler.h"
29 #include "caprotocolmessage.h"
30 #include "canetworkconfigurator.h"
31 #include "cainterfacecontroller.h"
32 #include "logger.h"
33 #ifdef __WITH_DTLS__
34 #include "caadapternetdtls.h"
35 #endif
36
37 #ifdef TCP_ADAPTER
38 #include "catcpadapter.h"
39 #endif
40
41 #include "ocrandom.h"
42
43
44 CAGlobals_t caglobals = { 0 };
45
46 #define TAG "CA_CONN_MGR"
47
48 static bool g_isInitialized = false;
49
50 #ifdef __WITH_DTLS__
51 // CAAdapterNetDTLS will register the callback.
52 // Taking callback all the way through adapters not the right approach, hence calling here.
53 extern void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
54 #endif
55
56 #ifdef __WITH_X509__
57 // CAAdapterNetDTLS will register the callback.
58 // Taking callback all the way through adapters not the right approach, hence calling here.
59 extern void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback);
60 extern void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback);
61 #endif
62
63 CAResult_t CAInitialize()
64 {
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 CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
151 {
152     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
153
154     if(!g_isInitialized)
155     {
156         return CA_STATUS_NOT_INITIALIZED;
157     }
158
159     CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
160     return CA_STATUS_OK;
161 }
162 #endif //__WITH_DTLS__
163
164 #ifdef __WITH_X509__
165 CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
166 {
167     OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
168
169     if(!g_isInitialized)
170     {
171         return CA_STATUS_NOT_INITIALIZED;
172     }
173
174     CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
175     return CA_STATUS_OK;
176 }
177
178 CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
179 {
180     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
181
182     if(!g_isInitialized)
183     {
184         return CA_STATUS_NOT_INITIALIZED;
185     }
186
187     CADTLSSetCrlCallback(GetDTLSCrlHandler);
188     return CA_STATUS_OK;
189 }
190 #endif //__WITH_X509__
191
192 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
193                             CATransportAdapter_t adapter,
194                             const char *addr,
195                             uint16_t port,
196                             CAEndpoint_t **object)
197 {
198     if (!object)
199     {
200         OIC_LOG(ERROR, TAG, "Invalid Parameter");
201         return CA_STATUS_INVALID_PARAM;
202     }
203
204     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
205     if (!endpoint)
206     {
207         return CA_STATUS_FAILED;
208     }
209     *object = endpoint;
210     return CA_STATUS_OK;
211 }
212
213 void CADestroyEndpoint(CAEndpoint_t *rep)
214 {
215     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
216
217     CAFreeEndpoint(rep);
218 }
219
220 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
221 {
222     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
223
224     return CAGenerateTokenInternal(token, tokenLength);
225 }
226
227 void CADestroyToken(CAToken_t token)
228 {
229     OIC_LOG(DEBUG, TAG, "CADestroyToken");
230
231     CADestroyTokenInternal(token);
232
233     OIC_LOG(DEBUG, TAG, "OUT");
234 }
235
236 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
237 {
238     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
239
240     if(!g_isInitialized)
241     {
242         return CA_STATUS_NOT_INITIALIZED;
243     }
244
245     return CAGetNetworkInformationInternal(info, size);
246 }
247
248 CAResult_t CASendRequest(const CAEndpoint_t *object,const CARequestInfo_t *requestInfo)
249 {
250     OIC_LOG(DEBUG, TAG, "CASendGetRequest");
251
252     if(!g_isInitialized)
253     {
254         return CA_STATUS_NOT_INITIALIZED;
255     }
256
257     return CADetachRequestMessage(object, requestInfo);
258 }
259
260 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
261 {
262     OIC_LOG(DEBUG, TAG, "CASendResponse");
263
264     if(!g_isInitialized)
265     {
266         return CA_STATUS_NOT_INITIALIZED;
267     }
268
269     return CADetachResponseMessage(object, responseInfo);
270 }
271
272 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
273 {
274     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
275
276     if(!g_isInitialized)
277     {
278         return CA_STATUS_NOT_INITIALIZED;
279     }
280
281     CAResult_t res = CA_STATUS_OK;
282
283     if (interestedNetwork & CA_ADAPTER_IP)
284     {
285         res = CAAddNetworkType(CA_ADAPTER_IP);
286         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
287     }
288     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
289     {
290         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
291         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
292     }
293     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
294     {
295         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
296         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
297     }
298
299 #ifdef RA_ADAPTER
300     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
301     {
302         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
303         OIC_LOG_V(DEBUG, TAG,
304                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
305     }
306 #endif
307
308 #ifdef TCP_ADAPTER
309     else if (interestedNetwork & CA_ADAPTER_TCP)
310     {
311         res = CAAddNetworkType(CA_ADAPTER_TCP);
312         OIC_LOG_V(DEBUG, TAG,
313                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
314     }
315 #endif
316
317     else
318     {
319         res = CA_NOT_SUPPORTED;
320     }
321     return res;
322 }
323
324 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
325 {
326     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
327
328     if(!g_isInitialized)
329     {
330         return CA_STATUS_NOT_INITIALIZED;
331     }
332
333     CAResult_t res = CA_STATUS_OK;
334
335     if (nonInterestedNetwork & CA_ADAPTER_IP)
336     {
337         res = CARemoveNetworkType(CA_ADAPTER_IP);
338         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
339     }
340     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
341     {
342         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
343         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
344     }
345     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
346     {
347         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
348         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
349     }
350 #ifdef RA_ADAPTER
351     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
352     {
353         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
354         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
355                   res);
356     }
357 #endif
358
359
360 #ifdef TCP_ADAPTER
361     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
362     {
363         res = CARemoveNetworkType(CA_ADAPTER_TCP);
364         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
365                   res);
366     }
367 #endif
368
369     else
370     {
371         res = CA_STATUS_FAILED;
372     }
373     return res;
374 }
375
376 CAResult_t CAHandleRequestResponse()
377 {
378     if (!g_isInitialized)
379     {
380         OIC_LOG(ERROR, TAG, "not initialized");
381         return CA_STATUS_NOT_INITIALIZED;
382     }
383
384     CAHandleRequestResponseCallbacks();
385
386     return CA_STATUS_OK;
387 }
388
389 #ifdef __WITH_DTLS__
390
391 CAResult_t CASelectCipherSuite(const uint16_t cipher)
392 {
393     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
394
395     return CADtlsSelectCipherSuite(cipher);
396 }
397
398 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
399 {
400     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
401
402     return CADtlsEnableAnonECDHCipherSuite(enable);
403 }
404
405 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
406                     const uint8_t* label, const size_t labelLen,
407                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
408                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
409                     uint8_t* ownerPSK, const size_t ownerPSKSize)
410 {
411     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
412
413     CAResult_t res = CA_STATUS_OK;
414
415     //newOwnerLabel and prevOwnerLabe can be NULL
416     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
417     {
418         return CA_STATUS_INVALID_PARAM;
419     }
420
421     res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
422                                   rsrcServerDeviceID, rsrcServerDeviceIDLen,
423                                   provServerDeviceID, provServerDeviceIDLen,
424                                   ownerPSK, ownerPSKSize);
425     if (CA_STATUS_OK != res)
426     {
427         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
428     }
429
430     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
431
432     return res;
433 }
434
435 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
436 {
437     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
438     CAResult_t res = CA_STATUS_OK;
439
440     if (!endpoint)
441     {
442         return CA_STATUS_INVALID_PARAM;
443     }
444
445     res = CADtlsInitiateHandshake(endpoint);
446     if (CA_STATUS_OK != res)
447     {
448         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
449     }
450
451     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
452
453     return res;
454 }
455
456 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
457 {
458     OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
459     CAResult_t res = CA_STATUS_OK;
460
461     if (!endpoint)
462     {
463         return CA_STATUS_INVALID_PARAM;
464     }
465
466     res = CADtlsClose(endpoint);
467     if (CA_STATUS_OK != res)
468     {
469         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
470     }
471
472     OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
473
474     return res;
475 }
476
477 #endif /* __WITH_DTLS__ */