1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #include "oic_malloc.h"
26 #include "resourcemanager.h"
27 #include "psinterface.h"
28 #include "svcresource.h"
30 #include "srmresourcestrings.h"
31 #include "srmutility.h"
35 #define TAG PCF("SRM-SVC")
37 OicSecSvc_t *gSvc = NULL;
38 static OCResourceHandle gSvcHandle = NULL;
40 void DeleteSVCList(OicSecSvc_t* svc)
44 OicSecSvc_t *svcTmp1 = NULL, *svcTmp2 = NULL;
45 LL_FOREACH_SAFE(svc, svcTmp1, svcTmp2)
47 LL_DELETE(svc, svcTmp1);
50 OICFree(svcTmp1->owners);
52 // Clean SVC node itself
59 * This internal method converts SVC data into JSON format.
61 * Note: Caller needs to invoke 'free' when finished done using
64 char * BinToSvcJSON(const OicSecSvc_t * svc)
66 cJSON *jsonRoot = NULL;
71 jsonRoot = cJSON_CreateObject();
72 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
74 cJSON *jsonSvcArray = NULL;
75 cJSON_AddItemToObject (jsonRoot, OIC_JSON_SVC_NAME, jsonSvcArray = cJSON_CreateArray());
76 VERIFY_NON_NULL(TAG, jsonSvcArray, ERROR);
80 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
82 B64Result b64Ret = B64_OK;
84 cJSON *jsonSvc = cJSON_CreateObject();
86 // Service Device Identity
88 b64Ret = b64Encode(svc->svcdid.id, sizeof(OicUuid_t), base64Buff,
89 sizeof(base64Buff), &outLen);
90 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
91 cJSON_AddStringToObject(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID, base64Buff );
94 cJSON_AddNumberToObject (jsonSvc, OIC_JSON_SERVICE_TYPE, svc->svct);
97 cJSON *jsonOwnrArray = NULL;
98 cJSON_AddItemToObject (jsonSvc, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
99 VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
100 for (unsigned int i = 0; i < svc->ownersLen; i++)
104 b64Ret = b64Encode(svc->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
105 sizeof(base64Buff), &outLen);
106 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
108 cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
111 // Attach current svc node to Svc Array
112 cJSON_AddItemToArray(jsonSvcArray, jsonSvc);
116 jsonStr = cJSON_PrintUnformatted(jsonRoot);
122 cJSON_Delete(jsonRoot);
128 * This internal method converts JSON SVC into binary SVC.
130 OicSecSvc_t * JSONToSvcBin(const char * jsonStr)
132 OCStackResult ret = OC_STACK_ERROR;
133 OicSecSvc_t * headSvc = NULL;
134 OicSecSvc_t * prevSvc = NULL;
135 cJSON *jsonRoot = NULL;
136 cJSON *jsonSvcArray = NULL;
138 VERIFY_NON_NULL(TAG, jsonStr, ERROR);
140 jsonRoot = cJSON_Parse(jsonStr);
141 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
143 jsonSvcArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
144 VERIFY_NON_NULL(TAG, jsonSvcArray, INFO);
146 if (cJSON_Array == jsonSvcArray->type)
148 int numSvc = cJSON_GetArraySize(jsonSvcArray);
151 VERIFY_SUCCESS(TAG, numSvc > 0, INFO);
154 cJSON *jsonSvc = cJSON_GetArrayItem(jsonSvcArray, idx);
155 VERIFY_NON_NULL(TAG, jsonSvc, ERROR);
157 OicSecSvc_t *svc = (OicSecSvc_t*)OICCalloc(1, sizeof(OicSecSvc_t));
158 VERIFY_NON_NULL(TAG, svc, ERROR);
160 headSvc = (headSvc) ? headSvc : svc;
166 cJSON *jsonObj = NULL;
168 unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
170 B64Result b64Ret = B64_OK;
172 // Service Device Identity
173 jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID);
174 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
175 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
177 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
178 sizeof(base64Buff), &outLen);
179 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->svcdid.id)), ERROR);
180 memcpy(svc->svcdid.id, base64Buff, outLen);
183 jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_TYPE);
184 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
185 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
186 svc->svct = (OicSecSvcType_t)jsonObj->valueint;
189 jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_OWNERS_NAME);
190 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
191 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
193 svc->ownersLen = cJSON_GetArraySize(jsonObj);
194 VERIFY_SUCCESS(TAG, svc->ownersLen > 0, ERROR);
195 svc->owners = (OicUuid_t*)OICCalloc(svc->ownersLen, sizeof(OicUuid_t));
196 VERIFY_NON_NULL(TAG, (svc->owners), ERROR);
201 cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
202 VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
203 VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
206 b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
207 sizeof(base64Buff), &outLen);
209 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->owners[idxx].id)),
211 memcpy(svc->owners[idxx].id, base64Buff, outLen);
212 } while ( ++idxx < svc->ownersLen);
215 } while( ++idx < numSvc);
221 cJSON_Delete(jsonRoot);
222 if (OC_STACK_OK != ret)
224 DeleteSVCList(headSvc);
230 static OCEntityHandlerResult HandleSVCGetRequest (const OCEntityHandlerRequest * ehRequest)
232 // Convert SVC data into JSON for transmission
233 char* jsonStr = BinToSvcJSON(gSvc);
235 OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
237 // Send response payload to request originator
238 SendSRMResponse(ehRequest, ehRet, jsonStr);
242 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
246 static OCEntityHandlerResult HandleSVCPostRequest (const OCEntityHandlerRequest * ehRequest)
248 OCEntityHandlerResult ehRet = OC_EH_ERROR;
250 // Convert JSON SVC data into binary. This will also validate the SVC data received.
251 OicSecSvc_t* newSvc = JSONToSvcBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
255 // Append the new SVC to existing SVC
256 LL_APPEND(gSvc, newSvc);
258 // Convert SVC data into JSON for update to persistent storage
259 char *jsonStr = BinToSvcJSON(gSvc);
262 cJSON *jsonSvc = cJSON_Parse(jsonStr);
266 (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_SVC_NAME, jsonSvc)))
268 ehRet = OC_EH_RESOURCE_CREATED;
270 cJSON_Delete(jsonSvc);
274 // Send payload to request originator
275 SendSRMResponse(ehRequest, ehRet, NULL);
277 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
282 * This internal method is the entity handler for SVC resources and
283 * will handle REST request (GET/PUT/POST/DEL) for them.
285 OCEntityHandlerResult SVCEntityHandler (OCEntityHandlerFlag flag,
286 OCEntityHandlerRequest * ehRequest,
287 void* callbackParameter)
289 (void) callbackParameter;
290 OCEntityHandlerResult ehRet = OC_EH_ERROR;
297 if (flag & OC_REQUEST_FLAG)
299 switch (ehRequest->method)
302 ehRet = HandleSVCGetRequest(ehRequest);
306 ehRet = HandleSVCPostRequest(ehRequest);
311 SendSRMResponse(ehRequest, ehRet, NULL);
319 * This internal method is used to create '/oic/sec/svc' resource.
321 OCStackResult CreateSVCResource()
325 ret = OCCreateResource(&gSvcHandle,
326 OIC_RSRC_TYPE_SEC_SVC,
333 if (OC_STACK_OK != ret)
335 OC_LOG (FATAL, TAG, PCF("Unable to instantiate SVC resource"));
342 OCStackResult InitSVCResource()
344 OCStackResult ret = OC_STACK_ERROR;
346 OC_LOG_V (INFO, TAG, PCF("Begin %s "), __func__ );
348 // Read SVC resource from PS
349 char* jsonSVRDatabase = GetSVRDatabase();
353 // Convert JSON SVC into binary format
354 gSvc = JSONToSvcBin(jsonSVRDatabase);
355 OICFree(jsonSVRDatabase);
358 // Instantiate 'oic.sec.svc'
359 ret = CreateSVCResource();
361 if (OC_STACK_OK != ret)
366 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ret);
371 * Perform cleanup for SVC resources.
375 void DeInitSVCResource()
377 OCDeleteResource(gSvcHandle);