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