Implementation of connectivity abstraction feature Release v0.3
[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 "cawifiadapter_singlethread.h"
29 #include "caethernetadapter_singlethread.h"
30 #include "caedradapter_singlethread.h"
31 #include "caleadapter_singlethread.h"
32
33 #include "canetworkconfigurator.h"
34 #include "oic_malloc.h"
35 #include "logger.h"
36
37 #define TAG "CAIFCNT_ST"
38
39 #define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "Out of memory"); goto memory_error_exit;} }
40
41 #define CA_CONNECTIVITY_TYPE_NUM   4
42
43 static CAConnectivityHandler_t gAdapterHandler[CA_CONNECTIVITY_TYPE_NUM];
44
45 static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL;
46
47 static CANetworkChangeCallback gNetworkChangeCallback = NULL;
48
49 static int8_t CAGetAdapterIndex(CAConnectivityType_t cType)
50 {
51     //OIC_LOG(DEBUG, TAG, "IN");
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     //OIC_LOG(DEBUG, TAG, "OUT");
64     return -1;
65 }
66
67 static void CARegisterCallback(CAConnectivityHandler_t handler, CAConnectivityType_t cType)
68 {
69     OIC_LOG(DEBUG, TAG, "IN");
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", cType);
83     OIC_LOG(DEBUG, TAG, "OUT");
84 }
85
86 static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
87 {
88     OIC_LOG(DEBUG, TAG, "IN");
89
90     // Call the callback.
91     if (gNetworkPacketReceivedCallback != NULL)
92     {
93         gNetworkPacketReceivedCallback(endpoint, data, dataLen);
94     }
95     OIC_LOG(DEBUG, TAG, "OUT");
96 }
97
98 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
99 {
100     OIC_LOG(DEBUG, TAG, "IN");
101
102     // Call the callback.
103     if (gNetworkChangeCallback != NULL)
104     {
105         gNetworkChangeCallback(info, status);
106     }
107     OIC_LOG(DEBUG, TAG, "OUT");
108 }
109
110 void CAInitializeAdapters()
111 {
112     OIC_LOG(DEBUG, TAG, "IN");
113
114     memset(gAdapterHandler, 0, sizeof(CAConnectivityHandler_t) * CA_CONNECTIVITY_TYPE_NUM);
115
116
117     // Initialize adapters and register callback.
118 #ifdef ETHERNET_ADAPTER
119     CAInitializeEthernet(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
120 #endif /* ETHERNET_ADAPTER */
121
122 #ifdef WIFI_ADAPTER
123     CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
124 #endif /* WIFI_ADAPTER */
125
126 #ifdef EDR_ADAPTER
127     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
128 #endif /* EDR_ADAPTER */
129
130 #ifdef LE_ADAPTER
131     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback);
132 #endif /* LE_ADAPTER */
133     OIC_LOG(DEBUG, TAG, "OUT");
134
135 }
136
137 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
138 {
139     OIC_LOG(DEBUG, TAG, "IN");
140
141     gNetworkPacketReceivedCallback = callback;
142     OIC_LOG(DEBUG, TAG, "OUT");
143 }
144
145 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
146 {
147     OIC_LOG(DEBUG, TAG, "IN");
148
149     gNetworkChangeCallback = callback;
150     OIC_LOG(DEBUG, TAG, "OUT");
151 }
152
153 void CAStartAdapter(CAConnectivityType_t cType)
154 {
155     OIC_LOG_V(DEBUG, TAG, "cType[%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     OIC_LOG(DEBUG, TAG, "OUT");
172 }
173
174 void CAStopAdapter(CAConnectivityType_t cType)
175 {
176     OIC_LOG_V(DEBUG, TAG, "cType[%d]", cType);
177
178     int8_t index = -1;
179
180     index = CAGetAdapterIndex(cType);
181
182     if (index == -1)
183     {
184         OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
185         return;
186     }
187
188     if (gAdapterHandler[index].stopAdapter != NULL)
189     {
190         gAdapterHandler[index].stopAdapter();
191     }
192     OIC_LOG(DEBUG, TAG, "OUT");
193 }
194
195 CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size)
196 {
197     OIC_LOG(DEBUG, TAG, "IN");
198     CAResult_t res = CA_STATUS_FAILED;
199     int8_t index = 0;
200     int8_t i = 0;
201
202     CALocalConnectivity_t *resInfo = NULL;
203     uint32_t resSize = 0;
204
205     CALocalConnectivity_t *tempInfo[CA_CONNECTIVITY_TYPE_NUM];
206     uint32_t tempSize[CA_CONNECTIVITY_TYPE_NUM];
207
208     memset(tempInfo, 0, sizeof(CALocalConnectivity_t *) * CA_CONNECTIVITY_TYPE_NUM);
209     memset(tempSize, 0, sizeof(int8_t) * CA_CONNECTIVITY_TYPE_NUM);
210
211     // #1. get information each adapter
212     for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
213     {
214         if (gAdapterHandler[index].GetnetInfo != NULL)
215         {
216             res = gAdapterHandler[index].GetnetInfo(&tempInfo[index], &tempSize[index]);
217
218             OIC_LOG_V (DEBUG, TAG, "%d adapter network info size is %d", index, tempSize[index]);
219         }
220     }
221
222     resSize = 0;
223     for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
224     {
225         // check information
226         if (tempInfo[index] == NULL || tempSize[index] <= 0)
227         {
228             continue;
229         }
230
231         // #2. total size
232         resSize += tempSize[index];
233     }
234
235     OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize);
236
237     if (resSize <= 0)
238     {
239         return res;
240     }
241
242     // #3. add data into result
243     // memory allocation
244     resInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * resSize);
245     MEMORY_ALLOCK_CHECK(resInfo);
246     memset(resInfo, 0, sizeof(CALocalConnectivity_t) * resSize);
247
248     i = 0;
249     for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
250     {
251         // check information
252         if (tempInfo[index] == NULL || tempSize[index] <= 0)
253         {
254             continue;
255         }
256
257         memcpy(resInfo + i, tempInfo[index], sizeof(CALocalConnectivity_t) * tempSize[index]);
258
259         i += tempSize[index];
260
261         // free adapter data
262         OICFree(tempInfo[index]);
263     }
264
265     // #5. save data
266     *info = resInfo;
267     *size = resSize;
268
269     OIC_LOG_V(DEBUG, TAG, "OUT");
270
271     return res;
272
273     // memory error label.
274 memory_error_exit:
275
276     return CA_MEMORY_ALLOC_FAILED;
277 }
278
279 CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t length)
280 {
281     OIC_LOG(DEBUG, TAG, "IN");
282
283     int8_t index = -1;
284     CAResult_t res = CA_STATUS_FAILED;
285
286     if (endpoint == NULL)
287     {
288         OIC_LOG_V(DEBUG, TAG, "RemoteEndpoint is NULL");
289         return CA_STATUS_INVALID_PARAM;
290     }
291
292     CAConnectivityType_t type = endpoint->connectivityType;
293
294     index = CAGetAdapterIndex(type);
295
296     if (index == -1)
297     {
298         OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
299         return CA_STATUS_INVALID_PARAM;
300     }
301
302     if (gAdapterHandler[index].sendData != NULL)
303     {
304         res = gAdapterHandler[index].sendData(endpoint, data, length);
305     }
306     OIC_LOG(DEBUG, TAG, "OUT");
307     return res;
308 }
309
310 CAResult_t CASendMulticastData(void *data, uint32_t length)
311 {
312     OIC_LOG(DEBUG, TAG, "IN");
313
314     uint8_t i, type;
315     int8_t index = -1;
316     CAResult_t res = CA_STATUS_FAILED;
317     u_arraylist_t *list = CAGetSelectedNetworkList();
318
319     if (!list)
320     {
321         OIC_LOG(DEBUG, TAG, "No selected network");
322         return CA_STATUS_FAILED;
323     }
324
325     for (i = 0; i < u_arraylist_length(list); i++)
326     {
327         type = *(uint8_t *) u_arraylist_get(list, i);
328
329         index = CAGetAdapterIndex(type);
330
331         if (index == -1)
332         {
333             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
334             continue;
335         }
336
337         if (gAdapterHandler[index].sendDataToAll != NULL)
338         {
339             res = gAdapterHandler[index].sendDataToAll(data, length);
340         }
341     }
342     OIC_LOG(DEBUG, TAG, "OUT");
343     return res;
344 }
345
346 CAResult_t CAStartListeningServerAdapters()
347 {
348     OIC_LOG(DEBUG, TAG, "IN");
349
350     uint8_t i, type;
351     int8_t index = -1;
352     u_arraylist_t *list = CAGetSelectedNetworkList();
353
354     if (!list)
355     {
356         OIC_LOG(DEBUG, TAG, "No selected network");
357         return CA_STATUS_FAILED;
358     }
359
360     for (i = 0; i < u_arraylist_length(list); i++)
361     {
362         type = *(uint8_t *) u_arraylist_get(list, i);
363
364         index = CAGetAdapterIndex(type);
365
366         if (index == -1)
367         {
368             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
369             continue;
370         }
371
372         if (gAdapterHandler[index].startListenServer != NULL)
373         {
374             gAdapterHandler[index].startListenServer();
375         }
376     }
377     OIC_LOG(DEBUG, TAG, "OUT");
378     return CA_STATUS_OK;
379 }
380
381 CAResult_t CAStartDiscoveryServerAdapters()
382 {
383     OIC_LOG(DEBUG, TAG, "IN");
384
385     uint8_t i, type;
386     int8_t index = -1;
387     u_arraylist_t *list = CAGetSelectedNetworkList();
388
389     if (!list)
390     {
391         OIC_LOG(DEBUG, TAG, "No selected network");
392         return CA_STATUS_FAILED;
393     }
394
395     for (i = 0; i < u_arraylist_length(list); i++)
396     {
397         type = *(uint8_t *) u_arraylist_get(list, i);
398
399         index = CAGetAdapterIndex(type);
400
401         if (index == -1)
402         {
403             OIC_LOG_V(DEBUG, TAG, "unknown connectivity type!");
404             continue;
405         }
406
407         if (gAdapterHandler[index].startDiscoverServer != NULL)
408         {
409             gAdapterHandler[index].startDiscoverServer();
410         }
411     }
412     OIC_LOG(DEBUG, TAG, "OUT");
413     return CA_STATUS_OK;
414 }
415
416 void CATerminateAdapters()
417 {
418     OIC_LOG(DEBUG, TAG, "IN");
419
420     uint8_t index;
421
422     for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++)
423     {
424         if (gAdapterHandler[index].terminate != NULL)
425         {
426             gAdapterHandler[index].terminate();
427         }
428     }
429     OIC_LOG(DEBUG, TAG, "OUT");
430 }
431
432 CAResult_t CAReadData()
433 {
434     //OIC_LOG(DEBUG, TAG, "IN");
435
436     uint8_t i, type;
437     int8_t index = -1;
438
439     u_arraylist_t *list = CAGetSelectedNetworkList();
440
441     if (!list)
442     {
443         OIC_LOG(DEBUG, TAG, "No selected network");
444         return CA_STATUS_FAILED;
445     }
446
447     for (i = 0; i < u_arraylist_length(list); i++)
448     {
449         type = *(uint8_t *) u_arraylist_get(list, i);
450
451         index = CAGetAdapterIndex(type);
452
453         if (-1 == index)
454         {
455             OIC_LOG_V(DEBUG, TAG, "unknown connectivity type!");
456             continue;
457         }
458
459         if (gAdapterHandler[index].readData != NULL)
460         {
461             gAdapterHandler[index].readData();
462         }
463     }
464
465     //OIC_LOG(DEBUG, TAG, "OUT");
466     return CA_STATUS_OK;
467 }