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