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