[CONPRO-1561] Crash in memcpy
[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     // check the method type of request info.
59     // Keep this check in sync with CAMethod_t
60     switch (rep->method)
61     {
62         case CA_GET:
63         case CA_POST:
64         case CA_PUT:
65         case CA_DELETE:
66             break;
67         default:
68             OIC_LOG_V(ERROR, TAG, "Method %u is invalid", rep->method);
69             return NULL;
70     }
71
72     // allocate the request info structure.
73     CARequestInfo_t *clone = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
74     if (!clone)
75     {
76         OIC_LOG(ERROR, TAG, "CACloneRequestInfo Out of memory");
77         return NULL;
78     }
79
80     CAResult_t result = CACloneInfo(&rep->info, &clone->info);
81     if(CA_STATUS_OK != result)
82     {
83         OIC_LOG(ERROR, TAG, "CACloneRequestInfo error in CACloneInfo");
84         CADestroyRequestInfoInternal(clone);
85         return NULL;
86     }
87
88     clone->method = rep->method;
89     clone->isMulticast = rep->isMulticast;
90
91     return clone;
92 }
93
94 CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
95 {
96     if (NULL == rep)
97     {
98         OIC_LOG(ERROR, TAG, "Response pointer is NULL");
99         return NULL;
100     }
101
102     // check the result value of response info.
103     // Keep this check in sync with CAResponseResult_t
104     switch (rep->result)
105     {
106         case CA_EMPTY:
107         case CA_CREATED:
108         case CA_DELETED:
109         case CA_VALID:
110         case CA_CONTENT:
111         case CA_CHANGED:
112         case CA_CONTINUE:
113         case CA_BAD_REQ:
114         case CA_UNAUTHORIZED_REQ:
115         case CA_BAD_OPT:
116         case CA_FORBIDDEN_REQ:
117         case CA_NOT_FOUND:
118         case CA_METHOD_NOT_ALLOWED:
119         case CA_NOT_ACCEPTABLE:
120         case CA_REQUEST_ENTITY_INCOMPLETE:
121         case CA_REQUEST_ENTITY_TOO_LARGE:
122         case CA_TOO_MANY_REQUESTS:
123         case CA_INTERNAL_SERVER_ERROR:
124         case CA_NOT_IMPLEMENTED:
125         case CA_BAD_GATEWAY:
126         case CA_SERVICE_UNAVAILABLE:
127         case CA_RETRANSMIT_TIMEOUT:
128         case CA_PROXY_NOT_SUPPORTED:
129             break;
130         default:
131             OIC_LOG_V(ERROR, TAG, "Response code  %u is invalid", rep->result);
132             return NULL;
133     }
134
135     // allocate the response info structure.
136     CAResponseInfo_t *clone = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
137     if (NULL == clone)
138     {
139         OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
140         return NULL;
141     }
142
143     CAResult_t result = CACloneInfo(&rep->info, &clone->info);
144     if(CA_STATUS_OK != result)
145     {
146         OIC_LOG(ERROR, TAG, "CACloneResponseInfo error in CACloneInfo");
147         CADestroyResponseInfoInternal(clone);
148         return NULL;
149     }
150
151     clone->isMulticast = rep->isMulticast;
152     clone->result = rep->result;
153     return clone;
154 }
155
156 CAEndpoint_t *CACreateEndpointObject(CATransportFlags_t flags,
157                                      CATransportAdapter_t adapter,
158                                      const char *address,
159                                      uint16_t port)
160 {
161     CAEndpoint_t *info = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t));
162     if (NULL == info)
163     {
164         OIC_LOG(ERROR, TAG, "Memory allocation failed !");
165         return NULL;
166     }
167
168     if (address)
169     {
170         OICStrcpy(info->addr, sizeof(info->addr), address);
171         info->addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
172     }
173     info->flags = flags;
174     info->adapter = adapter;
175     info->port = port;
176
177     return info;
178 }
179
180 void CAFreeEndpoint(CAEndpoint_t *rep)
181 {
182     OICFree(rep);
183 }
184
185 static void CADestroyInfoInternal(CAInfo_t *info)
186 {
187     if (NULL == info)
188     {
189         return;
190     }
191
192     // free token field
193     OICFree(info->token);
194     info->token = NULL;
195     info->tokenLength = 0;
196
197     // free options field
198     OICFree(info->options);
199     info->options = NULL;
200     info->numOptions = 0;
201
202     // free payload field
203     OICFree((char *) info->payload);
204     info->payload = NULL;
205     info->payloadSize = 0;
206
207     // free uri
208     OICFree(info->resourceUri);
209     info->resourceUri = NULL;
210 }
211
212 void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
213 {
214     if (NULL == rep)
215     {
216         OIC_LOG(ERROR, TAG, "parameter is null");
217         return;
218     }
219
220     CADestroyInfoInternal(&rep->info);
221     OICFree(rep);
222 }
223
224 void CADestroyResponseInfoInternal(CAResponseInfo_t *rep)
225 {
226     if (NULL == rep)
227     {
228         OIC_LOG(ERROR, TAG, "parameter is null");
229         return;
230     }
231
232     CADestroyInfoInternal(&rep->info);
233     OICFree(rep);
234 }
235
236 void CADestroyErrorInfoInternal(CAErrorInfo_t *errorInfo)
237 {
238     if (NULL == errorInfo)
239     {
240         OIC_LOG(ERROR, TAG, "parameter is null");
241         return;
242     }
243
244     CADestroyInfoInternal(&errorInfo->info);
245     OICFree(errorInfo);
246 }
247
248 CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone)
249 {
250     if (!info || !clone)
251     {
252         OIC_LOG(ERROR, TAG, "input parameter invalid");
253         return CA_STATUS_INVALID_PARAM;
254     }
255
256     memset(clone, 0 , sizeof(CAInfo_t));
257
258     //Do not free clone. we cannot declare it const, as the content is modified
259     if ((info->token) && (0 < info->tokenLength))
260     {
261         // allocate token field
262         uint8_t len = info->tokenLength;
263
264         char *temp = (char *) OICCalloc(1, (len + 1) * sizeof(char));
265         if (!temp)
266         {
267             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
268             goto exit;
269         }
270
271         memcpy(temp, info->token, len);
272         // save the token
273         clone->token = temp;
274         clone->tokenLength = len;
275     }
276
277     if (info->options && (0 < info->numOptions))
278     {
279         // save the options
280         clone->options =
281             (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * info->numOptions);
282
283         if (!clone->options)
284         {
285             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
286             goto exit;
287         }
288         memcpy(clone->options, info->options, sizeof(CAHeaderOption_t) * info->numOptions);
289         clone->numOptions = info->numOptions;
290     }
291
292     memcpy(&(clone->identity), &(info->identity), sizeof(info->identity));
293
294     if ((info->payload) && (0 < info->payloadSize))
295     {
296         // allocate payload field
297         uint8_t *temp = OICMalloc(info->payloadSize);
298         if (!temp)
299         {
300             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
301             goto exit;
302         }
303         memcpy(temp, info->payload, info->payloadSize);
304
305         // save the payload
306         clone->payload = temp;
307         clone->payloadSize = info->payloadSize;
308     }
309     clone->payloadFormat = info->payloadFormat;
310     clone->acceptFormat = info->acceptFormat;
311
312     if (info->resourceUri)
313     {
314         // allocate payload field
315         char *temp = OICStrdup(info->resourceUri);
316         if (!temp)
317         {
318             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
319             goto exit;
320         }
321
322         // save the resourceUri
323         clone->resourceUri = temp;
324     }
325
326 #ifdef ROUTING_GATEWAY
327     clone->skipRetransmission = info->skipRetransmission;
328 #endif
329
330     clone->messageId = info->messageId;
331     clone->type = info->type;
332
333     return CA_STATUS_OK;
334
335 exit:
336     CADestroyInfoInternal(clone);
337     return CA_MEMORY_ALLOC_FAILED;
338 }