Merge branch 'master' into easysetup & CBOR changes
[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 CAGlobals_t caglobals = { 0 };
38
39 #define TAG "CA_CONN_MGR"
40
41 static bool g_isInitialized = false;
42
43 #ifdef __WITH_DTLS__
44 // CAAdapterNetDTLS will register the callback.
45 // Taking callback all the way through adapters not the right approach, hence calling here.
46 extern void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback);
47 #endif
48
49 CAResult_t CAInitialize()
50 {
51     OIC_LOG(DEBUG, TAG, "CAInitialize");
52
53     if (!g_isInitialized)
54     {
55         CAResult_t res = CAInitializeMessageHandler();
56         if (res != CA_STATUS_OK)
57         {
58             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
59             return res;
60         }
61         g_isInitialized = true;
62     }
63     return CA_STATUS_OK;
64 }
65
66 void CATerminate()
67 {
68     OIC_LOG(DEBUG, TAG, "CATerminate");
69
70     if (g_isInitialized)
71     {
72         CATerminateMessageHandler();
73         CATerminateNetworkType();
74
75         g_isInitialized = false;
76     }
77 }
78
79 CAResult_t CAStartListeningServer()
80 {
81     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
82
83     if(!g_isInitialized)
84     {
85         return CA_STATUS_NOT_INITIALIZED;
86     }
87
88     return CAStartListeningServerAdapters();
89 }
90
91 CAResult_t CAStartDiscoveryServer()
92 {
93     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
94
95     if(!g_isInitialized)
96     {
97         return CA_STATUS_NOT_INITIALIZED;
98     }
99
100     return CAStartDiscoveryServerAdapters();
101 }
102
103 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
104                        CAErrorCallback ErrorHandler)
105 {
106     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
107
108     if(!g_isInitialized)
109     {
110         OIC_LOG(DEBUG, TAG, "CA is not initialized");
111         return;
112     }
113
114     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
115 }
116
117 #ifdef __WITH_DTLS__
118 CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSCredentialsHandler GetDTLSCredentialsHandler)
119 {
120     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
121
122     if(!g_isInitialized)
123     {
124         return CA_STATUS_NOT_INITIALIZED;
125     }
126
127     CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
128     return CA_STATUS_OK;
129 }
130 #endif //__WITH_DTLS__
131
132 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
133                             CATransportAdapter_t adapter,
134                             const char *addr,
135                             uint16_t port,
136                             CAEndpoint_t **object)
137 {
138     if (!object)
139     {
140         OIC_LOG(ERROR, TAG, "Invalid Parameter");
141         return CA_STATUS_INVALID_PARAM;
142     }
143
144     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
145     if (!endpoint)
146     {
147         return CA_STATUS_FAILED;
148     }
149     *object = endpoint;
150     return CA_STATUS_OK;
151 }
152
153 void CADestroyEndpoint(CAEndpoint_t *rep)
154 {
155     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
156
157     CAFreeEndpoint(rep);
158 }
159
160 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
161 {
162     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
163
164     return CAGenerateTokenInternal(token, tokenLength);
165 }
166
167 void CADestroyToken(CAToken_t token)
168 {
169     OIC_LOG(DEBUG, TAG, "CADestroyToken");
170
171     CADestroyTokenInternal(token);
172
173     OIC_LOG(DEBUG, TAG, "OUT");
174 }
175
176 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
177 {
178     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
179
180     if(!g_isInitialized)
181     {
182         return CA_STATUS_NOT_INITIALIZED;
183     }
184
185     return CAGetNetworkInformationInternal(info, size);
186 }
187
188 CAResult_t CASendRequest(const CAEndpoint_t *object,const CARequestInfo_t *requestInfo)
189 {
190     OIC_LOG(DEBUG, TAG, "CASendGetRequest");
191
192     if(!g_isInitialized)
193     {
194         return CA_STATUS_NOT_INITIALIZED;
195     }
196
197     return CADetachRequestMessage(object, requestInfo);
198 }
199
200 CAResult_t CASendNotification(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
201 {
202     OIC_LOG(DEBUG, TAG, "CASendNotification");
203
204     if(!g_isInitialized)
205     {
206         return CA_STATUS_NOT_INITIALIZED;
207     }
208
209     return CADetachResponseMessage(object, responseInfo);
210 }
211
212 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
213 {
214     OIC_LOG(DEBUG, TAG, "CASendResponse");
215
216     if(!g_isInitialized)
217     {
218         return CA_STATUS_NOT_INITIALIZED;
219     }
220
221     return CADetachResponseMessage(object, responseInfo);
222 }
223
224 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
225 {
226     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
227
228     if(!g_isInitialized)
229     {
230         return CA_STATUS_NOT_INITIALIZED;
231     }
232
233     CAResult_t res = CA_STATUS_OK;
234
235     if (interestedNetwork & CA_ADAPTER_IP)
236     {
237         res = CAAddNetworkType(CA_ADAPTER_IP);
238         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns error : %d", res);
239     }
240     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
241     {
242         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
243         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns error : %d", res);
244     }
245     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
246     {
247         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
248         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
249     }
250
251     #ifdef RA_ADAPTER
252     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
253     {
254         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
255         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
256                                                                     res);
257     }
258     #endif
259     else
260     {
261         res = CA_NOT_SUPPORTED;
262     }
263     return res;
264 }
265
266 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
267 {
268     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
269
270     if(!g_isInitialized)
271     {
272         return CA_STATUS_NOT_INITIALIZED;
273     }
274
275     CAResult_t res = CA_STATUS_OK;
276
277     if (nonInterestedNetwork & CA_ADAPTER_IP)
278     {
279         res = CARemoveNetworkType(CA_ADAPTER_IP);
280         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns error : %d", res);
281     }
282     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
283     {
284         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
285         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns error : %d", res);
286     }
287     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
288     {
289         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
290         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns error : %d", res);
291     }
292     #ifdef RA_ADAPTER
293     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
294     {
295         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
296         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns error : %d",
297                                                 res);
298     }
299     #endif
300     else
301     {
302         res = CA_STATUS_FAILED;
303     }
304     return res;
305 }
306
307 CAResult_t CAHandleRequestResponse()
308 {
309     if (!g_isInitialized)
310     {
311         OIC_LOG(ERROR, TAG, "not initialized");
312         return CA_STATUS_NOT_INITIALIZED;
313     }
314
315     CAHandleRequestResponseCallbacks();
316
317     return CA_STATUS_OK;
318 }
319
320 #ifdef __WITH_DTLS__
321
322 CAResult_t CASelectCipherSuite(const uint16_t cipher)
323 {
324     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
325
326     return CADtlsSelectCipherSuite(cipher);
327 }
328
329 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
330 {
331     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
332
333     return CADtlsEnableAnonECDHCipherSuite(enable);
334 }
335
336 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
337                     const uint8_t* label, const size_t labelLen,
338                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
339                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
340                     uint8_t* ownerPSK, const size_t ownerPSKSize)
341 {
342     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
343
344     CAResult_t res = CA_STATUS_OK;
345
346     //newOwnerLabel and prevOwnerLabe can be NULL
347     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
348     {
349         return CA_STATUS_INVALID_PARAM;
350     }
351
352     res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
353                                   rsrcServerDeviceID, rsrcServerDeviceIDLen,
354                                   provServerDeviceID, provServerDeviceIDLen,
355                                   ownerPSK, ownerPSKSize);
356     if (CA_STATUS_OK != res)
357     {
358         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
359     }
360
361     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
362
363     return res;
364 }
365
366 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
367 {
368     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
369     CAResult_t res = CA_STATUS_OK;
370
371     if (!endpoint)
372     {
373         return CA_STATUS_INVALID_PARAM;
374     }
375
376     res = CADtlsInitiateHandshake(endpoint);
377     if (CA_STATUS_OK != res)
378     {
379         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
380     }
381
382     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
383
384     return res;
385 }
386
387 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
388 {
389     OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
390     CAResult_t res = CA_STATUS_OK;
391
392     if (!endpoint)
393     {
394         return CA_STATUS_INVALID_PARAM;
395     }
396
397     res = CADtlsClose(endpoint);
398     if (CA_STATUS_OK != res)
399     {
400         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
401     }
402
403     OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
404
405     return res;
406 }
407
408 #endif /* __WITH_DTLS__ */