Support Signaling Message for CoAP over TCP
[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 "experimental/logger.h"
27
28 #define TAG "OIC_CA_REMOTE_HANDLER"
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_CHANGED:
111         case CA_CONTENT:
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_INTERNAL_SERVER_ERROR:
123         case CA_BAD_GATEWAY:
124         case CA_SERVICE_UNAVAILABLE:
125         case CA_RETRANSMIT_TIMEOUT:
126         case CA_PROXY_NOT_SUPPORTED:
127             break;
128         default:
129             OIC_LOG_V(ERROR, TAG, "Response code  %u is invalid", rep->result);
130             return NULL;
131     }
132
133     // allocate the response info structure.
134     CAResponseInfo_t *clone = (CAResponseInfo_t *) OICCalloc(1, sizeof(CAResponseInfo_t));
135     if (NULL == clone)
136     {
137         OIC_LOG(ERROR, TAG, "CACloneResponseInfo Out of memory");
138         return NULL;
139     }
140
141     CAResult_t result = CACloneInfo(&rep->info, &clone->info);
142     if(CA_STATUS_OK != result)
143     {
144         OIC_LOG(ERROR, TAG, "CACloneResponseInfo error in CACloneInfo");
145         CADestroyResponseInfoInternal(clone);
146         return NULL;
147     }
148
149     clone->isMulticast = rep->isMulticast;
150     clone->result = rep->result;
151     return clone;
152 }
153
154 CASignalingInfo_t *CACloneSignalingInfo(const CASignalingInfo_t *sig)
155 {
156     if (NULL == sig)
157     {
158         OIC_LOG(ERROR, TAG, "Singnaling pointer is NULL");
159         return NULL;
160     }
161
162     // check the result value of signaling info.
163     // Keep this check in sync with CASignalingCode_t.
164     switch (sig->code)
165     {
166         case CA_CSM:
167         case CA_PING:
168         case CA_PONG:
169         case CA_RELEASE:
170         case CA_ABORT:
171             break;
172         default:
173             OIC_LOG_V(ERROR, TAG, "Signaling code  %u is invalid", sig->code);
174             return NULL;
175     }
176
177     // allocate the signaling info structure.
178     CASignalingInfo_t *clone = (CASignalingInfo_t *) OICCalloc(1, sizeof(CASignalingInfo_t));
179     if (NULL == clone)
180     {
181         OIC_LOG(ERROR, TAG, "CACloneSignalingInfo Out of memory");
182         return NULL;
183     }
184
185     CAResult_t result = CACloneInfo(&sig->info, &clone->info);
186     if (CA_STATUS_OK != result)
187     {
188         OIC_LOG(ERROR, TAG, "CACloneResponseInfo error in CACloneInfo");
189         CADestroySignalingInfoInternal(clone);
190         return NULL;
191     }
192
193     clone->code = sig->code;
194     return clone;
195 }
196
197 CAEndpoint_t *CACreateEndpointObject(CATransportFlags_t flags,
198                                      CATransportAdapter_t adapter,
199                                      const char *address,
200                                      uint16_t port)
201 {
202     CAEndpoint_t *info = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t));
203     if (NULL == info)
204     {
205         OIC_LOG(ERROR, TAG, "Memory allocation failed !");
206         return NULL;
207     }
208
209     if (address)
210     {
211         OICStrcpy(info->addr, sizeof(info->addr), address);
212         info->addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0';
213     }
214     info->flags = flags;
215     info->adapter = adapter;
216     info->port = port;
217
218     return info;
219 }
220
221 void CAFreeEndpoint(CAEndpoint_t *rep)
222 {
223     OICFree(rep);
224 }
225
226 static void CADestroyInfoInternal(CAInfo_t *info)
227 {
228     // free token field
229     OICFree(info->token);
230     info->token = NULL;
231     info->tokenLength = 0;
232
233     // free options field
234     OICFree(info->options);
235     info->options = NULL;
236     info->numOptions = 0;
237
238     // free payload field
239     OICFree((char *) info->payload);
240     info->payload = NULL;
241     info->payloadSize = 0;
242
243     // free uri
244     OICFree(info->resourceUri);
245     info->resourceUri = NULL;
246 }
247
248 void CADestroyRequestInfoInternal(CARequestInfo_t *rep)
249 {
250     if (NULL == rep)
251     {
252         OIC_LOG(ERROR, TAG, "parameter is null");
253         return;
254     }
255
256     CADestroyInfoInternal(&rep->info);
257     OICFree(rep);
258 }
259
260 void CADestroyResponseInfoInternal(CAResponseInfo_t *rep)
261 {
262     if (NULL == rep)
263     {
264         OIC_LOG(ERROR, TAG, "parameter is null");
265         return;
266     }
267
268     CADestroyInfoInternal(&rep->info);
269     OICFree(rep);
270 }
271
272 void CADestroyErrorInfoInternal(CAErrorInfo_t *errorInfo)
273 {
274     if (NULL == errorInfo)
275     {
276         OIC_LOG(ERROR, TAG, "parameter is null");
277         return;
278     }
279
280     CADestroyInfoInternal(&errorInfo->info);
281     OICFree(errorInfo);
282 }
283
284 void CADestroySignalingInfoInternal(CASignalingInfo_t *sig)
285 {
286     if (NULL == sig)
287     {
288         OIC_LOG(ERROR, TAG, "parameter is null");
289         return;
290     }
291
292     CADestroyInfoInternal(&sig->info);
293     OICFree(sig);
294 }
295
296 CAResult_t CACloneInfo(const CAInfo_t *info, CAInfo_t *clone)
297 {
298     if (!info || !clone)
299     {
300         OIC_LOG(ERROR, TAG, "input parameter invalid");
301         return CA_STATUS_INVALID_PARAM;
302     }
303
304     memset(clone, 0 , sizeof(CAInfo_t));
305
306     //Do not free clone. we cannot declare it const, as the content is modified
307     if ((info->token) && (0 < info->tokenLength))
308     {
309         // allocate token field
310         uint8_t len = info->tokenLength;
311
312         char *temp = (char *) OICMalloc(len * sizeof(char));
313         if (!temp)
314         {
315             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
316             goto exit;
317         }
318
319         memcpy(temp, info->token, len);
320         // save the token
321         clone->token = temp;
322         clone->tokenLength = len;
323     }
324
325     if (info->options && (0 < info->numOptions))
326     {
327         // save the options
328         clone->options =
329             (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * info->numOptions);
330
331         if (!clone->options)
332         {
333             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
334             goto exit;
335         }
336         memcpy(clone->options, info->options, sizeof(CAHeaderOption_t) * info->numOptions);
337         clone->numOptions = info->numOptions;
338     }
339
340     memcpy(&(clone->identity), &(info->identity), sizeof(info->identity));
341
342     if ((info->payload) && (0 < info->payloadSize))
343     {
344         // allocate payload field
345         uint8_t *temp = OICMalloc(info->payloadSize);
346         if (!temp)
347         {
348             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
349             goto exit;
350         }
351         memcpy(temp, info->payload, info->payloadSize);
352
353         // save the payload
354         clone->payload = temp;
355         clone->payloadSize = info->payloadSize;
356     }
357     clone->payloadFormat = info->payloadFormat;
358     clone->acceptFormat = info->acceptFormat;
359     clone->payloadVersion = info->payloadVersion;
360     clone->acceptVersion = info->acceptVersion;
361
362     if (info->resourceUri)
363     {
364         // allocate payload field
365         char *temp = OICStrdup(info->resourceUri);
366         if (!temp)
367         {
368             OIC_LOG(ERROR, TAG, "CACloneInfo Out of memory");
369             goto exit;
370         }
371
372         // save the resourceUri
373         clone->resourceUri = temp;
374     }
375
376 #ifdef ROUTING_GATEWAY
377     clone->skipRetransmission = info->skipRetransmission;
378 #endif
379
380     clone->messageId = info->messageId;
381     clone->type = info->type;
382
383     return CA_STATUS_OK;
384
385 exit:
386     CADestroyInfoInternal(clone);
387     return CA_MEMORY_ALLOC_FAILED;
388 }