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