[IOT-1911] Make resource/csdk/stack W4 compliant.
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocendpoint.c
1 /* ****************************************************************
2  *
3  * Copyright 2016 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 "ocendpoint.h"
22 #include "logger.h"
23 #include "oic_malloc.h"
24 #include "oic_string.h"
25 #include <string.h>
26 #include "cainterface.h"
27
28 #define VERIFY_NON_NULL(arg) { if (!arg) {OIC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
29 #define VERIFY_GT_ZERO(arg) { if (arg < 1) {OIC_LOG(FATAL, TAG, #arg " < 1"); goto exit;} }
30 #define VERIFY_GT(arg1, arg2) { if (arg1 <= arg2) {OIC_LOG(FATAL, TAG, #arg1 " <= " #arg2); goto exit;} }
31 #define VERIFY_LT_OR_EQ(arg1, arg2) { if (arg1 > arg2) {OIC_LOG(FATAL, TAG, #arg1 " > " #arg2); goto exit;} }
32 #define TAG  "OIC_RI_ENDPOINT"
33
34 OCStackResult OCGetSupportedEndpointFlags(const OCTpsSchemeFlags givenFlags, OCTpsSchemeFlags* out)
35 {
36     if (!out)
37     {
38         return OC_STACK_INVALID_PARAM;
39     }
40
41     CATransportAdapter_t SelectedNetwork = CAGetSelectedNetwork();
42     if ((givenFlags & (OC_COAP | OC_COAPS)) && (SelectedNetwork & CA_ADAPTER_IP))
43     {
44         *out = (OCTpsSchemeFlags)(*out | OC_COAP);
45
46         if (OC_SECURE)
47         {
48             *out = (OCTpsSchemeFlags)(*out | OC_COAPS);
49         }
50     }
51 #ifdef TCP_ADAPTER
52     if ((givenFlags & (OC_COAP_TCP | OC_COAPS_TCP)) && (SelectedNetwork & CA_ADAPTER_TCP))
53     {
54
55         *out = (OCTpsSchemeFlags)(*out | OC_COAP_TCP);
56
57         if (OC_SECURE)
58         {
59             *out = (OCTpsSchemeFlags)(*out | OC_COAPS_TCP);
60         }
61     }
62 #endif
63 #ifdef EDR_ADAPTER
64     if ((givenFlags & OC_COAP_RFCOMM) && (SelectedNetwork & CA_ADAPTER_RFCOMM_BTEDR))
65     {
66         *out = (OCTpsSchemeFlags)(*out | OC_COAP_RFCOMM);
67     }
68 #endif
69 #ifdef LE_ADAPTER
70     if ((givenFlags & OC_COAP_GATT) && (SelectedNetwork & CA_ADAPTER_GATT_BTLE))
71     {
72         *out = (OCTpsSchemeFlags)(*out | OC_COAP_GATT);
73     }
74 #endif
75 #ifdef NFC_ADAPTER
76     if ((givenFlags & OC_COAP_NFC) && (SelectedNetwork & CA_ADAPTER_NFC))
77     {
78         *out = (OCTpsSchemeFlags)(*out | OC_COAP_NFC);
79     }
80 #endif
81 #ifdef RA_ADAPTER
82     if ((givenFlags & OC_COAP_RA) && (SelectedNetwork & CA_ADAPTER_REMOTE_ACCESS))
83     {
84         *out = (OCTpsSchemeFlags)(*out | OC_COAP_RA);
85     }
86 #endif
87
88     return OC_STACK_OK;
89 }
90
91 OCStackResult OCGetMatchedTpsFlags(const CATransportAdapter_t adapter,
92                                    const CATransportFlags_t flags,
93                                    OCTpsSchemeFlags* out)
94 {
95     // return matched TPS Flags with given CA flags.
96     if (!out)
97     {
98         OIC_LOG(ERROR, TAG, "out param is NULL!!!");
99         return OC_STACK_INVALID_PARAM;
100     }
101
102     if ((adapter & OC_ADAPTER_IP) && (flags & (OC_IP_USE_V4 | OC_IP_USE_V6)))
103     {
104         if (flags & OC_FLAG_SECURE)
105         {
106             // OC_COAPS
107             // typecasting to support C90(arduino)
108             *out = (OCTpsSchemeFlags)(*out | OC_COAPS);
109         }
110         else
111         {   // OC_COAP
112             // typecasting to support C90(arduino)
113             *out = (OCTpsSchemeFlags)(*out | OC_COAP);
114         }
115     }
116
117 #ifdef TCP_ADAPTER
118     if ((adapter & OC_ADAPTER_TCP) && (flags & (OC_IP_USE_V4 | OC_IP_USE_V6)))
119     {
120         if (flags & OC_FLAG_SECURE)
121         {
122             // OC_COAPS_TCP
123             // typecasting to support C90(arduino)
124             *out = (OCTpsSchemeFlags)(*out | OC_COAPS_TCP);
125         }
126         else
127         {
128             // OC_COAP_TCP
129             // typecasting to support C90(arduino)
130             *out = (OCTpsSchemeFlags)(*out | OC_COAP_TCP);
131         }
132     }
133 #endif
134 #ifdef HTTP_ADAPTER
135     // OC_HTTP
136     // @todo iotivity not support http transport yet...
137
138     // OC_HTTPS
139     // @todo iotivity not support https transport yet...
140 #endif
141 #ifdef EDR_ADAPTER
142     // OC_COAP_RFCOMM
143     if (adapter & OC_ADAPTER_RFCOMM_BTEDR)
144     {
145         // typecasting to support C90(arduino)
146         *out = (OCTpsSchemeFlags)(*out | OC_COAP_RFCOMM);
147     }
148 #endif
149 #ifdef LE_ADAPTER
150     // OC_COAP_GATT
151     if (adapter & CA_ADAPTER_GATT_BTLE)
152     {
153         // typecasting to support C90(arduino)
154         *out = (OCTpsSchemeFlags)(*out | OC_COAP_GATT);
155     }
156 #endif
157 #ifdef NFC_ADAPTER
158     // OC_COAP_NFC
159     if (adapter & CA_ADAPTER_NFC)
160     {
161         // typecasting to support C90(arduino)
162         *out = (OCTpsSchemeFlags)(*out | OC_COAP_NFC);
163     }
164 #endif
165 #ifdef RA_ADAPTER
166     // OC_COAP_RA
167     if (adapter & CA_ADAPTER_REMOTE_ACCESS)
168     {
169         // typecasting to support C90(arduino)
170         *out = (OCTpsSchemeFlags)(*out | OC_COAP_RA);
171     }
172 #endif
173     return OC_STACK_OK;
174 }
175
176
177 OCStackResult OCConvertTpsToString(const OCTpsSchemeFlags tps, char** out)
178 {
179     // return given tps as string for payload
180     // OC_COAP_IPV4 -> OC_COAP
181
182     if (!out)
183     {
184         return OC_STACK_INVALID_PARAM;
185     }
186
187     switch (tps)
188     {
189         case OC_COAP:
190             *out = OICStrdup(COAP_STR);
191             break;
192
193         case OC_COAPS:
194             *out = OICStrdup(COAPS_STR);
195             break;
196 #ifdef TCP_ADAPTER
197         case OC_COAP_TCP:
198             *out = OICStrdup(COAP_TCP_STR);
199             break;
200
201         case OC_COAPS_TCP:
202             *out = OICStrdup(COAPS_TCP_STR);
203             break;
204 #endif
205 #ifdef HTTP_ADAPTER
206         case OC_HTTP:
207             *out = OICStrdup(HTTP_STR);
208             break;
209
210         case OC_HTTPS:
211             *out = OICStrdup(HTTPS_STR);
212             break;
213 #endif
214 #ifdef EDR_ADAPTER
215         case OC_COAP_RFCOMM:
216             *out = OICStrdup(COAP_RFCOMM_STR);
217             break;
218 #endif
219         default:
220             return OC_STACK_INVALID_PARAM;
221     }
222     VERIFY_NON_NULL(*out);
223     return OC_STACK_OK;
224
225 exit:
226     return OC_STACK_NO_MEMORY;
227 }
228
229 char* OCCreateEndpointString(const OCEndpointPayload* endpoint)
230 {
231     if (!endpoint)
232     {
233         return NULL;
234     }
235
236     char* buf = (char*)OICCalloc(MAX_ADDR_STR_SIZE, sizeof(char));
237     VERIFY_NON_NULL(buf);
238
239     if ((strcmp(endpoint->tps, COAP_STR) == 0) || (strcmp(endpoint->tps, COAPS_STR) == 0)
240 #ifdef TCP_ADAPTER
241         || (strcmp(endpoint->tps, COAP_TCP_STR) == 0) ||(strcmp(endpoint->tps, COAPS_TCP_STR) == 0)
242 #endif
243 #ifdef HTTP_ADAPTER
244         || (strcmp(endpoint->tps, HTTP_STR) == 0) ||(strcmp(endpoint->tps, HTTPS_STR) == 0)
245 #endif
246         )
247     {
248         // checking addr is ipv4 or not
249         if (endpoint->family & OC_IP_USE_V4)
250         {
251             // ipv4
252             sprintf(buf, "%s://%s:%d", endpoint->tps, endpoint->addr, endpoint->port);
253         }
254         else
255         {
256             // ipv6
257             sprintf(buf, "%s://[%s]:%d", endpoint->tps, endpoint->addr, endpoint->port);
258         }
259     }
260 #ifdef EDR_ADAPTER
261     else if ((strcmp(endpoint->tps, COAP_RFCOMM_STR) == 0))
262     {
263         // coap+rfcomm
264         sprintf(buf, "%s://%s", endpoint->tps, endpoint->addr);
265     }
266 #endif
267     else
268     {
269         OIC_LOG_V(ERROR, TAG, "Payload has invalid TPS!!! %s", endpoint->tps);
270         return NULL;
271     }
272     return buf;
273
274 exit:
275     return NULL;
276 }
277
278 OCStackResult OCParseEndpointString(const char* endpointStr, OCEndpointPayload* out)
279 {
280     if (!endpointStr || !out)
281     {
282         return OC_STACK_INVALID_PARAM;
283     }
284
285     char* tmp = NULL;
286     void* ret = NULL;
287     char* tps = NULL;
288     char* addr = NULL;
289     char* origin = NULL;
290     char* tokPos = NULL;
291     size_t tpsCharsToWrite = 0;
292     size_t addrCharsToWrite = 0;
293     OCStackResult isEnabledAdapter = OC_STACK_ADAPTER_NOT_ENABLED;
294     OCTransportAdapter parsedAdapter = OC_DEFAULT_ADAPTER;
295
296     tps = (char*)OICCalloc(OC_MAX_TPS_STR_SIZE, sizeof(char));
297     VERIFY_NON_NULL(tps);
298
299     addr = (char*)OICCalloc(OC_MAX_ADDR_STR_SIZE, sizeof(char));
300     VERIFY_NON_NULL(addr);
301
302     origin = OICStrdup(endpointStr);
303     VERIFY_NON_NULL(origin);
304
305     // token start pos
306     tokPos = strstr(origin, OC_ENDPOINT_TPS_TOKEN);
307     VERIFY_NON_NULL(tokPos);
308
309     // copy tps
310     tpsCharsToWrite = tokPos - origin;
311     VERIFY_GT_ZERO(tpsCharsToWrite);
312     VERIFY_GT((size_t)OC_MAX_TPS_STR_SIZE, tpsCharsToWrite);
313     ret = memcpy(tps, origin, tpsCharsToWrite);
314     VERIFY_NON_NULL(ret);
315     OIC_LOG_V(INFO, TAG, "parsed tps is:%s", tps);
316
317     // check tps type
318     if (strcmp(tps, COAP_STR) == 0)
319     {
320         isEnabledAdapter = OC_STACK_OK;
321         parsedAdapter = OC_ADAPTER_IP;
322     }
323     else if (strcmp(tps, COAPS_STR) == 0)
324     {
325         isEnabledAdapter = OC_STACK_OK;
326         parsedAdapter = OC_ADAPTER_IP;
327     }
328 #ifdef TCP_ADAPTER
329     else if (strcmp(tps, COAP_TCP_STR) == 0)
330     {
331         isEnabledAdapter = OC_STACK_OK;
332         parsedAdapter = OC_ADAPTER_TCP;
333     }
334     else if (strcmp(tps, COAPS_TCP_STR) == 0)
335     {
336         isEnabledAdapter = OC_STACK_OK;
337         parsedAdapter = OC_ADAPTER_TCP;
338     }
339 #endif
340 #ifdef HTTP_ADAPTER
341     // @todo iotivity not support http, https transport yet...
342 #endif
343 #ifdef EDR_ADAPTER
344     else if (strcmp(tps, COAP_RFCOMM_STR) == 0)
345     {
346         isEnabledAdapter = OC_STACK_OK;
347         parsedAdapter = OC_ADAPTER_RFCOMM_BTEDR;
348     }
349 #endif
350     // ignore unrecognized tps type
351     if (isEnabledAdapter == OC_STACK_ADAPTER_NOT_ENABLED
352         && parsedAdapter == OC_DEFAULT_ADAPTER)
353     {
354         OICFree(tps);
355         OICFree(addr);
356         OICFree(origin);
357         return OC_STACK_ADAPTER_NOT_ENABLED;
358     }
359
360 #ifdef EDR_ADAPTER
361     if (parsedAdapter == OC_ADAPTER_RFCOMM_BTEDR)
362     {
363         // copy addr
364         tokPos = tokPos + 3;
365         ret = strcpy(addr, tokPos);
366         VERIFY_NON_NULL(ret);
367         out->tps = tps;
368         out->addr = addr;
369         out->family = OC_DEFAULT_FLAGS;
370         out->port = 0;
371     }
372     else
373 #endif
374     {
375         // first check epl has square bracket
376         tmp = strchr(origin, OC_ENDPOINT_BRACKET_START);
377         if (tmp)
378         {
379             out->family = OC_IP_USE_V6;
380             tokPos = tokPos + 4;
381             tmp = strrchr(origin, OC_ENDPOINT_BRACKET_END);
382         }
383         else
384         {
385             out->family = OC_IP_USE_V4;
386             tokPos = tokPos + 3;
387             tmp = strrchr(origin, OC_ENDPOINT_ADDR_TOKEN);
388         }
389         VERIFY_NON_NULL(tmp);
390
391         // copy addr
392         addrCharsToWrite = tmp - tokPos;
393         VERIFY_GT_ZERO(addrCharsToWrite);
394         VERIFY_GT((size_t)OC_MAX_ADDR_STR_SIZE, addrCharsToWrite);
395         ret = memcpy(addr, tokPos, addrCharsToWrite);
396         VERIFY_NON_NULL(ret);
397         OIC_LOG_V(INFO, TAG, "parsed addr is:%s", addr);
398
399         tmp = strrchr(origin, OC_ENDPOINT_ADDR_TOKEN);
400         VERIFY_NON_NULL(tmp);
401
402         // port start pos
403         tokPos = tmp + 1;
404         char* end = NULL;
405         long port = strtol(tokPos, &end, 10);
406         VERIFY_GT_ZERO(port);
407         VERIFY_LT_OR_EQ(port, UINT16_MAX);
408         OIC_LOG_V(INFO, TAG, "parsed port is:%s", tokPos);
409
410         out->tps = tps;
411         out->addr = addr;
412         out->port = (uint16_t)port;
413     }
414
415     OICFree(origin);
416     origin = NULL;
417     tokPos = NULL;
418     tmp = NULL;
419     ret = NULL;
420
421     return OC_STACK_OK;
422 exit:
423     OICFree(origin);
424     OICFree(tps);
425     OICFree(addr);
426     origin = NULL;
427     tokPos = NULL;
428     tmp = NULL;
429     ret = NULL;
430     tps = NULL;
431     addr = NULL;
432
433     return OC_STACK_ERROR;
434 }
435
436 OCTpsSchemeFlags OCGetSupportedTpsFlags()
437 {
438     OCTpsSchemeFlags ret = OC_NO_TPS;
439     CATransportAdapter_t SelectedNetwork = CAGetSelectedNetwork();
440
441     if (SelectedNetwork & CA_ADAPTER_IP)
442     {
443         ret = (OCTpsSchemeFlags)(ret | OC_COAP);
444
445         if (OC_SECURE)
446         {
447             ret = (OCTpsSchemeFlags)(ret | OC_COAPS);
448         }
449     }
450 #ifdef TCP_ADAPTER
451     if (SelectedNetwork & CA_ADAPTER_TCP)
452     {
453         ret = (OCTpsSchemeFlags)(ret | OC_COAP_TCP);
454
455         if (OC_SECURE)
456         {
457             ret = (OCTpsSchemeFlags)(ret | OC_COAPS_TCP);
458         }
459     }
460 #endif
461 #ifdef EDR_ADAPTER
462     if (SelectedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
463     {
464         ret = (OCTpsSchemeFlags)(ret | OC_COAP_RFCOMM);
465     }
466 #endif
467 #ifdef LE_ADAPTER
468     if (SelectedNetwork & CA_ADAPTER_GATT_BTLE)
469     {
470         ret = (OCTpsSchemeFlags)(ret | OC_COAP_GATT);
471     }
472 #endif
473 #ifdef NFC_ADAPTER
474     if (SelectedNetwork & CA_ADAPTER_NFC)
475     {
476         ret = (OCTpsSchemeFlags)(ret | OC_COAP_NFC);
477     }
478 #endif
479 #ifdef RA_ADAPTER
480     if (SelectedNetwork & CA_ADAPTER_REMOTE_ACCESS)
481     {
482         ret = (OCTpsSchemeFlags)(ret | OC_COAP_RA);
483     }
484 #endif
485     return ret;
486 }