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