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