1 //******************************************************************
3 // Copyright 2015 Samsung Electronics 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 #include "rd_server.h"
22 #include "rd_database.h"
25 #include "payload_logging.h"
26 #include "ocpayload.h"
28 #include "oic_string.h"
30 #define TAG PCF("OIC_RD_SERVER")
34 // This is temporary hardcoded value for bias factor.
35 static const int OC_RD_DISC_SEL = 100;
37 static OCResourceHandle rdHandle;
39 static OCStackResult sendResponse(const OCEntityHandlerRequest *ehRequest, OCRepPayload *rdPayload,
40 OCEntityHandlerResult ehResult)
42 OCEntityHandlerResponse response = { 0 };
43 response.requestHandle = ehRequest->requestHandle;
44 response.resourceHandle = ehRequest->resource;
45 response.ehResult = ehResult;
46 response.payload = (OCPayload*)(rdPayload);
47 return OCDoResponse(&response);
51 * This internal method handles RD discovery request.
52 * Responds with the RD discovery payload message.
54 static OCEntityHandlerResult handleGetRequest(const OCEntityHandlerRequest *ehRequest)
58 OIC_LOG(DEBUG, TAG, "Invalid request pointer.");
62 OCEntityHandlerResult ehResult = OC_EH_OK;
63 OIC_LOG_V(DEBUG, TAG, "Received OC_REST_GET from client with query: %s.", ehRequest->query);
65 OCRepPayload *rdPayload = (OCRepPayload *)OCRepPayloadCreate();
68 return OC_STACK_NO_MEMORY;
71 const char *id = OCGetServerInstanceIDString();
74 OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_ID, id);
76 OCRepPayloadSetPropInt(rdPayload, OC_RSRVD_RD_DISCOVERY_SEL, OC_RD_DISC_SEL);
78 OCRepPayloadAddResourceType(rdPayload, OC_RSRVD_RESOURCE_TYPE_RD);
79 OCRepPayloadAddResourceType(rdPayload, OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
81 OCRepPayloadAddInterface(rdPayload, OC_RSRVD_INTERFACE_DEFAULT);
83 OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
85 if (sendResponse(ehRequest, rdPayload, OC_EH_OK) != OC_STACK_OK)
87 OIC_LOG(ERROR, TAG, "Sending response failed.");
88 ehResult = OC_EH_ERROR;
95 * This internal method handles RD publish request.
96 * Responds with the RD success message.
98 static OCEntityHandlerResult handlePublishRequest(const OCEntityHandlerRequest *ehRequest)
100 OCEntityHandlerResult ehResult = OC_EH_OK;
104 OIC_LOG(DEBUG, TAG, "Invalid request pointer");
108 OIC_LOG_V(DEBUG, TAG, "Received OC_REST_POST from client with query: %s.", ehRequest->query);
110 OCRepPayload *payload = (OCRepPayload *)ehRequest->payload;
111 OCRepPayload *resPayload = NULL;
114 OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) payload);
115 if (OCRDDatabaseInit(NULL) == OC_STACK_OK)
117 if (OCRDDatabaseStoreResources(payload, &ehRequest->devAddr) == OC_STACK_OK)
119 OIC_LOG_V(DEBUG, TAG, "Stored resources.");
120 resPayload = payload;
125 resPayload = (OCRepPayload *)OCRepPayloadCreate();
126 ehResult = OC_EH_ERROR;
131 if (sendResponse(ehRequest, resPayload, ehResult) != OC_STACK_OK)
133 OIC_LOG(ERROR, TAG, "Sending response failed.");
140 static OCEntityHandlerResult handleDeleteRequest(const OCEntityHandlerRequest *ehRequest)
142 OCEntityHandlerResult ehResult = OC_EH_ERROR;
145 char *queryDup = NULL;
146 char *restOfQuery = NULL;
147 char *keyValuePair = NULL;
154 OIC_LOG(DEBUG, TAG, "Invalid request pointer");
158 OIC_LOG_V(DEBUG, TAG, "Received OC_REST_DELETE from client with query: %s.", ehRequest->query);
160 if (OCRDDatabaseInit(NULL) != OC_STACK_OK)
165 #define OC_RSRVD_INS_KEY OC_RSRVD_INS OC_KEY_VALUE_DELIMITER /* "ins=" */
166 keyValuePair = strstr(ehRequest->query, OC_RSRVD_INS_KEY);
170 keyValuePair = strstr(keyValuePair + sizeof(OC_RSRVD_INS_KEY), OC_RSRVD_INS_KEY);
174 ins = OICMalloc(nIns * sizeof(uint8_t));
177 OIC_LOG_V(ERROR, TAG, "ins is NULL");
183 queryDup = OICStrdup(ehRequest->query);
184 if (NULL == queryDup)
186 OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
189 keyValuePair = strtok_r(queryDup, OC_QUERY_SEPARATOR, &restOfQuery);
192 key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
195 OIC_LOG_V(ERROR, TAG, "Invalid query parameter!");
198 else if (strncasecmp(key, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1) == 0)
202 else if (strncasecmp(key, OC_RSRVD_INS, sizeof(OC_RSRVD_INS) - 1) == 0)
205 long int i = strtol(value, &endptr, 0);
206 if (*endptr != '\0' || i < 0 || i > UINT8_MAX)
208 OIC_LOG_V(ERROR, TAG, "Invalid ins query parameter: %s", value);
214 keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
218 OIC_LOG_V(ERROR, TAG, "Missing required di query parameter!");
222 if (OCRDDatabaseDeleteResources(di, ins, nIns) == OC_STACK_OK)
224 OIC_LOG_V(DEBUG, TAG, "Deleted resource(s).");
231 if (sendResponse(ehRequest, NULL, ehResult) != OC_STACK_OK)
233 OIC_LOG(ERROR, TAG, "Sending response failed.");
239 * This internal method is the entity handler for RD resources and
240 * will handle REST request (GET/PUT/POST/DEL) for them.
242 static OCEntityHandlerResult rdEntityHandler(OCEntityHandlerFlag flag,
243 OCEntityHandlerRequest *ehRequest, OC_ANNOTATE_UNUSED void *callbackParameter)
245 OCEntityHandlerResult ehRet = OC_EH_ERROR;
252 if (flag & OC_REQUEST_FLAG)
254 OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG.");
255 switch (ehRequest->method)
258 case OC_REST_DISCOVER:
259 ehRet = handleGetRequest(ehRequest);
262 ehRet = handlePublishRequest(ehRequest);
265 ehRet = handleDeleteRequest(ehRequest);
268 case OC_REST_OBSERVE:
269 case OC_REST_OBSERVE_ALL:
270 case OC_REST_PRESENCE:
271 case OC_REST_NOMETHOD:
280 * Registers RD resource
282 OCStackResult OCRDStart()
284 OCStackResult result = OCCreateResource(&rdHandle,
285 OC_RSRVD_RESOURCE_TYPE_RD,
286 OC_RSRVD_INTERFACE_DEFAULT,
290 (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE));
292 if (result == OC_STACK_OK)
294 OIC_LOG(DEBUG, TAG, "Resource Directory resource created.");
298 OIC_LOG(ERROR, TAG, "Failed creating Resource Directory resource.");
301 result = OCBindResourceTypeToResource(rdHandle,
302 OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
303 if (result == OC_STACK_OK)
305 OIC_LOG(DEBUG, TAG, "Resource Directory resource Publish created.");
309 OIC_LOG(ERROR, TAG, "Failed creating Resource Directory Publish resource.");
316 * Stops resource directory server
318 OCStackResult OCRDStop()
322 OIC_LOG(ERROR, TAG, "Resource Directory resource handle is not initialized.");
323 return OC_STACK_NO_RESOURCE;
326 OCStackResult result = OCDeleteResource(rdHandle);
328 if (result == OC_STACK_OK)
330 OIC_LOG(DEBUG, TAG, "Resource Directory resource deleted.");
334 OIC_LOG(ERROR, TAG, "Resource Directory resource not deleted.");