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