1 /* ****************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "CoapHttpMap.h"
23 #include "oic_malloc.h"
24 #include "oic_string.h"
28 #include "ocpayload.h"
32 int CHPGetOptionID(const char *httpOptionName)
36 OIC_LOG(ERROR, TAG, "HTTP option name is NULL");
40 OICStringToLower((char *)httpOptionName);
41 if (0 == strcmp(httpOptionName, HTTP_OPTION_CACHE_CONTROL) ||
42 0 == strcmp(httpOptionName, HTTP_OPTION_EXPIRES))
44 return COAP_OPTION_MAXAGE;
46 else if (0 == strcmp(httpOptionName, HTTP_OPTION_IF_MATCH))
48 return COAP_OPTION_IF_MATCH;
50 else if (0 == strcmp(httpOptionName, HTTP_OPTION_IF_NONE_MATCH))
52 return COAP_OPTION_IF_NONE_MATCH;
54 else if (0 == strcmp(httpOptionName, HTTP_OPTION_ETAG))
56 return COAP_OPTION_ETAG;
60 OIC_LOG_V(ERROR, TAG, "No Mapping found for %s", httpOptionName);
66 OCStackResult CHPGetOCCode(const HttpResponseResult_t httpCode, const OCMethod method,
67 OCEntityHandlerResult *ocfCode)
69 OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
70 OIC_LOG_V(DEBUG, TAG, "Http Code is %d", httpCode);
75 if (OC_REST_GET == method)
77 *ocfCode = OC_EH_CONTENT;
79 else if (OC_REST_DELETE == method)
81 *ocfCode = OC_EH_RESOURCE_DELETED;
85 *ocfCode = OC_EH_CHANGED;
89 if (OC_REST_DELETE == method)
91 *ocfCode = OC_EH_RESOURCE_DELETED;
95 *ocfCode = OC_EH_CHANGED;
99 *ocfCode = OC_EH_RESOURCE_CREATED;
101 case CHP_NOT_MODIFIED:
102 *ocfCode = OC_EH_VALID;
105 case CHP_REQUEST_URI_TOO_LARGE:
106 *ocfCode = OC_EH_BAD_REQ;
108 case CHP_BAD_GATEWAY:
109 case CHP_VERSION_NOT_SUPPORTED:
110 *ocfCode = OC_EH_BAD_GATEWAY;
112 case CHP_UNAUTHORIZED_REQ:
113 case CHP_FORBIDDEN_REQ:
115 case CHP_NOT_ACCEPTABLE:
116 case CHP_REQUEST_ENTITY_TOO_LARGE:
117 case CHP_UNSUPPORTED_MEDIA_TYPE:
118 case CHP_INTERNAL_SERVER_ERROR:
119 case CHP_NOT_IMPLEMENTED:
120 case CHP_SERVICE_UNAVAILABLE:
121 case CHP_GATEWAY_TIMEOUT:
125 OIC_LOG_V(ERROR, TAG, "HTTP Response code[%d] is not matching the OCF Response code",
127 return OC_STACK_ERROR;
130 OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
134 OCStackResult CHPGetOCOption(const HttpHeaderOption_t *httpOption, OCHeaderOption *ocfOption)
136 OIC_LOG(DEBUG, TAG, "CHPGetCoAPOption IN");
139 OIC_LOG(ERROR, TAG, "HTTP option is Null");
140 return OC_STACK_INVALID_PARAM;
143 ocfOption->optionID = CHPGetOptionID(httpOption->optionName);
144 if (!ocfOption->optionID)
146 OIC_LOG(INFO, TAG, "No match for HTTP option found");
147 return OC_STACK_INVALID_OPTION;
150 ocfOption->protocolID = OC_COAP_ID;
151 ocfOption->optionLength = httpOption->optionLength < sizeof(ocfOption->optionData) ?
152 httpOption->optionLength : sizeof(ocfOption->optionData);
153 memcpy(ocfOption->optionData, httpOption->optionData, ocfOption->optionLength);
155 OIC_LOG(DEBUG, TAG, "CHPGetCoAPOption OUT");
159 OCPayloadFormat CHPGetOCContentType(const char *httpContentType)
161 OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
163 OICStringToLower((char *)httpContentType);
164 if (strstr(httpContentType, CBOR_CONTENT_TYPE))
166 return OC_FORMAT_CBOR;
168 else if (strstr(httpContentType, JSON_CONTENT_TYPE))
170 return OC_FORMAT_JSON;
173 OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
174 return OC_FORMAT_UNSUPPORTED;
177 OCStackResult CHPGetHttpMethod(const OCMethod method, HttpMethod_t *httpMethod)
179 OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
184 *httpMethod = CHP_GET;
187 *httpMethod = CHP_PUT;
190 *httpMethod = CHP_POST;
193 *httpMethod = CHP_DELETE;
196 *httpMethod = CHP_INVALID;
197 OIC_LOG_V(ERROR, TAG, "Unknown method type %d", method);
198 return OC_STACK_INVALID_METHOD;
201 OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
205 OCStackResult CHPGetHttpOption(const OCHeaderOption* option, HttpHeaderOption_t** httpOption)
207 OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
210 OIC_LOG(ERROR, TAG, "option is NULL");
211 return OC_STACK_INVALID_PARAM;
214 *httpOption = (HttpHeaderOption_t *)OICCalloc(1, sizeof(HttpHeaderOption_t));
215 if (NULL == *httpOption)
217 OIC_LOG(ERROR, TAG, "Memory allocation failed");
218 return OC_STACK_NO_MEMORY;
221 switch (option->optionID)
223 case COAP_OPTION_ACCEPT:
224 OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
227 case COAP_OPTION_IF_MATCH:
228 OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
229 HTTP_OPTION_IF_MATCH);
231 case COAP_OPTION_IF_NONE_MATCH:
232 OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
233 HTTP_OPTION_IF_NONE_MATCH);
235 case COAP_OPTION_ETAG:
236 OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
239 case COAP_OPTION_CONTENT_TYPE:
240 OICStrcpy((*httpOption)->optionName, sizeof((*httpOption)->optionName),
241 HTTP_OPTION_CONTENT_TYPE);
244 OIC_LOG_V(INFO, TAG, "No Matching found for the ID %d", option->optionID);
247 if ('\0' == (*httpOption)->optionName[0])
249 OIC_LOG(ERROR, TAG, "No matching is found");
250 OICFree(*httpOption);
251 return OC_STACK_INVALID_OPTION;
254 (*httpOption)->optionLength = option->optionLength < sizeof((*httpOption)->optionData) ?
255 option->optionLength : sizeof((*httpOption)->optionData);
256 memcpy((*httpOption)->optionData, option->optionData, (*httpOption)->optionLength);
258 OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
262 void CHPJsonToRepPayload(cJSON* rootJSon, OCRepPayload* payload)
264 cJSON* dataJson = rootJSon->child;
267 switch (dataJson->type)
270 OCRepPayloadSetPropString(payload, dataJson->string, dataJson->valuestring);
273 if (dataJson->valueint == dataJson->valuedouble)
275 OCRepPayloadSetPropInt(payload, dataJson->string, dataJson->valueint);
279 OCRepPayloadSetPropDouble(payload, dataJson->string, dataJson->valuedouble);
283 OCRepPayloadSetPropBool(payload, dataJson->string, false);
286 OCRepPayloadSetPropBool(payload, dataJson->string, true);
290 OCRepPayload* childPayload = OCRepPayloadCreate();
291 CHPJsonToRepPayload(dataJson,childPayload);
292 OCRepPayloadSetPropObject(payload, dataJson->string,childPayload );
297 int size = cJSON_GetArraySize(dataJson);
298 size_t dimensions[MAX_REP_ARRAY_DEPTH];
299 dimensions[0] = size;
300 dimensions[1] = dimensions[2] = 0;
303 int type = cJSON_IsReference;
304 int numType = 0; // int:1, double:2
305 const int intType = 1;
306 const int doubleType = 2;
308 int64_t intArray[size];
309 double doubleArray[size];
310 char* strArray[size];
311 OCRepPayload* objPayloadArray[size];
313 for (; i < size ; ++i)
315 cJSON* subitem = cJSON_GetArrayItem(dataJson, i);
321 if ((type != cJSON_IsReference) && (type != subitem->type))
327 type = subitem->type;
331 if (subitem->valueint == subitem->valuedouble)
334 intArray[i] = (int64_t) subitem->valueint;
338 numType = doubleType;
339 doubleArray[i] = subitem->valuedouble;
343 strArray[i] = subitem->valuestring;
346 objPayloadArray[i] = OCRepPayloadCreate();
347 CHPJsonToRepPayload(subitem,objPayloadArray[i]);
350 OIC_LOG(ERROR, TAG, "wrong ArrayType in JsonToRepPayload()");
359 if (numType == intType)
361 OCRepPayloadSetIntArray(payload, dataJson->string,(const int64_t*)intArray,
364 else if (numType == doubleType)
366 OCRepPayloadSetDoubleArray(payload, dataJson->string,
367 (const double*)doubleArray,
372 OCRepPayloadSetStringArray(payload, dataJson->string,
373 (const char**)strArray,
377 OCRepPayloadSetPropObjectArray(payload, dataJson->string,
378 (const OCRepPayload**)objPayloadArray,
382 OIC_LOG(ERROR, TAG, "wrong ArrayType in JsonToRepPayload()");
388 dataJson = dataJson->next;
392 cJSON* CHPRepPayloadToJson(OCRepPayload* repData)
394 cJSON *outJson = cJSON_CreateObject();
400 OCRepPayloadValue* val = repData->values;
405 case OCREP_PROP_NULL:
408 OIC_LOG_V(DEBUG, TAG, "%s(int):%d", val->name, (int)val->i);
409 cJSON_AddNumberToObject(outJson,val->name,(int)val->i);
411 case OCREP_PROP_DOUBLE:
412 OIC_LOG_V(DEBUG, TAG, "%s(double):%f", val->name, val->d);
413 cJSON_AddNumberToObject(outJson,val->name,val->d);
415 case OCREP_PROP_BOOL:
416 OIC_LOG_V(DEBUG, TAG, "%s(bool):%s", val->name, val->b ? "true" : "false");
417 cJSON_AddBoolToObject(outJson,val->name,val->b);
419 case OCREP_PROP_STRING:
420 OIC_LOG_V(DEBUG, TAG, "%s(string):%s", val->name, val->str);
421 cJSON_AddStringToObject(outJson,val->name,val->str);
423 case OCREP_PROP_OBJECT:
425 cJSON *objJson = CHPRepPayloadToJson(val->obj);
428 cJSON_AddItemToObject(outJson,val->name,objJson);
432 case OCREP_PROP_ARRAY:
435 int arraySize = (int)val->arr.dimensions[0];
436 switch (val->arr.type)
439 OIC_LOG_V(DEBUG, TAG, "%s(int array)", val->name);
442 int castVal[val->arr.dimensions[0]];
443 for (i = 0 ; i < (unsigned int)arraySize ; i++)
445 castVal[i] = (int)val->arr.iArray[i];
447 cJSON *array = cJSON_CreateIntArray(castVal,arraySize);
450 cJSON_AddItemToObject(outJson,val->name,array);
454 case OCREP_PROP_DOUBLE:
455 OIC_LOG_V(DEBUG, TAG, "%s(double array)", val->name);
458 cJSON *array = cJSON_CreateDoubleArray(val->arr.dArray,arraySize);
461 cJSON_AddItemToObject(outJson,val->name,array);
465 case OCREP_PROP_STRING:
466 OIC_LOG_V(DEBUG, TAG, "%s(string array)", val->name);
469 cJSON *array = cJSON_CreateStringArray((const char**)val->arr.strArray,
473 cJSON_AddItemToObject(outJson,val->name,array);
477 case OCREP_PROP_OBJECT:
480 cJSON *arrayJson = cJSON_CreateArray();
481 for (i = 0 ; i < (unsigned int)arraySize ; i++)
483 cJSON *objJson = CHPRepPayloadToJson(val->arr.objArray[i]);
484 if (objJson != NULL && arrayJson != NULL)
486 cJSON_AddItemToArray(arrayJson, objJson);
489 if (arrayJson != NULL)
491 cJSON_AddItemToObject(outJson,val->name,arrayJson);
495 case OCREP_PROP_BOOL:
496 //TODO : Not support - cJSON_CreateBoolArray
499 OIC_LOG_V(ERROR, TAG, "Unknown/unsupported array type: %s", val->name);
505 OIC_LOG_V(ERROR, TAG, "Unknown type: %s", val->name);
511 if( repData->values != NULL)
517 cJSON_Delete(outJson);