3209d8b3f5464797e4cb3aa5722ffe306f1778c9
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / adapter_util / caadapterutils.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 "caadapterutils.h"
22
23 #include <string.h>
24 #include <ctype.h>
25 #include "oic_string.h"
26 #include "oic_malloc.h"
27
28 #ifdef __ANDROID__
29 #include <jni.h>
30 #endif
31
32 #define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
33
34 #ifdef __ANDROID__
35 /**
36  * @var g_jvm
37  * @brief pointer to store JavaVM
38  */
39 static JavaVM *g_jvm = NULL;
40
41 /**
42  * @var gContext
43  * @brief pointer to store context for android callback interface
44  */
45 static jobject g_Context = NULL;
46 #endif
47
48 void CALogPDUData(coap_pdu_t *pdu)
49 {
50     VERIFY_NON_NULL_VOID(pdu, CA_ADAPTER_UTILS_TAG, "pdu");
51     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - payload : %s", pdu->data);
52
53     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - type : %d", pdu->hdr->type);
54
55     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - code : %d", pdu->hdr->code);
56
57     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - id : %d", pdu->hdr->id);
58
59     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
60 }
61
62 CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CATransportType_t type, const char *address)
63 {
64     CALocalConnectivity_t *info = (CALocalConnectivity_t *)
65                                   OICCalloc(1, sizeof(CALocalConnectivity_t));
66     if (NULL == info)
67     {
68         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
69         return NULL;
70     }
71
72     info->type = type;
73     if (address && strlen(address))
74     {
75         if (CA_EDR == type)
76         {
77             OICStrcpy(info->addressInfo.BT.btMacAddress, sizeof(info->addressInfo.BT.btMacAddress),
78                     address);
79         }
80         else if (CA_LE == type)
81         {
82             OICStrcpy(info->addressInfo.LE.leMacAddress, sizeof(info->addressInfo.LE.leMacAddress),
83                     address);
84         }
85         else if (CA_IPV4 == type)
86         {
87             OICStrcpy(info->addressInfo.IP.ipAddress, sizeof(info->addressInfo.IP.ipAddress),
88                     address);
89         }
90         else if (CA_IPV6 == type)
91         {
92             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
93             OICFree(info);
94             return NULL;
95         }
96         else
97         {
98             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
99             OICFree(info);
100             return NULL;
101         }
102     }
103
104     return info;
105 }
106
107 CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity)
108 {
109     VERIFY_NON_NULL_RET(connectivity, CA_ADAPTER_UTILS_TAG, "connectivity is NULL", NULL);
110
111     CALocalConnectivity_t *info = (CALocalConnectivity_t *)
112                                   OICCalloc(1, sizeof(CALocalConnectivity_t));
113     if (NULL == info)
114     {
115         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
116         return NULL;
117     }
118
119     info->type = connectivity->type;
120     if (CA_EDR == info->type && strlen(connectivity->addressInfo.BT.btMacAddress))
121     {
122         OICStrcpy(info->addressInfo.BT.btMacAddress, sizeof(info->addressInfo.BT.btMacAddress),
123                 connectivity->addressInfo.BT.btMacAddress);
124     }
125     else if (CA_LE == info->type && strlen(connectivity->addressInfo.LE.leMacAddress))
126     {
127         OICStrcpy(info->addressInfo.LE.leMacAddress, sizeof(info->addressInfo.LE.leMacAddress),
128             connectivity->addressInfo.LE.leMacAddress);
129     }
130     else if ((CA_IPV4 == info->type)
131
132             && strlen(connectivity->addressInfo.IP.ipAddress))
133     {
134         OICStrcpy(info->addressInfo.IP.ipAddress, sizeof(info->addressInfo.IP.ipAddress),
135                 connectivity->addressInfo.IP.ipAddress);
136         info->addressInfo.IP.port = connectivity->addressInfo.IP.port;
137     }
138     else if (CA_IPV6 == info->type)
139     {
140         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
141         OICFree(info);
142         return NULL;
143     }
144     else
145     {
146         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
147         OICFree(info);
148         return NULL;
149     }
150
151     info->isSecured = connectivity->isSecured;
152     return info;
153 }
154
155 void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint)
156 {
157     OICFree(localEndpoint);
158 }
159
160 CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CATransportType_t type, const char *address,
161                                                   const char *resourceUri)
162 {
163     CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
164                                OICCalloc(1, sizeof(CARemoteEndpoint_t));
165     if (NULL == info)
166     {
167         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
168         return NULL;
169     }
170
171     info->transportType = type;
172     if (address && strlen(address))
173     {
174         if (CA_EDR == type)
175         {
176             OICStrcpy(info->addressInfo.BT.btMacAddress, sizeof(info->addressInfo.BT.btMacAddress),
177                     address);
178         }
179         else if (CA_LE == type)
180         {
181             OICStrcpy(info->addressInfo.LE.leMacAddress, sizeof(info->addressInfo.LE.leMacAddress),
182                     address);
183         }
184         else if (CA_IPV4 == type)
185         {
186             OICStrcpy(info->addressInfo.IP.ipAddress, sizeof(info->addressInfo.IP.ipAddress),
187                     address);
188         }
189         else if (CA_IPV6 == type)
190         {
191             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
192             OICFree(info);
193             return NULL;
194         }
195         else
196         {
197             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
198             OICFree(info);
199             return NULL;
200         }
201     }
202
203     if (resourceUri && strlen(resourceUri))
204     {
205         info->resourceUri = OICStrdup(resourceUri);
206     }
207
208     return info;
209 }
210
211 CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint)
212 {
213     VERIFY_NON_NULL_RET(remoteEndpoint, CA_ADAPTER_UTILS_TAG, "Remote endpoint is NULL", NULL);
214
215     CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
216                                OICCalloc(1, sizeof(CARemoteEndpoint_t));
217     if (NULL == info)
218     {
219         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
220         return NULL;
221     }
222
223     info->transportType = remoteEndpoint->transportType;
224     if (CA_EDR == info->transportType && ('\0' != remoteEndpoint->addressInfo.BT.btMacAddress[0]))
225     {
226         OICStrcpy(info->addressInfo.BT.btMacAddress, sizeof(info->addressInfo.BT.btMacAddress),
227                 remoteEndpoint->addressInfo.BT.btMacAddress);
228     }
229     else if (CA_LE == info->transportType
230              && ('\0' != remoteEndpoint->addressInfo.LE.leMacAddress[0]))
231     {
232         OICStrcpy(info->addressInfo.LE.leMacAddress, sizeof(info->addressInfo.LE.leMacAddress),
233                 remoteEndpoint->addressInfo.LE.leMacAddress);
234     }
235     else if ((CA_IPV4 == info->transportType)
236             && ('\0' != remoteEndpoint->addressInfo.IP.ipAddress[0]))
237     {
238         OICStrcpy(info->addressInfo.IP.ipAddress, sizeof(info->addressInfo.IP.ipAddress),
239                 remoteEndpoint->addressInfo.IP.ipAddress);
240         info->addressInfo.IP.port = remoteEndpoint->addressInfo.IP.port;
241     }
242     else if (CA_IPV6 == info->transportType)
243     {
244         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Currently IPV6 is not supported");
245     }
246     else
247     {
248         OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "Its not matching. May be multicast.");
249     }
250
251     //For Multicast, remote address will be null while resourceUri will have the service UUID
252
253     if (remoteEndpoint->resourceUri && strlen(remoteEndpoint->resourceUri))
254     {
255         info->resourceUri = OICStrdup(remoteEndpoint->resourceUri);
256     }
257
258     info->isSecured = remoteEndpoint->isSecured;
259     info->identity  = remoteEndpoint->identity;
260     return info;
261 }
262
263 void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint)
264 {
265     if (remoteEndpoint)
266     {
267         OICFree(remoteEndpoint->resourceUri);
268         OICFree(remoteEndpoint);
269     }
270 }
271
272 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
273                                    size_t ipAddrLen, uint16_t *port)
274 {
275     if (!ipAddr || !isdigit(ipAddrStr[0]) || !port)
276     {
277         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
278         return CA_STATUS_INVALID_PARAM;
279     }
280
281     size_t index = 0;
282     uint8_t dotCount = 0;
283
284     ipAddr[index] = 0;
285     *port = 0;
286     while (*ipAddrStr)
287     {
288         if (isdigit(*ipAddrStr))
289         {
290             if(index >= ipAddrLen)
291             {
292                 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
293                 return CA_STATUS_INVALID_PARAM;
294             }
295             ipAddr[index] *= 10;
296             ipAddr[index] += *ipAddrStr - '0';
297         }
298         else if (*ipAddrStr == '.')
299         {
300             index++;
301             dotCount++;
302             ipAddr[index] = 0;
303         }
304         else
305         {
306             break;
307         }
308         ipAddrStr++;
309     }
310
311     if (*ipAddrStr == ':')
312     {
313         ipAddrStr++;
314         while (*ipAddrStr)
315         {
316             if (isdigit(*ipAddrStr))
317             {
318                 *port *= 10;
319                 *port += *ipAddrStr - '0';
320             }
321             else
322             {
323                 break;
324             }
325             ipAddrStr++;
326         }
327     }
328
329     if (dotCount == 3)
330     {
331         return CA_STATUS_OK;
332     }
333     return CA_STATUS_FAILED;
334 }
335
336 bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, const char *netMask)
337 {
338     VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
339     VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
340     VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
341
342     uint8_t ipList1[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
343     uint8_t ipList2[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
344     uint8_t maskList[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
345     CAResult_t ret = CA_STATUS_OK;
346
347     /* Local Loopback Address */
348     if (0 == strncmp(ipAddress1, "127.", 4) || 0 == strncmp(ipAddress2, "127.", 4))
349     {
350         return true;
351     }
352
353     uint16_t parsedPort = 0;
354     ret = CAParseIPv4AddressInternal(ipAddress1, ipList1, sizeof(ipList1), &parsedPort);
355     if (ret != CA_STATUS_OK)
356     {
357         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "First ip address parse fail %d", ret);
358         return false;
359     }
360
361     ret = CAParseIPv4AddressInternal(ipAddress2, ipList2, sizeof(ipList2), &parsedPort);
362     if (ret != CA_STATUS_OK)
363     {
364         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Second ip address parse fail %d", ret);
365         return false;
366     }
367
368     ret = CAParseIPv4AddressInternal(netMask, maskList, sizeof(maskList), &parsedPort);
369     if (ret != CA_STATUS_OK)
370     {
371         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Net mask parse fail %d", ret);
372         return false;
373     }
374
375     return ((ipList1[0] & maskList[0]) == (ipList2[0] & maskList[0])) && ((ipList1[1] & maskList[1])
376             == (ipList2[1] & maskList[1]))
377            && ((ipList1[2] & maskList[2]) == (ipList2[2] & maskList[2]))
378            && ((ipList1[3] & maskList[3]) == (ipList2[3] & maskList[3]));
379 }
380
381
382 bool CAIsMulticastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
383                                 const char *multicastAddress, uint16_t port)
384 {
385     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
386     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
387     VERIFY_NON_NULL_RET(multicastAddress, CA_ADAPTER_UTILS_TAG, "multicastAddress is null", false);
388
389     uint32_t listLength = u_arraylist_length(serverInfoList);
390     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
391     {
392         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
393         if (!info)
394         {
395             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Info is NULL");
396             return false;
397         }
398
399         if (info->isMulticastServer && (strncmp(info->ipAddress, multicastAddress,
400                                                 strlen(multicastAddress) == 0))
401             && (info->port == port) && (strncmp(info->ifAddr, ipAddress, strlen(ipAddress)) == 0))
402         {
403             return info->isServerStarted;
404         }
405     }
406     return false;
407 }
408
409 bool CAIsUnicastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress,
410                               uint16_t port)
411 {
412     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", false);
413     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", false);
414
415     uint32_t listLength = u_arraylist_length(serverInfoList);
416     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
417     {
418         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
419         if (!info)
420         {
421             continue;
422         }
423
424         if (!info->isMulticastServer && (strncmp(info->ipAddress, ipAddress,
425                                                  strlen(ipAddress)) == 0)
426             && (info->port == port))
427         {
428             return info->isServerStarted;
429         }
430     }
431     return false;
432 }
433
434 uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddress, bool isSecured)
435 {
436     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", 0);
437     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", 0);
438
439     uint32_t listLength = u_arraylist_length(serverInfoList);
440     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
441     {
442         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
443         if (!info)
444         {
445             continue;
446         }
447         if ((strncmp(info->ipAddress, ipAddress, strlen(ipAddress)) == 0) &&
448                     (info->isSecured == isSecured))
449         {
450             return info->port;
451         }
452     }
453
454     return 0;
455 }
456
457 int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList, const char *ipAddress,
458                                   bool isSecured, bool isMulticast, CATransportType_t type)
459 {
460     VERIFY_NON_NULL_RET(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null", -1);
461     VERIFY_NON_NULL_RET(ipAddress, CA_ADAPTER_UTILS_TAG, "ipAddress is null", -1);
462
463     uint32_t listLength = u_arraylist_length(serverInfoList);
464
465     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
466     {
467         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
468         if (!info)
469         {
470             continue;
471         }
472
473         if (!CAAdapterIsSameSubnet(info->ipAddress, ipAddress, info->subNetMask))
474         {
475             continue;
476         }
477
478         if (!info->isMulticastServer && (info->isSecured == isSecured))
479         {
480             OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG,
481                       "CAGetSocketFdForServer found socket [%d]", info->socketFd);
482             return info->socketFd;
483         }
484
485     }
486
487     OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG,
488             "CAGetSocketFdForServer socket fd is not found");
489     return -1;
490 }
491
492 CAResult_t CAAddServerInfo(u_arraylist_t *serverInfoList, CAServerInfo_t *info)
493 {
494     VERIFY_NON_NULL(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
495     VERIFY_NON_NULL(info, CA_ADAPTER_UTILS_TAG, "info is null");
496
497     CAResult_t result = u_arraylist_add(serverInfoList, (void *) info);
498     if (CA_STATUS_OK != result)
499     {
500         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_add failed!");
501     }
502     return result;
503 }
504
505 void CARemoveServerInfo(u_arraylist_t *serverInfoList, int sockFd)
506 {
507     VERIFY_NON_NULL_VOID(serverInfoList, CA_ADAPTER_UTILS_TAG, "serverInfoList is null");
508
509     uint32_t listLength = u_arraylist_length(serverInfoList);
510     for (uint32_t listIndex = 0; listIndex < listLength;)
511     {
512         CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
513         if (!info)
514         {
515             listIndex++;
516             continue;
517         }
518
519         if (info->socketFd == sockFd)
520         {
521             if (u_arraylist_remove(serverInfoList, listIndex))
522             {
523                 OICFree(info);
524                 listLength--;
525             }
526             else
527             {
528                 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "u_arraylist_remove failed!");
529                 break;
530             }
531         }
532         else
533         {
534             listIndex++;
535         }
536     }
537 }
538
539 void CAClearNetInterfaceInfoList(u_arraylist_t *infoList)
540 {
541     uint32_t listLength = u_arraylist_length(infoList);
542     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
543     {
544         CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(infoList, listIndex);
545         if (!netInfo)
546         {
547             continue;
548         }
549         OICFree(netInfo);
550     }
551     u_arraylist_free(&infoList);
552 }
553
554 void CAClearServerInfoList(u_arraylist_t *serverInfoList)
555 {
556     uint32_t listLength = u_arraylist_length(serverInfoList);
557     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
558     {
559         CAServerInfo_t *serverInfo = (CAServerInfo_t *) u_arraylist_get(serverInfoList, listIndex);
560         if (!serverInfo)
561         {
562             continue;
563         }
564         OICFree(serverInfo);
565     }
566     u_arraylist_free(&serverInfoList);
567 }
568
569 #ifdef __ANDROID__
570 void CANativeJNISetContext(JNIEnv *env, jobject context)
571 {
572     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetContext");
573
574     if (!context)
575     {
576         OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "context is null");
577
578     }
579
580     g_Context = (*env)->NewGlobalRef(env, context);
581 }
582
583 void CANativeJNISetJavaVM(JavaVM *jvm)
584 {
585     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "CANativeJNISetJavaVM");
586     g_jvm = jvm;
587 }
588
589 jobject CANativeJNIGetContext()
590 {
591     return g_Context;
592 }
593
594 JavaVM *CANativeJNIGetJavaVM()
595 {
596     return g_jvm;
597 }
598 #endif
599