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