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