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