Removed Token ASCII-char limit and length limit
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / caremotehandler.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 <string.h>
22
23 #include "oic_malloc.h"
24 #include "caremotehandler.h"
25 #include "logger.h"
26
27 #define TAG "CA"
28
29 CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *rep)
30 {
31     char *temp = NULL;
32     size_t len = 0;
33
34     if (rep == NULL)
35         return NULL;
36
37     // allocate the remote end point structure.
38     CARemoteEndpoint_t *clone = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t));
39     if (clone == NULL)
40     {
41         OIC_LOG(DEBUG, TAG, "CACloneRemoteEndpoint Out of memory");
42         return NULL;
43     }
44     memcpy(clone, rep, sizeof(CARemoteEndpoint_t));
45
46     if (rep->resourceUri != NULL)
47     {
48         // allocate reference uri field
49         len = strlen(rep->resourceUri);
50
51         temp = (char *) OICCalloc(len + 1, sizeof(char));
52         if (temp == NULL)
53         {
54             OIC_LOG(DEBUG, TAG, "CACloneRemoteEndpoint Out of memory");
55
56             CADestroyRemoteEndpointInternal(clone);
57
58             return NULL;
59         }
60
61         strncpy(temp, rep->resourceUri, len);
62
63         // save the uri
64         clone->resourceUri = temp;
65     }
66
67     return clone;
68 }
69
70 #define COAP_PREFIX         "coap://"
71 #define COAP_PREFIX_LEN     7
72 #define COAPS_PREFIX         "coaps://"
73 #define COAPS_PREFIX_LEN     8
74
75
76 // return 1 : ip
77 // return 0 : mac
78 static int32_t getCAAddress(const char *pAddress, CAAddress_t *outAddress)
79 {
80     if (pAddress == NULL || outAddress == NULL)
81         return -1;
82
83     // simple parse, it will be change.
84     // 10.11.12.13:4545 (ip)
85     // 10:11:12:13:45:45 (mac)
86
87     int32_t len = strlen(pAddress);
88
89     int32_t isIp = 0;
90     int32_t ipLen = 0;
91
92     int i = 0;
93     for (i = 0; i < len; i++)
94     {
95         if (pAddress[i] == '.')
96         {
97             isIp = 1;
98         }
99
100         // found port number start index
101         if (isIp && pAddress[i] == ':')
102         {
103             ipLen = i;
104             break;
105         }
106     }
107
108     if (isIp)
109     {
110         strncpy(outAddress->IP.ipAddress, pAddress, ipLen == 0 ? len : ipLen);
111
112         if (ipLen > 0)
113             outAddress->IP.port = atoi(pAddress + ipLen + 1);
114
115         OIC_LOG_V(DEBUG, TAG, "ip: %s, port: %d", outAddress->IP.ipAddress, outAddress->IP.port);
116     }
117     else
118     {
119         strncpy(outAddress->BT.btMacAddress, pAddress, CA_MACADDR_SIZE - 1);
120
121         OIC_LOG_V(DEBUG, TAG, "mac address : %s", outAddress->BT.btMacAddress);
122     }
123
124     return isIp;
125 }
126
127 CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri,
128                                                       const CAConnectivityType_t connectivityType)
129 {
130     // support URI type
131     // coap://10.11.12.13:4545/resource_uri
132     // coap://10:11:12:13:45:45/resource_uri
133
134     if (uri == NULL)
135         return NULL;
136
137     // parse uri
138     // #1. check prefix
139     int startIndex = 0;
140     bool secured = false;
141     if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
142     {
143         OIC_LOG_V(DEBUG, TAG, "uri has '%s' prefix.", COAP_PREFIX);
144         startIndex = COAP_PREFIX_LEN;
145     }
146
147     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
148     {
149         OIC_LOG_V(DEBUG, TAG, "uri has '%s' prefix.", COAPS_PREFIX);
150         startIndex = COAPS_PREFIX_LEN;
151         secured = true;
152     }
153
154     // #2. copy uri for parse
155     char *cloneUri = NULL;
156     int32_t len = strlen(uri) - startIndex;
157
158     if (len <= 0)
159     {
160         OIC_LOG(DEBUG, TAG, "uri length is 0!");
161         return NULL;
162     }
163
164     cloneUri = (char *) OICCalloc(len + 1, sizeof(char));
165     if (cloneUri == NULL)
166     {
167         OIC_LOG(DEBUG, TAG, "CACreateRemoteEndpointUriInternal Out of memory");
168         return NULL;
169     }
170
171     memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
172
173     // #3. parse address
174     // #4. parse resource uri
175     char *pAddress = cloneUri;
176     char *pResourceUri = NULL;
177
178     int32_t i = 0;
179     for (i = 0; i < len; i++)
180     {
181         if (cloneUri[i] == '/')
182         {
183             // separate
184             cloneUri[i] = 0;
185
186             pResourceUri = &cloneUri[i + 1];
187
188             break;
189         }
190
191     }
192
193     OIC_LOG_V(DEBUG, TAG, "pAddress : %s", pAddress);
194
195     OIC_LOG_V(DEBUG, TAG, "pResourceUri : %s", pResourceUri == NULL ? "" : pResourceUri);
196
197     // address
198     CAAddress_t address = {};
199
200     int resType = getCAAddress(pAddress, &address);
201     if (resType == -1)
202     {
203         OIC_LOG(DEBUG, TAG, "address parse error");
204
205         OICFree(cloneUri);
206         return NULL;
207     }
208
209     // resource uri
210     CAURI_t resourceUri = pResourceUri;
211
212     CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, address,
213                                                                         connectivityType);
214     if (remoteEndpoint == NULL)
215     {
216         OIC_LOG(DEBUG, TAG, "create remote endpoint fail");
217
218         OICFree(cloneUri);
219         return NULL;
220     }
221     remoteEndpoint->isSecured = secured;
222
223     OICFree(cloneUri);
224
225     OIC_LOG_V(DEBUG, TAG, "Remote endpoint successfully created [%d]!", remoteEndpoint->isSecured);
226     return remoteEndpoint;
227 }
228
229 CARemoteEndpoint_t *CACreateRemoteEndpointInternal(const CAURI_t resourceUri,
230         const CAAddress_t addr, const CAConnectivityType_t type)
231 {
232     char *temp = NULL;
233     int len = 0;
234
235     if (resourceUri == NULL)
236     {
237         OIC_LOG(DEBUG, TAG, "uri is null value");
238         return NULL;
239     }
240
241     // allocate the remote end point structure.
242     CARemoteEndpoint_t *rep = (CARemoteEndpoint_t *) OICCalloc(1, sizeof(CARemoteEndpoint_t));
243
244     if (rep == NULL)
245     {
246         OIC_LOG(DEBUG, TAG, "CACreateRemoteEndpointInternal of memory");
247         return NULL;
248     }
249
250     // allocate reference uri field
251     len = strlen(resourceUri);
252
253     temp = (char *) OICMalloc(sizeof(char) * (len + 1));
254     if (temp == NULL)
255     {
256         OIC_LOG(DEBUG, TAG, "CACreateRemoteEndpointInternal Out of memory");
257
258         CADestroyRemoteEndpointInternal(rep);
259
260         return NULL;
261     }
262     strncpy(temp, resourceUri, len);
263     temp[len] = '\0';
264
265     // save the uri
266     rep->resourceUri = temp;
267
268     // save the addressInfo
269     memcpy(&(rep->addressInfo), &addr, sizeof(CAAddress_t));
270
271     // save the type
272     rep->connectivityType = type;
273
274     return rep;
275 }
276
277 CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
278 {
279     if (rep == NULL)
280         return NULL;
281
282     // allocate the request info structure.
283     CARequestInfo_t *clone = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
284     if (!clone)
285     {
286         OIC_LOG(DEBUG, TAG, "CACloneRequestInfo Out of memory");
287         return NULL;
288     }
289
290     memcpy(clone, rep, sizeof(CARequestInfo_t));
291
292     if (rep->info.token)
293     {
294         char *temp = NULL;
295
296         // allocate token field
297         int len = rep->info.tokenLength;
298
299         if (len)
300         {
301             temp = (char *) OICCalloc(len, sizeof(char));
302             if (!temp)
303             {
304                 OIC_LOG(DEBUG, TAG, "CACloneRequestInfo Out of memory");
305
306                 CADestroyRequestInfoInternal(clone);
307
308                 return NULL;
309             }
310             memcpy(temp, rep->info.token, len);
311         }
312
313         // save the token
314         clone->info.token = temp;
315         clone->info.tokenLength = len;
316     }
317
318     if (rep->info.options != NULL && rep->info.numOptions > 0)
319     {
320         // save the options
321         clone->info.options =
322             (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
323         if (clone->info.options == NULL)
324         {
325             OIC_LOG(DEBUG, TAG, "CACloneRequestInfo Out of memory");
326             OICFree(clone->info.token);
327             OICFree(clone);
328             return NULL;
329         }
330         memcpy(clone->info.options,
331                 rep->info.options,
332                 sizeof(CAHeaderOption_t) * rep->info.numOptions);
333     }
334     else
335     {
336         clone->info.options = NULL;
337         clone->info.numOptions = 0;
338     }
339
340     if (rep->info.payload != NULL)
341     {
342         char *temp = NULL;
343
344         // allocate payload field
345         int len = strlen(rep->info.payload);
346
347         temp = (char *) OICMalloc(sizeof(char) * (len + 1));
348         if (temp == NULL)
349         {
350             OIC_LOG(DEBUG, TAG, "CACloneRequestInfo Out of memory");
351
352             CADestroyRequestInfoInternal(clone);
353
354             return NULL;
355         }
356         strncpy(temp, rep->info.payload, len);
357         temp[len] = '\0';
358
359         // save the payload
360         clone->info.payload = temp;
361     }
362
363     return clone;
364 }
365
366 CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
367 {
368     if (rep == NULL)
369         return NULL;
370
371     // allocate the response info structure.
372     CAResponseInfo_t *clone = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
373     if (clone == NULL)
374     {
375         OIC_LOG(DEBUG, TAG, "CACloneResponseInfo Out of memory");
376         return NULL;
377     }
378     memcpy(clone, rep, sizeof(CAResponseInfo_t));
379
380     if (rep->info.token)
381     {
382         char *temp = NULL;
383
384         // allocate token field
385         int len = rep->info.tokenLength;
386
387         if (len)
388         {
389             temp = (char *) OICCalloc(len, sizeof(char));
390             if (!temp)
391             {
392                 OIC_LOG(DEBUG, TAG, "CACloneResponseInfo Out of memory");
393
394                 CADestroyResponseInfoInternal(clone);
395
396                 return NULL;
397             }
398             memcpy(temp, rep->info.token, len);
399         }
400         // save the token
401         clone->info.token = temp;
402         clone->info.tokenLength = len;
403     }
404
405     if (rep->info.options != NULL && rep->info.numOptions)
406     {
407         // save the options
408         clone->info.options = (CAHeaderOption_t *) OICMalloc(
409                                 sizeof(CAHeaderOption_t) * rep->info.numOptions);
410
411         if (clone->info.options == NULL)
412         {
413             OIC_LOG(DEBUG, TAG, "CACloneResponseInfo Out of memory");
414             OICFree(clone->info.token);
415             OICFree(clone);
416             return NULL;
417         }
418         memcpy(clone->info.options, rep->info.options,
419                 sizeof(CAHeaderOption_t) * rep->info.numOptions);
420     }
421     else
422     {
423         clone->info.options = NULL;
424         clone->info.numOptions = 0;
425     }
426
427     if (rep->info.payload != NULL)
428     {
429         char *temp = NULL;
430         // allocate payload field
431         int len = strlen(rep->info.payload);
432
433         temp = (char *) OICCalloc(len + 1, sizeof(char));
434         if (temp == NULL)
435         {
436             OIC_LOG(DEBUG, TAG, "CACloneResponseInfo Out of memory");
437
438             CADestroyResponseInfoInternal(clone);
439
440             return NULL;
441         }
442         strncpy(temp, rep->info.payload, len);
443
444         // save the payload
445         clone->info.payload = temp;
446     }
447
448     return clone;
449 }
450
451 void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t *rep)
452 {
453     if (rep == NULL)
454         return;
455
456     // free uri field
457     OICFree((char *) rep->resourceUri);
458
459     // free remote end point structure.
460     OICFree(rep);
461 }
462
463 void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
464 {
465     if (rep == NULL)
466         return;
467
468     // free token field
469     OICFree(rep->info.token);
470
471     // free options field
472     OICFree((CAHeaderOption_t *) rep->info.options);
473
474     // free payload field
475     OICFree((char *) rep->info.payload);
476
477     OICFree(rep);
478 }
479
480 void CADestroyResponseInfoInternal(CAResponseInfo_t *rep)
481 {
482     if (rep == NULL)
483         return;
484
485     // free token field
486     OICFree(rep->info.token);
487
488     // free options field
489     if (rep->info.options != NULL && rep->info.numOptions)
490     {
491         OICFree((CAHeaderOption_t *) rep->info.options);
492     }
493
494     // free payload field
495     OICFree((char *) rep->info.payload);
496
497     OICFree(rep);
498 }
499