[CONPRO-1471]Adding logic for caching MTU in tizen LE Server
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / caleutil.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 "caleutil.h"
22
23 #include<stdio.h>
24 #include<stdlib.h>
25 #include<string.h>
26 #include<arpa/inet.h>
27 #include<sys/types.h>
28 #include<sys/socket.h>
29 #include<netinet/in.h>
30
31
32 #include "caadapterutils.h"
33 #include "oic_string.h"
34 #include "oic_malloc.h"
35
36 /**
37  * Logging tag for module name
38  */
39 #define TAG "OIC_CA_LE_UTIL"
40
41 /**
42  * Number of services connected.
43  */
44 static int32_t g_numberOfServiceConnected = 0;
45
46 /*void CAIncrementRegisteredServiceCount()
47 {
48     g_numberOfServiceConnected++;
49 }*/
50
51 CAResult_t CAAddLEDataToList(LEDataList **dataList, const void *data, uint32_t dataLength)
52 {
53     OIC_LOG(DEBUG, TAG, "IN");
54
55     VERIFY_NON_NULL(dataList, TAG, "Data list is null");
56     VERIFY_NON_NULL(data, TAG, "data is null");
57
58     if (0 == dataLength)
59     {
60         OIC_LOG(ERROR, TAG, "Invalid input: data length is zero!");
61         return CA_STATUS_INVALID_PARAM;
62     }
63
64     LEDataList *pending_data = (LEDataList *) OICMalloc(sizeof(LEDataList));
65     if (NULL == pending_data)
66     {
67         OIC_LOG(ERROR, TAG, "OICMalloc failed (data list)!");
68         return CA_MEMORY_ALLOC_FAILED;
69     }
70
71     pending_data->data = (LEData *) OICMalloc(sizeof(LEData));
72     if (NULL == pending_data->data)
73     {
74         OIC_LOG(ERROR, TAG, "OICMalloc failed (data node)!");
75         OICFree(pending_data);
76         return CA_MEMORY_ALLOC_FAILED;
77     }
78
79     pending_data->next = NULL;
80     pending_data->data->data = (void *) OICMalloc(dataLength); //data
81     if (NULL == pending_data->data->data)
82     {
83         OIC_LOG(ERROR, TAG, "OICMalloc failed (data)!");
84         OICFree(pending_data->data);
85         OICFree(pending_data);
86         return CA_MEMORY_ALLOC_FAILED;
87     }
88
89     memcpy(pending_data->data->data, data, dataLength);
90     pending_data->data->dataLength = dataLength;
91
92     if (NULL == *dataList)
93     {
94         *dataList = pending_data;
95     }
96     else
97     {
98         LEDataList *curNode = *dataList;
99         while (curNode->next != NULL)
100         {
101             curNode = curNode->next;
102         }
103         curNode->next = pending_data;
104     }
105
106     OIC_LOG(DEBUG, TAG, "OUT");
107     return CA_STATUS_OK;
108 }
109
110
111 void CARemoveLEDataFromList(LEDataList **dataList)
112 {
113     OIC_LOG(DEBUG, TAG, "IN");
114
115     VERIFY_NON_NULL_VOID(dataList, TAG, "Data list is null");
116
117     if (*dataList)
118     {
119         LEDataList *curNode = *dataList;
120         *dataList = (*dataList)->next;
121
122         //Delete the first node
123         CADestroyLEData(curNode->data);
124         OICFree(curNode);
125     }
126
127     OIC_LOG(DEBUG, TAG, "OUT");
128 }
129
130 void CADestroyLEDataList(LEDataList **dataList)
131 {
132     OIC_LOG(DEBUG, TAG, "IN");
133
134     VERIFY_NON_NULL_VOID(dataList, TAG, "Data list is null");
135
136     while (*dataList)
137     {
138         LEDataList *curNode = *dataList;
139         *dataList = (*dataList)->next;
140
141         CADestroyLEData(curNode->data);
142         OICFree(curNode);
143     }
144
145     *dataList = NULL;
146
147     OIC_LOG(DEBUG, TAG, "OUT");
148 }
149
150 void CADestroyLEData(LEData *data)
151 {
152     if (data)
153     {
154         OICFree(data->data);
155         OICFree(data);
156     }
157 }
158
159 CAResult_t CAAddLEServerInfoToList(LEServerInfoList **serverList,
160                                    LEServerInfo *leServerInfo)
161 {
162
163     OIC_LOG(DEBUG, TAG, "IN");
164
165     VERIFY_NON_NULL(serverList, TAG, "serverList");
166     VERIFY_NON_NULL(leServerInfo, TAG, "leServerInfo");
167
168     LEServerInfoList *node = (LEServerInfoList *) OICCalloc(1, sizeof(LEServerInfoList));
169     if (NULL == node)
170     {
171         OIC_LOG(ERROR, TAG, "Calloc failed!");
172         return CA_STATUS_FAILED;
173     }
174
175     node->serverInfo = leServerInfo;
176     node->next = NULL;
177
178     if (*serverList == NULL)   // Empty list
179     {
180         *serverList = node;
181     }
182     else     // Add at front end
183     {
184         node->next = *serverList;
185         *serverList = node;
186     }
187
188     OIC_LOG_V(DEBUG, TAG, "Device [%s] added to list",
189               leServerInfo->remoteAddress);
190
191     OIC_LOG(DEBUG, TAG, "OUT");
192
193     return CA_STATUS_OK;
194 }
195
196 void CARemoveLEServerInfoFromList(LEServerInfoList **serverList,
197                                         const char *remoteAddress)
198 {
199     OIC_LOG(DEBUG, TAG, "IN");
200     VERIFY_NON_NULL_VOID(serverList, TAG, "serverList");
201     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remoteAddress");
202
203     LEServerInfoList *temp = *serverList;
204     LEServerInfoList *prev = NULL;
205     while (temp)
206     {
207         if (!strcasecmp(temp->serverInfo->remoteAddress, remoteAddress))
208         {
209             if (NULL == prev)
210             {
211                 *serverList = temp->next;
212             }
213             else
214             {
215                 prev->next = temp->next;
216             }
217             
218             CAFreeLEServerInfo(temp->serverInfo);
219             OICFree(temp);
220             OIC_LOG_V(DEBUG, TAG, "Device [%s] removed from list", remoteAddress);
221             break;
222         }
223         prev = temp;
224         temp = temp->next;
225     }
226
227     OIC_LOG(DEBUG, TAG, "OUT");
228 }
229
230 CAResult_t CAGetLEServerInfo(LEServerInfoList *serverList, const char *leAddress,
231                              LEServerInfo **leServerInfo)
232 {
233
234     OIC_LOG(DEBUG, TAG, "IN");
235
236     VERIFY_NON_NULL(leServerInfo, TAG, "leClientInfo");
237     VERIFY_NON_NULL(leAddress, TAG, "leAddress");
238
239     if (NULL == serverList)
240     {
241         OIC_LOG(DEBUG, TAG, "Server list is empty");
242         return CA_STATUS_FAILED;
243     }
244
245     LEServerInfoList *cur = serverList;
246     *leServerInfo = NULL;
247     while (cur != NULL)
248     {
249         if (!strcasecmp(cur->serverInfo->remoteAddress , leAddress))
250         {
251             *leServerInfo = cur->serverInfo;
252             OIC_LOG(DEBUG, TAG, "OUT");
253             return CA_STATUS_OK;
254         }
255
256         cur = cur->next;
257     }
258
259     OIC_LOG(DEBUG, TAG, " OUT");
260     return CA_STATUS_FAILED;
261 }
262
263
264
265 void CAFreeLEServerList(LEServerInfoList *serverList)
266 {
267     OIC_LOG(DEBUG, TAG, "IN");
268     while (serverList)
269     {
270         LEServerInfoList *temp = serverList;
271         serverList = serverList->next;
272         CAFreeLEServerInfo(temp->serverInfo);
273         OICFree(temp);
274     }
275     OIC_LOG(DEBUG, TAG, "OUT");
276 }
277
278 void CAFreeLEServerInfo(LEServerInfo *leServerInfo)
279 {
280     OIC_LOG(DEBUG, TAG, "IN");
281     if (leServerInfo)
282     {
283         if (leServerInfo->clientHandle)
284         {
285             bt_gatt_client_destroy(leServerInfo->clientHandle);
286         }
287
288         if (leServerInfo->pendingDataList)
289         {
290             CADestroyLEDataList(&(leServerInfo->pendingDataList));
291         }
292
293         if (leServerInfo->status > LE_STATUS_CONNECTED)
294         {    int32_t ret = bt_gatt_disconnect(leServerInfo->remoteAddress);
295
296             if (BT_ERROR_NONE != ret)
297             {
298                 OIC_LOG_V(ERROR, TAG,
299                           "bt_gatt_disconnect Failed with ret value [%d]",
300                           ret);
301                 return;
302             }
303         }
304         OICFree(leServerInfo->remoteAddress);
305         OICFree(leServerInfo);
306     }
307     OIC_LOG(DEBUG, TAG, "OUT");
308 }
309
310 CAResult_t CAAddLEClientInfoToList(LEClientInfoList **clientList,
311                                    char *clientAddress)
312 {
313     OIC_LOG(DEBUG, TAG, "IN");
314     VERIFY_NON_NULL(clientList, TAG, "clientList");
315     VERIFY_NON_NULL(clientAddress, TAG, "clientAddress");
316
317     LEClientInfoList *node = (LEClientInfoList *) OICCalloc(1, sizeof(LEClientInfoList));
318     if (NULL == node)
319     {
320         OIC_LOG(ERROR, TAG, "Malloc failed!");
321         return CA_STATUS_FAILED;
322     }
323
324     node->remoteAddress= clientAddress;
325     node->mtuSize = 0;
326     node->next = NULL;
327
328     if (*clientList == NULL)   // Empty list
329     {
330         *clientList = node;
331     }
332     else     // Add at front end
333     {
334         node->next = *clientList;
335         *clientList = node;
336     }
337
338     OIC_LOG_V(DEBUG, TAG, "Device [%s] added to list", clientAddress);
339     OIC_LOG(DEBUG, TAG, "OUT");
340     return CA_STATUS_OK;
341 }
342
343 uint16_t CAClientInfoGetMTUSize(LEClientInfoList *clientList,
344                                         const char *clientAddress)
345 {
346     OIC_LOG(DEBUG, TAG, "IN");
347
348     LEClientInfoList *temp = clientList;
349     while (temp)
350     {
351         if (!strcasecmp(temp->remoteAddress, clientAddress))
352         {
353             return temp->mtuSize;
354         }
355         temp = temp->next;
356     }
357
358     OIC_LOG(DEBUG, TAG, "OUT");
359     return 0;
360 }
361
362 CAResult_t CAClientInfoUpdateMTUSize(LEClientInfoList *clientList,
363                                         const char *clientAddress,uint16_t mtu_size)
364 {
365     OIC_LOG(DEBUG, TAG, "IN");
366
367     LEClientInfoList *temp = clientList;
368     while (temp)
369     {
370         if (!strcasecmp(temp->remoteAddress, clientAddress))
371         {
372             temp->mtuSize = mtu_size;
373             return CA_STATUS_OK;
374         }
375         temp = temp->next;
376     }
377
378     OIC_LOG(DEBUG, TAG, "OUT");
379     return CA_STATUS_FAILED;
380 }
381
382 CAResult_t CAIsLEClientInfoInList(LEClientInfoList *clientList,
383                                         const char *clientAddress)
384 {
385     OIC_LOG(DEBUG, TAG, "IN");
386
387     LEClientInfoList *temp = clientList;
388     while (temp)
389     {
390         if (!strcasecmp(temp->remoteAddress, clientAddress))
391         {
392             return CA_STATUS_OK;
393         }
394         temp = temp->next;
395     }
396
397     OIC_LOG(DEBUG, TAG, "OUT");
398     return CA_STATUS_FAILED;
399 }
400
401 void CARemoveLEClientInfoFromList(LEClientInfoList **clientList,
402                                   const char *clientAddress)
403 {
404     OIC_LOG(DEBUG, TAG, "IN");
405     VERIFY_NON_NULL_VOID(clientAddress, TAG, "clientAddress");
406
407     LEClientInfoList *temp = *clientList;
408     LEClientInfoList *prev = NULL;
409     while (temp)
410     {
411         if (!strcasecmp(temp->remoteAddress, clientAddress))
412         {
413             if (NULL == prev)
414             {
415                 *clientList = temp->next;
416             }
417             else
418             {
419                 prev->next = temp->next;
420             }
421             OICFree(temp->remoteAddress);
422             OICFree(temp);
423             OIC_LOG_V(DEBUG, TAG, "Device [%s] removed from list", clientAddress);
424             break;
425         }
426         prev = temp;
427         temp = temp->next;
428     }
429
430     OIC_LOG(DEBUG, TAG, "OUT");
431 }
432
433 void CADisconnectAllClient(LEClientInfoList *clientList)
434 {
435     OIC_LOG(DEBUG, TAG, "IN");
436     while (clientList)
437     {
438         LEClientInfoList *temp = clientList;
439         clientList = clientList->next;
440         if (temp->remoteAddress)
441         {
442             int32_t ret = bt_gatt_disconnect(temp->remoteAddress);
443
444             if (BT_ERROR_NONE != ret)
445             {
446                 OIC_LOG_V(ERROR, TAG,
447                           "bt_gatt_disconnect Failed with ret value [%d]",
448                           ret);
449                 return;
450             }
451             OICFree(temp->remoteAddress);
452         }
453         OICFree(temp);
454     }
455     OIC_LOG(DEBUG, TAG, "OUT");
456 }
457
458 const char *CALEGetErrorMsg(bt_error_e err)
459 {
460     const char *errStr = NULL;
461
462     switch (err)
463     {
464         case BT_ERROR_NONE:
465             errStr = "BT_ERROR_NONE";
466             break;
467         case BT_ERROR_CANCELLED:
468             errStr = "BT_ERROR_CANCELLED";
469             break;
470         case BT_ERROR_INVALID_PARAMETER:
471             errStr = "BT_ERROR_INVALID_PARAMETER";
472             break;
473         case BT_ERROR_OUT_OF_MEMORY:
474             errStr = "BT_ERROR_OUT_OF_MEMORY";
475             break;
476         case BT_ERROR_RESOURCE_BUSY:
477             errStr = "BT_ERROR_RESOURCE_BUSY";
478             break;
479         case BT_ERROR_TIMED_OUT:
480             errStr = "BT_ERROR_TIMED_OUT";
481             break;
482         case BT_ERROR_NOW_IN_PROGRESS:
483             errStr = "BT_ERROR_NOW_IN_PROGRESS";
484             break;
485         case BT_ERROR_NOT_INITIALIZED:
486             errStr = "BT_ERROR_NOT_INITIALIZED";
487             break;
488         case BT_ERROR_NOT_ENABLED:
489             errStr = "BT_ERROR_NOT_ENABLED";
490             break;
491         case BT_ERROR_ALREADY_DONE:
492             errStr = "BT_ERROR_ALREADY_DONE";
493             break;
494         case BT_ERROR_OPERATION_FAILED:
495             errStr = "BT_ERROR_OPERATION_FAILED";
496             break;
497         case BT_ERROR_NOT_IN_PROGRESS:
498             errStr = "BT_ERROR_NOT_IN_PROGRESS";
499             break;
500         case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
501             errStr = "BT_ERROR_REMOTE_DEVICE_NOT_BONDED";
502             break;
503         case BT_ERROR_AUTH_REJECTED:
504             errStr = "BT_ERROR_AUTH_REJECTED";
505             break;
506         case BT_ERROR_AUTH_FAILED:
507             errStr = "BT_ERROR_AUTH_FAILED";
508             break;
509         case BT_ERROR_REMOTE_DEVICE_NOT_FOUND:
510             errStr = "BT_ERROR_REMOTE_DEVICE_NOT_FOUND";
511             break;
512         case BT_ERROR_SERVICE_SEARCH_FAILED:
513             errStr = "BT_ERROR_SERVICE_SEARCH_FAILED";
514             break;
515         case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED:
516             errStr = "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED";
517             break;
518         case BT_ERROR_PERMISSION_DENIED:
519             errStr = "BT_ERROR_PERMISSION_DENIED";
520             break;
521         case BT_ERROR_SERVICE_NOT_FOUND:
522             errStr = "BT_ERROR_SERVICE_NOT_FOUND";
523             break;
524         case BT_ERROR_NOT_SUPPORTED:
525             errStr = "BT_ERROR_NOT_SUPPORTED";
526             break;
527         case BT_ERROR_QUOTA_EXCEEDED:
528             errStr = "BT_ERROR_QUOTA_EXCEEDED";
529             break;
530         case BT_ERROR_NO_DATA:
531             errStr = "BT_ERROR_NO_DATA";
532             break;
533         case BT_ERROR_AGAIN:
534             errStr = "BT_ERROR_AGAIN";
535             break;
536         default:
537             errStr = "NOT Defined";
538             break;
539     }
540
541     return errStr;
542 }
543
544