[Jira IOT-604] Fix error handling from message handler
[platform/upstream/iotivity.git] / resource / csdk / connectivity / common / 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 "oic_string.h"
25 #include "caremotehandler.h"
26 #include "logger.h"
27
28 #define TAG "CA"
29
30 CAEndpoint_t *CACloneEndpoint(const CAEndpoint_t *rep)
31 {
32     if (NULL == rep)
33     {
34         OIC_LOG(ERROR, TAG, "parameter is null");
35         return NULL;
36     }
37
38     // allocate the remote end point structure.
39     CAEndpoint_t *clone = (CAEndpoint_t *)OICMalloc(sizeof (CAEndpoint_t));
40     if (NULL == clone)
41     {
42         OIC_LOG(ERROR, TAG, "CACloneRemoteEndpoint Out of memory");
43         return NULL;
44     }
45     *clone = *rep;
46
47     return clone;
48 }
49
50 CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
51 {
52     if (NULL == rep)
53     {
54         OIC_LOG(ERROR, TAG, "parameter is null");
55         return NULL;
56     }
57
58     // allocate the request info structure.
59     CARequestInfo_t *clone = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
60     if (!clone)
61     {
62         OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
63         return NULL;
64     }
65
66     *clone = *rep;
67
68     if (rep->info.token)
69     {
70         char *temp = NULL;
71
72         // allocate token field
73         uint8_t len = rep->info.tokenLength;
74
75         if (len)
76         {
77             temp = (char *) OICCalloc(len, sizeof(char));
78             if (!temp)
79             {
80                 OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
81
82                 CADestroyRequestInfoInternal(clone);
83
84                 return NULL;
85             }
86             memcpy(temp, rep->info.token, len);
87         }
88
89         // save the token
90         clone->info.token = temp;
91         clone->info.tokenLength = len;
92     }
93
94     if (NULL != rep->info.options && 0 < rep->info.numOptions)
95     {
96         // save the options
97         clone->info.options =
98             (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
99         if (NULL == clone->info.options)
100         {
101             OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
102             OICFree(clone->info.token);
103             OICFree(clone);
104             return NULL;
105         }
106         memcpy(clone->info.options, rep->info.options,
107                sizeof(CAHeaderOption_t) * rep->info.numOptions);
108     }
109     else
110     {
111         clone->info.options = NULL;
112         clone->info.numOptions = 0;
113     }
114
115     if (NULL != rep->info.payload)
116     {
117         // allocate payload field
118         uint8_t *temp = OICMalloc(rep->info.payloadSize);
119         if (NULL == temp)
120         {
121             OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
122
123             CADestroyRequestInfoInternal(clone);
124
125             return NULL;
126         }
127         memcpy(temp, rep->info.payload, rep->info.payloadSize);
128
129         // save the payload
130         clone->info.payload = temp;
131     }
132
133     if (NULL != rep->info.resourceUri)
134     {
135         // allocate payload field
136         char *temp = OICStrdup(rep->info.resourceUri);
137         if (NULL == temp)
138         {
139             OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
140
141             CADestroyRequestInfoInternal(clone);
142
143             return NULL;
144         }
145
146         // save the resourceUri
147         clone->info.resourceUri = temp;
148     }
149
150     return clone;
151 }
152
153 CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
154 {
155     if (NULL == rep)
156     {
157         OIC_LOG(ERROR, TAG, "Response pointer is NULL");
158         return NULL;
159     }
160
161     // check the result value of response info.
162     // Keep this check in sync with CAResponseResult_t
163     switch (rep->result)
164     {
165         case CA_EMPTY:
166         case CA_SUCCESS:
167         case CA_CREATED:
168         case CA_DELETED:
169         case CA_VALID:
170         case CA_CONTENT:
171         case CA_CHANGED:
172         case CA_CONTINUE:
173         case CA_BAD_REQ:
174         case CA_UNAUTHORIZED_REQ:
175         case CA_BAD_OPT:
176         case CA_FORBIDDEN_REQ:
177         case CA_NOT_FOUND:
178         case CA_REQUEST_ENTITY_INCOMPLETE:
179         case CA_REQUEST_ENTITY_TOO_LARGE:
180         case CA_INTERNAL_SERVER_ERROR:
181         case CA_RETRANSMIT_TIMEOUT:
182             break;
183
184         default:
185             OIC_LOG_V(ERROR, TAG, "Response code  %u is invalid", rep->result);
186             return NULL;
187     }
188
189     // allocate the response info structure.
190     CAResponseInfo_t *clone = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
191     if (NULL == clone)
192     {
193         OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
194         return NULL;
195     }
196     *clone = *rep;
197
198     if (rep->info.token)
199     {
200         char *temp = NULL;
201
202         // allocate token field
203         uint8_t len = rep->info.tokenLength;
204
205         if (len)
206         {
207             temp = (char *) OICCalloc(len, sizeof(char));
208             if (!temp)
209             {
210                 OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
211
212                 CADestroyResponseInfoInternal(clone);
213
214                 return NULL;
215             }
216             memcpy(temp, rep->info.token, len);
217         }
218         // save the token
219         clone->info.token = temp;
220         clone->info.tokenLength = len;
221     }
222
223     if (NULL != rep->info.options && rep->info.numOptions)
224     {
225         // save the options
226         clone->info.options =
227                 (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * rep->info.numOptions);
228
229         if (NULL == clone->info.options)
230         {
231             OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
232
233             OICFree(clone->info.token);
234             OICFree(clone);
235             return NULL;
236         }
237         memcpy(clone->info.options, rep->info.options,
238                 sizeof(CAHeaderOption_t) * rep->info.numOptions);
239     }
240     else
241     {
242         clone->info.options = NULL;
243         clone->info.numOptions = 0;
244     }
245
246     if (NULL != rep->info.payload)
247     {
248         // allocate payload field
249         uint8_t *temp = (uint8_t *) OICMalloc(rep->info.payloadSize);
250         if (NULL == temp)
251         {
252             OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
253
254             CADestroyResponseInfoInternal(clone);
255
256             return NULL;
257         }
258         memcpy(temp, rep->info.payload, rep->info.payloadSize);
259
260         // save the payload
261         clone->info.payload = temp;
262     }
263
264     if (NULL != rep->info.resourceUri)
265     {
266         // allocate payload field
267         char *temp = OICStrdup(rep->info.resourceUri);
268         if (NULL == temp)
269         {
270             OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
271
272             CADestroyResponseInfoInternal(clone);
273
274             return NULL;
275         }
276
277         // save the resourceUri
278         clone->info.resourceUri = temp;
279     }
280
281     return clone;
282 }
283
284 CAEndpoint_t *CACreateEndpointObject(CATransportFlags_t flags,
285                                      CATransportAdapter_t adapter,
286                                      const char *address,
287                                      uint16_t port)
288 {
289     CAEndpoint_t *info = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t));
290     if (NULL == info)
291     {
292         OIC_LOG(ERROR, TAG, "Memory allocation failed !");
293         return NULL;
294     }
295
296     if (address)
297     {
298         OICStrcpy(info->addr, sizeof(info->addr), address);
299         info->addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
300     }
301     info->flags = flags;
302     info->adapter = adapter;
303     info->port = port;
304
305     return info;
306 }
307
308 void CAFreeEndpoint(CAEndpoint_t *rep)
309 {
310     OICFree(rep);
311 }
312
313 static void CADestroyInfoInternal(CAInfo_t *info)
314 {
315     // free token field
316     OICFree(info->token);
317     info->token = NULL;
318     info->tokenLength = 0;
319
320     // free options field
321     OICFree(info->options);
322     info->options = NULL;
323     info->numOptions = 0;
324
325
326     // free payload field
327     OICFree((char *) info->payload);
328     info->payload = NULL;
329     info->payloadSize = 0;
330
331     // free uri
332     OICFree(info->resourceUri);
333     info->resourceUri = NULL;
334 }
335
336 void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
337 {
338     if (NULL == rep)
339     {
340         OIC_LOG(ERROR, TAG, "parameter is null");
341         return;
342     }
343
344     CADestroyInfoInternal(&rep->info);
345     OICFree(rep);
346 }
347
348 void CADestroyResponseInfoInternal(CAResponseInfo_t *rep)
349 {
350     if (NULL == rep)
351     {
352         OIC_LOG(ERROR, TAG, "parameter is null");
353         return;
354     }
355
356     CADestroyInfoInternal(&rep->info);
357     OICFree(rep);
358 }
359
360 void CADestroyErrorInfoInternal(CAErrorInfo_t *errorInfo)
361 {
362     if (NULL == errorInfo)
363     {
364         OIC_LOG(ERROR, TAG, "parameter is null");
365         return;
366     }
367
368     CADestroyInfoInternal(&errorInfo->info);
369     OICFree(errorInfo);
370 }
371
372 CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone)
373 {
374     if (!info || !clone)
375     {
376         OIC_LOG(ERROR, TAG, "input parameter invalid");
377         return CA_STATUS_INVALID_PARAM;
378     }
379
380     //Do not free clone. we cannot declare it const, as the content is modified
381     if ((info->token) && (0 < info->tokenLength))
382     {
383         char *temp = NULL;
384
385         // allocate token field
386         uint8_t len = info->tokenLength;
387
388         temp = (char *) OICMalloc(len * sizeof(char));
389         if (!temp)
390         {
391             OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
392             return CA_MEMORY_ALLOC_FAILED;
393         }
394
395         memcpy(temp, info->token, len);
396         // save the token
397         clone->token = temp;
398         clone->tokenLength = len;
399     }
400
401     if (info->options && (0 < info->numOptions))
402     {
403         // save the options
404         clone->options =
405             (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * info->numOptions);
406
407         if (!clone->options)
408         {
409             OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
410             CADestroyInfoInternal(clone);
411             return CA_MEMORY_ALLOC_FAILED;
412         }
413         memcpy(clone->options, info->options, sizeof(CAHeaderOption_t) * info->numOptions);
414     }
415
416     if (info->payload)
417     {
418         // allocate payload field
419         uint8_t *temp = OICMalloc(info->payloadSize);
420         if (!temp)
421         {
422             OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
423             CADestroyInfoInternal(clone);
424             return CA_MEMORY_ALLOC_FAILED;
425         }
426         memcpy(temp, info->payload, info->payloadSize);
427
428         // save the payload
429         clone->payload = temp;
430     }
431
432     if (info->resourceUri)
433     {
434         // allocate payload field
435         char *temp = OICStrdup(info->resourceUri);
436         if (!temp)
437         {
438             OIC_LOG(ERROR, TAG, "CAClonePayloadInfo Out of memory");
439             CADestroyInfoInternal(clone);
440             return CA_MEMORY_ALLOC_FAILED;
441         }
442
443         // save the resourceUri
444         clone->resourceUri = temp;
445     }
446
447     return CA_STATUS_OK;
448
449 }