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