BLE implementation for Tizen Platform.
[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 #include "oic_malloc.h"
27 #include "oic_string.h"
28
29 #define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
30
31 void CALogPDUData(coap_pdu_t *pdu)
32 {
33     VERIFY_NON_NULL_VOID(pdu, CA_ADAPTER_UTILS_TAG, "pdu");
34     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - payload : %s", pdu->data);
35
36     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - type : %d", pdu->hdr->type);
37
38     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - code : %d", pdu->hdr->code);
39
40     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - id : %d", pdu->hdr->id);
41
42     OIC_LOG_V(DEBUG, CA_ADAPTER_UTILS_TAG, "PDU Maker - token : %s", pdu->hdr->token);
43 }
44
45 CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type,
46         const char *address)
47 {
48     CALocalConnectivity_t *info = (CALocalConnectivity_t *)
49                                   OICCalloc(1, sizeof(CALocalConnectivity_t));
50     if (NULL == info)
51     {
52         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
53         return NULL;
54     }
55
56     info->type = type;
57     if (address && strlen(address))
58     {
59         if (CA_EDR == type)
60         {
61             strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
62             info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
63         }
64         else if (CA_LE == type)
65         {
66             strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
67             info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
68         }
69         else if (CA_WIFI == type || CA_ETHERNET == type)
70         {
71             strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
72             info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
73         }
74         else
75         {
76             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
77             OICFree(info);
78             return NULL;
79         }
80     }
81
82     return info;
83 }
84
85 CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity)
86 {
87     VERIFY_NON_NULL_RET(connectivity, CA_ADAPTER_UTILS_TAG, "connectivity is NULL", NULL);
88
89     CALocalConnectivity_t *info = (CALocalConnectivity_t *)
90                                   OICCalloc(1, sizeof(CALocalConnectivity_t));
91     if (NULL == info)
92     {
93         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
94         return NULL;
95     }
96
97     info->type = connectivity->type;
98     if (CA_EDR == info->type && strlen(connectivity->addressInfo.BT.btMacAddress))
99     {
100         strncpy(info->addressInfo.BT.btMacAddress, connectivity->addressInfo.BT.btMacAddress,
101                 CA_MACADDR_SIZE - 1);
102         info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
103     }
104     else if (CA_LE == info->type && strlen(connectivity->addressInfo.LE.leMacAddress))
105     {
106         strncpy(info->addressInfo.LE.leMacAddress, connectivity->addressInfo.LE.leMacAddress,
107                 CA_MACADDR_SIZE - 1);
108         info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
109     }
110     else if ((CA_WIFI == info->type || CA_ETHERNET == info->type)
111              && strlen(connectivity->addressInfo.IP.ipAddress))
112     {
113         strncpy(info->addressInfo.IP.ipAddress, connectivity->addressInfo.IP.ipAddress,
114                 CA_IPADDR_SIZE - 1);
115         info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
116         info->addressInfo.IP.port = connectivity->addressInfo.IP.port;
117     }
118     else
119     {
120         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
121         OICFree(info);
122         return NULL;
123     }
124
125     info->isSecured = connectivity->isSecured;
126     return info;
127 }
128
129 void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint)
130 {
131     OICFree(localEndpoint);
132 }
133
134 CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type,
135         const char *address,
136         const char *resourceUri)
137 {
138     CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
139                                OICCalloc(1, sizeof(CARemoteEndpoint_t));
140     if (NULL == info)
141     {
142         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
143         return NULL;
144     }
145
146     info->connectivityType = type;
147     if (address && strlen(address))
148     {
149         if (CA_EDR == type)
150         {
151             strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1);
152             info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
153         }
154         else if (CA_LE == type)
155         {
156             strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1);
157             info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
158         }
159         else if (CA_WIFI == type || CA_ETHERNET == type)
160         {
161             strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1);
162             info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
163         }
164         else
165         {
166             OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "type is not matched with any transport!");
167             OICFree(info);
168             return NULL;
169         }
170     }
171
172     if (resourceUri && strlen(resourceUri))
173     {
174         info->resourceUri = OICStrdup(resourceUri);
175     }
176
177     return info;
178 }
179
180 CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint)
181 {
182     VERIFY_NON_NULL_RET(remoteEndpoint, CA_ADAPTER_UTILS_TAG, "Remote endpoint is NULL", NULL);
183
184     CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
185                                OICCalloc(1, sizeof(CARemoteEndpoint_t));
186     if (NULL == info)
187     {
188         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !");
189         return NULL;
190     }
191
192     info->connectivityType = remoteEndpoint->connectivityType;
193     if (CA_EDR == info->connectivityType && strlen(remoteEndpoint->addressInfo.BT.btMacAddress))
194     {
195         strncpy(info->addressInfo.BT.btMacAddress, remoteEndpoint->addressInfo.BT.btMacAddress,
196                 CA_MACADDR_SIZE - 1);
197         info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
198     }
199     else if (CA_LE == info->connectivityType && strlen(remoteEndpoint->addressInfo.LE.leMacAddress))
200     {
201         strncpy(info->addressInfo.LE.leMacAddress, remoteEndpoint->addressInfo.LE.leMacAddress,
202                 CA_MACADDR_SIZE - 1);
203         info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
204     }
205     else if ((CA_WIFI == info->connectivityType || CA_ETHERNET == info->connectivityType)
206              && strlen(remoteEndpoint->addressInfo.IP.ipAddress))
207     {
208         strncpy(info->addressInfo.IP.ipAddress, remoteEndpoint->addressInfo.IP.ipAddress,
209                 CA_IPADDR_SIZE - 1);
210         info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
211         info->addressInfo.IP.port = remoteEndpoint->addressInfo.IP.port;
212     }
213     else
214     {
215         OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "Its not matching. May be multicast.");
216     }
217
218     //For Multicast, remote address will be null while resourceUri will have the service UUID
219
220     if (remoteEndpoint->resourceUri && strlen(remoteEndpoint->resourceUri))
221     {
222         info->resourceUri = OICStrdup(remoteEndpoint->resourceUri);
223     }
224
225     info->isSecured = remoteEndpoint->isSecured;
226     return info;
227 }
228
229 void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint)
230 {
231     if (remoteEndpoint)
232     {
233         OICFree(remoteEndpoint->resourceUri);
234         OICFree(remoteEndpoint);
235     }
236 }
237
238 CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr,
239                                    size_t ipAddrLen, uint16_t *port)
240 {
241     if (!ipAddr || !isdigit(ipAddrStr[0]) || !port)
242     {
243         OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
244         return CA_STATUS_INVALID_PARAM;
245     }
246
247     size_t index = 0;
248     uint8_t dotCount = 0;
249
250     ipAddr[index] = 0;
251     *port = 0;
252     while (*ipAddrStr)
253     {
254         if (isdigit(*ipAddrStr))
255         {
256             if(index >= ipAddrLen)
257             {
258                 OIC_LOG(ERROR, CA_ADAPTER_UTILS_TAG, "invalid param");
259                 return CA_STATUS_INVALID_PARAM;
260             }
261             ipAddr[index] *= 10;
262             ipAddr[index] += *ipAddrStr - '0';
263         }
264         else if (*ipAddrStr == '.')
265         {
266             index++;
267             dotCount++;
268             ipAddr[index] = 0;
269         }
270         else
271         {
272             break;
273         }
274         ipAddrStr++;
275     }
276
277     if (*ipAddrStr == ':')
278     {
279         ipAddrStr++;
280         while (*ipAddrStr)
281         {
282             if (isdigit(*ipAddrStr))
283             {
284                 *port *= 10;
285                 *port += *ipAddrStr - '0';
286             }
287             else
288             {
289                 break;
290             }
291             ipAddrStr++;
292         }
293     }
294
295     if (dotCount == 3)
296     {
297         return CA_STATUS_OK;
298     }
299     return CA_STATUS_FAILED;
300 }
301
302 bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, const char *netMask)
303 {
304     VERIFY_NON_NULL_RET(ipAddress1, CA_ADAPTER_UTILS_TAG, "First address", false);
305     VERIFY_NON_NULL_RET(ipAddress2, CA_ADAPTER_UTILS_TAG, "Second address", false);
306     VERIFY_NON_NULL_RET(netMask, CA_ADAPTER_UTILS_TAG, "netMask", false);
307
308     uint8_t ipList1[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
309     uint8_t ipList2[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
310     uint8_t maskList[IPV4_ADDR_ONE_OCTECT_LEN] = { 0 };
311     CAResult_t ret = CA_STATUS_OK;
312
313     /* Local Loopback Address */
314     if (0 == strncmp(ipAddress1, "127.", 4) || 0 == strncmp(ipAddress2, "127.", 4))
315     {
316         return true;
317     }
318
319     uint16_t parsedPort = 0;
320     ret = CAParseIPv4AddressInternal(ipAddress1, ipList1, sizeof(ipList1), &parsedPort);
321     if (ret != CA_STATUS_OK)
322     {
323         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "First ip address parse fail %d", ret);
324         return false;
325     }
326
327     ret = CAParseIPv4AddressInternal(ipAddress2, ipList2, sizeof(ipList2), &parsedPort);
328     if (ret != CA_STATUS_OK)
329     {
330         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Second ip address parse fail %d", ret);
331         return false;
332     }
333
334     ret = CAParseIPv4AddressInternal(netMask, maskList, sizeof(maskList), &parsedPort);
335     if (ret != CA_STATUS_OK)
336     {
337         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Net mask parse fail %d", ret);
338         return false;
339     }
340
341     return ((ipList1[0] & maskList[0]) == (ipList2[0] & maskList[0])) && ((ipList1[1] & maskList[1])
342             == (ipList2[1] & maskList[1]))
343            && ((ipList1[2] & maskList[2]) == (ipList2[2] & maskList[2]))
344            && ((ipList1[3] & maskList[3]) == (ipList2[3] & maskList[3]));
345 }
346