Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / cainterfacecontroller_singlethread.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 "cainterfacecontroller_singlethread.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdint.h>
27
28 #include "caipadapter_singlethread.h"
29 #include "caedradapter_singlethread.h"
30 #include "caleadapter_singlethread.h"
31 #include "caadapterutils.h"
32
33 #include "canetworkconfigurator.h"
34 #include "oic_malloc.h"
35 #include "logger.h"
36
37 #define TAG "CAIFCNT_ST"
38
39 #define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG(ERROR, TAG, "Out of memory");\
40     goto memory_error_exit;} }
41
42 #define CA_CONNECTIVITY_TYPE_NUM   4
43
44 static CAConnectivityHandler_t g_adapterHandler[CA_CONNECTIVITY_TYPE_NUM];
45
46 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
47
48 static CANetworkChangeCallback g_networkChangeCallback = NULL;
49
50 static int CAGetAdapterIndex(CATransportType_t cType)
51 {
52     switch (cType)
53     {
54         case CA_IPV4:
55             return 0;
56         case CA_IPV6:
57             return 1;
58         case CA_EDR:
59             return 2;
60         case CA_LE:
61             return 3;
62     }
63
64     OIC_LOG(DEBUG, TAG, "CA_CONNECTIVITY_TYPE_NUM is not 4");
65
66     return -1;
67 }
68
69 static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportType_t cType)
70 {
71     OIC_LOG(DEBUG, TAG, "IN");
72
73     if(handler.startAdapter == NULL ||
74         handler.startListenServer == NULL ||
75         handler.startDiscoveryServer == NULL ||
76         handler.sendData == NULL ||
77         handler.sendDataToAll == NULL ||
78         handler.GetnetInfo == NULL ||
79         handler.readData == NULL ||
80         handler.stopAdapter == NULL ||
81         handler.terminate == NULL)
82     {
83         OIC_LOG(ERROR, TAG, "connectivity handler is not enough to be used!");
84         return;
85     }
86
87     int index = CAGetAdapterIndex(cType);
88
89     if (index == -1)
90     {
91         OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
92         return;
93     }
94
95     memcpy(&g_adapterHandler[index], &handler, sizeof(CAConnectivityHandler_t));
96
97     OIC_LOG_V(DEBUG, TAG, "%d type adapter", cType);
98     OIC_LOG(DEBUG, TAG, "OUT");
99 }
100
101 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
102     uint32_t dataLen)
103 {
104     OIC_LOG(DEBUG, TAG, "IN");
105
106     // Call the callback.
107     if (g_networkPacketReceivedCallback != NULL)
108     {
109         g_networkPacketReceivedCallback(endpoint, data, dataLen);
110     }
111     OIC_LOG(DEBUG, TAG, "OUT");
112 }
113
114 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
115 {
116     OIC_LOG(DEBUG, TAG, "IN");
117
118     // Call the callback.
119     if (g_networkChangeCallback != NULL)
120     {
121         g_networkChangeCallback(info, status);
122     }
123     OIC_LOG(DEBUG, TAG, "OUT");
124 }
125
126 void CAInitializeAdapters()
127 {
128     OIC_LOG(DEBUG, TAG, "IN");
129
130     memset(g_adapterHandler, 0, sizeof(CAConnectivityHandler_t) * CA_CONNECTIVITY_TYPE_NUM);
131
132     // Initialize adapters and register callback.
133 #ifdef IP_ADAPTER
134     CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
135 #endif /* IP_ADAPTER */
136
137 #ifdef EDR_ADAPTER
138     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
139 #endif /* EDR_ADAPTER */
140
141 #ifdef LE_ADAPTER
142     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
143 #endif /* LE_ADAPTER */
144
145     OIC_LOG(DEBUG, TAG, "OUT");
146 }
147
148 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
149 {
150     OIC_LOG(DEBUG, TAG, "IN");
151
152     g_networkPacketReceivedCallback = callback;
153     OIC_LOG(DEBUG, TAG, "OUT");
154 }
155
156 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
157 {
158     OIC_LOG(DEBUG, TAG, "IN");
159
160     g_networkChangeCallback = callback;
161     OIC_LOG(DEBUG, TAG, "OUT");
162 }
163
164 CAResult_t CAStartAdapter(CATransportType_t transportType)
165 {
166     OIC_LOG_V(DEBUG, TAG, "transportType[%d]", transportType);
167
168     int index = CAGetAdapterIndex(transportType);
169
170     if (index == -1)
171     {
172         OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
173         return CA_STATUS_FAILED;
174     }
175
176     if (g_adapterHandler[index].startAdapter != NULL)
177     {
178         g_adapterHandler[index].startAdapter();
179     }
180     OIC_LOG(DEBUG, TAG, "OUT");
181     return CA_STATUS_OK;
182 }
183
184 void CAStopAdapter(CATransportType_t transportType)
185 {
186     OIC_LOG_V(DEBUG, TAG, "transportType[%d]", transportType);
187
188     int index = CAGetAdapterIndex(transportType);
189
190     if (index == -1)
191     {
192         OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
193         return;
194     }
195
196     if (g_adapterHandler[index].stopAdapter != NULL)
197     {
198         g_adapterHandler[index].stopAdapter();
199     }
200     OIC_LOG(DEBUG, TAG, "OUT");
201 }
202
203 CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
204 {
205     OIC_LOG(DEBUG, TAG, "IN");
206     VERIFY_NON_NULL(info, TAG, "info");
207     VERIFY_NON_NULL(size, TAG, "size");
208
209     CALocalConnectivity_t *tempInfo[CA_CONNECTIVITY_TYPE_NUM] = { 0 };
210     uint32_t tempSize[CA_CONNECTIVITY_TYPE_NUM] = { 0 };
211
212     CAResult_t res = CA_STATUS_FAILED;
213     // #1. get information each adapter
214     for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
215     {
216         if (g_adapterHandler[index].GetnetInfo != NULL)
217         {
218             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index], &tempSize[index]);
219
220             OIC_LOG_V (DEBUG, TAG, "%d adapter network info size is %d", index, tempSize[index]);
221         }
222     }
223
224     uint32_t resSize = 0;
225     for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
226     {
227         // check information
228         if (tempInfo[index] == NULL || tempSize[index] <= 0)
229         {
230             continue;
231         }
232
233         // #2. total size
234         resSize += tempSize[index];
235     }
236
237     OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize);
238
239     if (resSize <= 0)
240     {
241         if (CA_ADAPTER_NOT_ENABLED == res || CA_NOT_SUPPORTED == res)
242         {
243             return res;
244         }
245         return CA_STATUS_FAILED;
246     }
247
248     // #3. add data into result
249     // memory allocation
250     CALocalConnectivity_t *resInfo =
251         (CALocalConnectivity_t *) OICCalloc(resSize, sizeof(CALocalConnectivity_t));
252     CA_MEMORY_ALLOC_CHECK(resInfo);
253
254     uint8_t i = 0;
255     for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
256     {
257         // check information
258         if (tempInfo[index] == NULL || tempSize[index] <= 0)
259         {
260             continue;
261         }
262
263         memcpy(resInfo + i, tempInfo[index], sizeof(CALocalConnectivity_t) * tempSize[index]);
264
265         i += tempSize[index];
266
267         // free adapter data
268         OICFree(tempInfo[index]);
269     }
270
271     // #5. save data
272     *info = resInfo;
273     *size = resSize;
274
275     OIC_LOG(DEBUG, TAG, "OUT");
276
277     return res;
278
279     // memory error label.
280 memory_error_exit:
281
282     for (uint8_t index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
283     {
284
285         OICFree(tempInfo[index]);
286     }
287
288     return CA_MEMORY_ALLOC_FAILED;
289 }
290
291 CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length)
292 {
293     OIC_LOG(DEBUG, TAG, "IN");
294
295     CAResult_t res = CA_STATUS_FAILED;
296
297     if (endpoint == NULL)
298     {
299         OIC_LOG(DEBUG, TAG, "RemoteEndpoint is NULL");
300         return CA_STATUS_INVALID_PARAM;
301     }
302
303     CATransportType_t type = endpoint->transportType;
304
305     int index = CAGetAdapterIndex(type);
306
307     if (index == -1)
308     {
309         OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
310         return CA_STATUS_INVALID_PARAM;
311     }
312
313     uint32_t sentDataLen = 0;
314     if (g_adapterHandler[index].sendData != NULL)
315     {
316         sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
317     }
318
319     if (sentDataLen == length)
320     {
321         res = CA_STATUS_OK;
322     }
323
324     OIC_LOG(DEBUG, TAG, "OUT");
325     return res;
326 }
327
328 CAResult_t CASendMulticastData(const void *data, uint32_t length)
329 {
330     OIC_LOG(DEBUG, TAG, "IN");
331
332     CAResult_t res = CA_STATUS_FAILED;
333     u_arraylist_t *list = CAGetSelectedNetworkList();
334
335     if (!list)
336     {
337         OIC_LOG(DEBUG, TAG, "No selected network");
338         return res;
339     }
340
341     for (uint8_t i = 0; i < u_arraylist_length(list); i++)
342     {
343         void* ptrType = u_arraylist_get(list, i);
344         if (NULL == ptrType)
345         {
346             continue;
347         }
348
349         CATransportType_t connType = *(CATransportType_t *) ptrType;
350
351         int index = CAGetAdapterIndex(connType);
352
353         if (index == -1)
354         {
355             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
356             continue;
357         }
358
359         uint32_t sentDataLen = 0;
360         if (g_adapterHandler[index].sendDataToAll != NULL)
361         {
362             sentDataLen = g_adapterHandler[index].sendDataToAll(data, length);
363         }
364
365         if (sentDataLen == length)
366         {
367             res = CA_STATUS_OK;
368         }
369     }
370     OIC_LOG(DEBUG, TAG, "OUT");
371     return res;
372 }
373
374 CAResult_t CAStartListeningServerAdapters()
375 {
376     OIC_LOG(DEBUG, TAG, "IN");
377
378     u_arraylist_t *list = CAGetSelectedNetworkList();
379
380     if (!list)
381     {
382         OIC_LOG(DEBUG, TAG, "No selected network");
383         return CA_STATUS_FAILED;
384     }
385
386     for (uint8_t i = 0; i < u_arraylist_length(list); i++)
387     {
388         void* ptrType = u_arraylist_get(list, i);
389         if (NULL == ptrType)
390         {
391             OIC_LOG(ERROR, TAG, "Invalid conn type");
392             continue;
393         }
394
395         CATransportType_t connType = *(CATransportType_t *) ptrType;
396
397         int index = CAGetAdapterIndex(connType);
398
399         if (index == -1)
400         {
401             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
402             continue;
403         }
404
405         if (g_adapterHandler[index].startListenServer != NULL)
406         {
407             g_adapterHandler[index].startListenServer();
408         }
409     }
410     OIC_LOG(DEBUG, TAG, "OUT");
411     return CA_STATUS_OK;
412 }
413
414 CAResult_t CAStartDiscoveryServerAdapters()
415 {
416     OIC_LOG(DEBUG, TAG, "IN");
417
418     u_arraylist_t *list = CAGetSelectedNetworkList();
419
420     if (!list)
421     {
422         OIC_LOG(DEBUG, TAG, "No selected network");
423         return CA_STATUS_FAILED;
424     }
425
426     for (uint8_t i = 0; i < u_arraylist_length(list); i++)
427     {
428         void* ptrType = u_arraylist_get(list, i);
429         if (NULL == ptrType)
430         {
431             continue;
432         }
433
434         CATransportType_t connType = *(CATransportType_t *) ptrType;
435
436         int index = CAGetAdapterIndex(connType);
437
438         if (index == -1)
439         {
440             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
441             continue;
442         }
443
444         if (g_adapterHandler[index].startDiscoveryServer != NULL)
445         {
446             g_adapterHandler[index].startDiscoveryServer();
447         }
448     }
449     OIC_LOG(DEBUG, TAG, "OUT");
450     return CA_STATUS_OK;
451 }
452
453 void CATerminateAdapters()
454 {
455     OIC_LOG(DEBUG, TAG, "IN");
456
457     uint8_t index;
458
459     for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
460     {
461         if (g_adapterHandler[index].stopAdapter != NULL)
462         {
463             g_adapterHandler[index].stopAdapter();
464         }
465         if (g_adapterHandler[index].terminate != NULL)
466         {
467             g_adapterHandler[index].terminate();
468         }
469     }
470
471     OIC_LOG(DEBUG, TAG, "OUT");
472 }
473
474 CAResult_t CAReadData()
475 {
476     OIC_LOG(DEBUG, TAG, "IN");
477     u_arraylist_t *list = CAGetSelectedNetworkList();
478
479     if (!list)
480     {
481         return CA_STATUS_FAILED;
482     }
483
484     for (uint8_t i = 0; i < u_arraylist_length(list); i++)
485     {
486         void *ptrType = u_arraylist_get(list, i);
487         if (NULL == ptrType)
488         {
489             OIC_LOG(ERROR, TAG, "get list fail");
490             return CA_STATUS_FAILED;
491         }
492
493         CATransportType_t connType = *(CATransportType_t *) ptrType;
494
495         int index = CAGetAdapterIndex(connType);
496
497         if (-1 == index)
498         {
499             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
500             continue;
501         }
502
503         if (g_adapterHandler[index].readData != NULL)
504         {
505             g_adapterHandler[index].readData();
506         }
507     }
508
509     OIC_LOG(DEBUG, TAG, "OUT");
510     return CA_STATUS_OK;
511 }
512