1 //******************************************************************
3 // Copyright 2014 Intel Corporation All Rights Reserved.
4 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
11 #include "ocstackinternal.h"
12 #include "ocserverrequest.h"
13 #include "occlientcb.h"
20 //-----------------------------------------------------------------------------
22 //-----------------------------------------------------------------------------
24 OC_STACK_UNINITIALIZED = 0, OC_STACK_INITIALIZED
27 //-----------------------------------------------------------------------------
29 //-----------------------------------------------------------------------------
30 static OCStackState stackState = OC_STACK_UNINITIALIZED;
31 OCResource *headResource = NULL;
33 //-----------------------------------------------------------------------------
35 //-----------------------------------------------------------------------------
36 #define TAG PCF("OCStack")
37 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
38 TAG, PCF(#arg " is NULL")); return (retVal); } }
40 //-----------------------------------------------------------------------------
41 // Internal API function
42 //-----------------------------------------------------------------------------
44 //This function will be called back by occoap layer when a request is received
45 OCStackResult OCStackHandleReceiveRequest(OCRequest * request) {
46 OC_LOG(INFO, TAG, "Entering OCStackHandleReceiveRequest (OCStack Layer)");
52 VERIFY_NON_NULL(request, ERROR, OC_STACK_ERROR);
53 VERIFY_NON_NULL(request->entityHandlerRequest, ERROR, OC_STACK_ERROR);
55 result = validateUrlQuery(request->resourceUrl, request->query, &filterOn,
58 if (OC_STACK_OK != result) {
62 result = processResourceDiscoverReq(
63 request->entityHandlerRequest->reqJSONPayload,
64 request->entityHandlerRequest->resJSONPayload, filterOn,
67 if (OC_STACK_OK != result) {
71 // TODO: lookup and service the resource
72 // TODO: call the entity handler
73 // for now just do this
74 //sprintf((char *) request->entityHandlerRequest->resJSONPayload,
75 // "Thank you, I got it!!!");
79 //This function will be called back by occoap layer when a response is received
80 void OCStackHandleReceiveResponse(OCResponse * response) {
81 ClientCB * cbNode = NULL;
82 OCStackApplicationResult result = OC_STACK_DELETE_TRANSACTION;
83 OC_LOG(INFO, TAG, "Entering OCHandleClientReceiveResponse (OCStack Layer)");
84 if (response->clientResponse->result != OC_STACK_OK) {
85 OC_LOG(DEBUG, TAG, "There is a problem in OCSTACK in OCStackHandleReceiveResponseeeeeeeeeeeeeeeeee");
88 cbNode = GetClientCB(response->token);
90 OC_LOG(INFO, TAG, PCF("Calling into application address space"));
91 result = cbNode->callBack(cbNode->context, response->clientResponse);
92 if (result == OC_STACK_DELETE_TRANSACTION) {
93 DeleteClientCB(cbNode);
95 }TODO ("What does the stack does in case of error");
98 //-----------------------------------------------------------------------------
99 // Private internal function prototypes
100 //-----------------------------------------------------------------------------
101 // TODO: ultimately OCMalloc and OCFree should be defined in a different module
102 static void *OCMalloc(size_t size);
103 static void OCFree(void *ptr);
105 static void initResources();
106 static void insertResource(OCResource *resource);
107 static OCResource *findResource(OCResource *resource);
108 static void insertResourceType(OCResource *resource,
109 OCResourceType *resourceType);
110 static OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle,
112 static void insertResourceInterface(OCResource *resource,
113 OCResourceInterface *resourceInterface);
114 static OCResourceInterface *findResourceInterfaceAtIndex(
115 OCResourceHandle handle, uint8_t index);
116 static void deleteResourceType(OCResourceType *resourceType);
117 static void deleteResourceInterface(OCResourceInterface *resourceInterface);
118 static void deleteResourceElements(OCResource *resource);
119 static int deleteResource(OCResource *resource);
121 //-----------------------------------------------------------------------------
122 // Default resource entity handler function
123 //-----------------------------------------------------------------------------
124 void defaultResourceEHandler(OCEntityHandlerFlag flag,
125 OCEntityHandlerRequest * request) {
126 TODO ("Implement me!!!!");
127 // TODO: remove silence unused param warnings
132 //-----------------------------------------------------------------------------
134 //-----------------------------------------------------------------------------
137 * Initialize the OC Stack. Must be called prior to starting the stack.
140 * IP Address of host device
142 * Port of host device
144 * Host device is client, server, or client-server
147 * OC_STACK_OK - no errors
148 * OC_STACK_ERROR - stack init error
150 OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode) {
151 OC_LOG(INFO, TAG, PCF("Entering OCInit"));
154 OC_LOG_V(INFO, TAG, "IP Address = %s", ipAddr);
159 OC_LOG(INFO, TAG, PCF("Client mode"));
162 OC_LOG(INFO, TAG, PCF("Server mode"));
164 case OC_CLIENT_SERVER:
165 OC_LOG(INFO, TAG, PCF("Client-server mode"));
168 OC_LOG(ERROR, TAG, PCF("Invalid mode"));
169 return OC_STACK_ERROR;
173 // Initialize resource
176 // Make call to OCCoAP layer
177 if (OCInitCoAP(ipAddr, (uint16_t) port, mode) == 0) {
178 stackState = OC_STACK_INITIALIZED;
182 OC_LOG(ERROR, TAG, PCF("Stack initialization error"));
183 return OC_STACK_ERROR;
187 * Stop the OC stack. Use for a controlled shutdown.
189 * OC_STACK_OK - no errors
190 * OC_STACK_ERROR - stack not initialized
192 OCStackResult OCStop() {
193 OC_LOG(INFO, TAG, PCF("Entering OCStop"));
195 if (stackState != OC_STACK_INITIALIZED) {
196 OC_LOG(ERROR, TAG, PCF("Stack not initialized"));
197 return OC_STACK_ERROR;
200 // Make call to OCCoAP layer
201 if (OCStopCoAP() == 0) {
202 // Remove all the client callbacks
203 DeleteClientCBList();
204 stackState = OC_STACK_UNINITIALIZED;
208 OC_LOG(ERROR, TAG, PCF("Stack stop error"));
209 return OC_STACK_ERROR;
213 * Discover OC resources.
215 * @param method - method to perform on the resource
216 * @param requiredUri - URI of the resource to interact with
217 * @param referenceUri - URI of the reference resource
218 * @param request - JSON encoded request
219 * @param qos - quality of service
220 * @param asyncApplicationCB - asynchronous callback function that is invoked
221 * by the stack when discovery or resource interaction is complete
224 * OC_STACK_OK - no errors
225 * OC_STACK_INVALID_CALLBACK - invalid callback function pointer
226 * OC_STACK_INVALID_METHOD - invalid resource method
227 * OC_STACK_INVALID_URI - invalid required or reference URI
230 OCStackResult OCDoResource(OCMethod method, const char *requiredUri,
231 const char *referenceUri, const char *request, OCQualityOfService qos,
232 // OCClientApplicationCBType clientApplicationCB) {
233 OCCallbackData *cbData) {
237 // TODO: Remove silence unused parameter warnings.
241 OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
243 // TODO: Eventually, we want to allow for the caller to pass a null on the callback function.
244 // For now however, ensure that the callback is valid
245 // Storing the return function here, used later to call back the application
246 if (!cbData || !cbData->cb) {
247 return OC_STACK_INVALID_CALLBACK;
250 // Generate token here, it will be deleted when the transaction is deleted
251 token = (OCToken *) malloc(sizeof(OCToken));
252 token->tokenLength = MAX_TOKEN_LENGTH;
253 OCFillRandomMem(token->token, token->tokenLength);
254 OC_LOG_V(INFO,TAG,"Token generated %d bytes..........%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
255 token->tokenLength,token->token[0],token->token[1],token->token[2],token->token[3],
256 token->token[4],token->token[5],token->token[6],token->token[7]);
258 // TODO: Form and insert transaction structure
259 // for now just store it here
260 //storedCB = clientApplicationCB;
263 if (method != OC_REST_GET) {
264 return OC_STACK_INVALID_METHOD;
267 TODO ("Need to form the final query by concatenating require and reference URI's");
268 // Validate required URI
269 VERIFY_NON_NULL(requiredUri, FATAL, OC_STACK_INVALID_URI);
271 // Make call to OCCoAP layer
272 if (OCDoCoAPResource(method, qos, token, requiredUri) == OC_COAP_OK) {
273 OC_LOG(INFO, TAG, "Done with this function");
274 AddClientCB(cbData, token);
278 OC_LOG(ERROR, TAG, PCF("Stack stop error"));
279 return OC_STACK_ERROR;
283 * Called in main loop of OC client or server. Allows low-level processing of
287 * OC_STACK_OK - no errors
288 * OC_STACK_ERROR - stack process error
290 OCStackResult OCProcess() {
292 OC_LOG(INFO, TAG, PCF("Entering OCProcess"));
300 * @param handle - pointer to handle to newly created resource. Set by ocstack. Used to refer to resource
301 * @param resourceTypeName - name of resource type. Example: "core.led"
302 * @param resourceAttributeRepresentation - attribute representation. list of attributes:type, with each pair
303 * separated by semicolons. Example: "state:oc.bt.b;power:oc.bt.i"
304 * @param resourceInterfaceName - name of resource interface. Example: "core.rw"
305 * @param allowedMethods - methods permitted on interface. Example: OC_REST_GET|OC_REST_PUT
306 * @param uri - URI of the resource. Example: "/a/led"
307 * @param entityHandler - entity handler function that is called by ocstack to handle requests, etc
308 * @param resourceProperties - properties supported by resource. Example: OC_DISCOVERABLE|OC_OBSERVABLE
311 * OC_STACK_OK - no errors
312 * OC_STACK_ERROR - stack process error
314 OCStackResult OCCreateResource(OCResourceHandle *handle,
315 const char *resourceTypeName,
316 const char *resourceAttributeRepresentation,
317 const char *resourceInterfaceName, uint8_t allowedMethods,
318 const char *uri, OCEntityHandler entityHandler,
319 uint8_t resourceProperties) {
321 OCResource *pointer = NULL;
324 OCStackResult result = OC_STACK_ERROR;
326 OC_LOG(INFO, TAG, PCF("Entering OCCreateResource"));
328 // Validate parameters
329 // TODO: Does resource attribute representation really have to be maintained in stack?
330 // Is it presented during resource discovery?
331 // VERIFY_NON_NULL(resourceAttributeRepresentation, ERROR, OC_STACK_ERROR);
332 if (!handle || !resourceTypeName || !resourceInterfaceName || !uri) {
333 OC_LOG(ERROR, TAG, PCF("Input parameter is NULL"));
334 return OC_STACK_INVALID_PARAM;
337 // Make sure allowedMethods bitmask has allowed methods specified
339 > (OC_REST_GET | OC_REST_PUT | OC_REST_POST | OC_REST_DELETE
341 || (allowedMethods == OC_REST_NOMETHOD)) {
342 OC_LOG(ERROR, TAG, PCF("Invalid method"));
343 return OC_STACK_INVALID_PARAM;
346 // Make sure resourceProperties bitmask has allowed properties specified
347 if (resourceProperties
348 > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW)) {
349 OC_LOG(ERROR, TAG, PCF("Invalid property"));
350 return OC_STACK_INVALID_PARAM;
353 // If the headResource is NULL, then no resources have been created...
354 pointer = headResource;
356 // At least one resources is in the resource list, so we need to search for
357 // repeated URLs, which are not allowed. If a repeat is found, exit with an error
359 if (strcmp(uri, pointer->uri) == 0) {
360 OC_LOG(ERROR, TAG, PCF("URI already in use"));
361 return OC_STACK_INVALID_PARAM;
363 pointer = pointer->next;
366 // Create the pointer and insert it into the resource list
367 pointer = (OCResource *) OCMalloc(sizeof(OCResource));
371 memset(pointer, 0, sizeof(OCResource));
373 insertResource(pointer);
376 size = strlen(uri) + 1;
377 str = (char *) OCMalloc(size);
381 strncpy(str, uri, size);
384 // Set properties. Set OC_ACTIVE
385 pointer->resourceProperties = resourceProperties | OC_ACTIVE;
387 // Add the resourcetype to the resource
388 result = OCBindResourceTypeToResource((OCResourceHandle) pointer,
389 resourceTypeName, resourceAttributeRepresentation);
390 if (result != OC_STACK_OK) {
391 OC_LOG(ERROR, TAG, PCF("Error adding resourcetype"));
395 // Add the resourceinterface to the resource
396 result = OCBindResourceInterfaceToResource((OCResourceHandle) pointer,
397 resourceInterfaceName, allowedMethods);
398 if (result != OC_STACK_OK) {
399 OC_LOG(ERROR, TAG, PCF("Error adding resourceinterface"));
404 result = OC_STACK_OK;
406 exit: if (result != OC_STACK_OK) {
414 * Add a resource to a container resource.
416 * @param containerHandle - handle to the container resource
417 * @param addedResourceHandle - handle to resource to be added to the container resource
420 * OC_STACK_OK - no errors
421 * OC_STACK_ERROR - stack process error
423 OCStackResult OCBindContainedResourceToResource(
424 OCResourceHandle containerHandle, OCResourceHandle addedResourceHandle) {
425 OCResource *resource;
428 OC_LOG(INFO, TAG, PCF("Entering OCBindContainedResourceToResource"));
430 // Validate parameters
431 VERIFY_NON_NULL(containerHandle, ERROR, OC_STACK_ERROR);
432 VERIFY_NON_NULL(addedResourceHandle, ERROR, OC_STACK_ERROR);
433 // Container cannot contain itself
434 if (containerHandle == addedResourceHandle) {
435 OC_LOG(ERROR, TAG, PCF("Added handle equals container handle"));
436 return OC_STACK_INVALID_PARAM;
439 // Use the handle to find the resource in the resource linked list
440 resource = findResource(containerHandle);
442 OC_LOG(ERROR, TAG, PCF("Resource not found"));
443 return OC_STACK_INVALID_PARAM;
446 // Look for an open slot to add add the child resource.
447 // If found, add it and return success
448 for (i = 0; i < MAX_CONTAINED_RESOURCES; i++) {
449 if (!resource->rsrcResources[i]) {
450 resource->rsrcResources[i] = addedResourceHandle;
451 OC_LOG(INFO, TAG, PCF("resource bound"));
456 // Unable to add addedResourceHandle, so return error
457 return OC_STACK_ERROR;
461 * Bind a resourcetype to a resource.
463 * @param handle - handle to the container resource
464 * @param resourceTypeName - name of resource type. Example: "core.led"
465 * @param resourceAttributeRepresentation - attribute representation. list of attributes:type, with each pair
466 * separated by semicolons. Example: "state:oc.bt.b;power:oc.bt.i"
469 * OC_STACK_OK - no errors
470 * OC_STACK_ERROR - stack process error
472 OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle,
473 const char *resourceTypeName,
474 const char *resourceAttributeRepresentation) {
476 OCResourceType *pointer = NULL;
479 OCResource *resource;
480 OCStackResult result = OC_STACK_ERROR;
482 OC_LOG(INFO, TAG, PCF("Entering OCBindResourceTypeToResource"));
484 // Validate parameters
485 VERIFY_NON_NULL(resourceTypeName, ERROR, OC_STACK_INVALID_PARAM);
486 // TODO: Does resource attribute resentation really have to be maintained in stack?
487 // Is it presented during resource discovery?
488 // VERIFY_NON_NULL(resourceAttributeRepresentation, ERROR, OC_STACK_ERROR);
490 // Make sure resource exists
491 resource = findResource((OCResource *) handle);
493 OC_LOG(ERROR, TAG, PCF("Resource not found"));
494 return OC_STACK_ERROR;
497 TODO ("Make sure that the resourcetypename doesn't already exist in the resource");
499 // Create the resourcetype and insert it into the resource list
500 pointer = (OCResourceType *) OCMalloc(sizeof(OCResourceType));
504 memset(pointer, 0, sizeof(OCResourceType));
506 // Set the resourceTypeName
507 size = strlen(resourceTypeName) + 1;
508 str = (char *) OCMalloc(size);
512 strncpy(str, resourceTypeName, size);
513 pointer->resourcetypename = str;
515 // If the resourceAttributeRepresentation is defined, add it.
516 if (resourceAttributeRepresentation) {
517 size = strlen(resourceAttributeRepresentation) + 1;
518 str = (char *) OCMalloc(size);
522 strncpy(str, resourceAttributeRepresentation, size);
523 pointer->typerepresentation = str;
525 // Bind the resourcetype to the resource
526 insertResourceType(resource, pointer);
528 result = OC_STACK_OK;
530 exit: if (result != OC_STACK_OK) {
538 * Bind a resourceinterface to a resource.
540 * @param handle - handle to the container resource
541 * @param resourceInterfaceName - name of resource interface. Example: "core.rw"
542 * @param allowedMethods - methods permitted on interface. Example: OC_REST_GET|OC_REST_PUT
545 * OC_STACK_OK - no errors
546 * OC_STACK_ERROR - stack process error
548 OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
549 const char *resourceInterfaceName, uint8_t allowedMethods) {
551 OCResourceInterface *pointer = NULL;
554 OCResource *resource;
555 OCStackResult result = OC_STACK_ERROR;
557 OC_LOG(INFO, TAG, PCF("Entering OCBindResourceInterfaceToResource"));
559 // Validate parameters
560 VERIFY_NON_NULL(resourceInterfaceName, ERROR, OC_STACK_INVALID_PARAM);
562 // Make sure allowedMethods bitmask has allowed methods specified
564 > (OC_REST_GET | OC_REST_PUT | OC_REST_POST | OC_REST_DELETE
566 || (allowedMethods == OC_REST_NOMETHOD)) {
567 OC_LOG(ERROR, TAG, PCF("Invalid method"));
568 return OC_STACK_INVALID_PARAM;
571 // Make sure resource exists
572 resource = findResource((OCResource *) handle);
574 OC_LOG(ERROR, TAG, PCF("Resource not found"));
575 return OC_STACK_INVALID_PARAM;
578 TODO ("Make sure that the resourceinterface name doesn't already exist in the resource");
580 // Create the resourceinterface and insert it into the resource list
581 pointer = (OCResourceInterface *) OCMalloc(sizeof(OCResourceInterface));
585 memset(pointer, 0, sizeof(OCResourceInterface));
587 // Set the resourceinterface name
588 size = strlen(resourceInterfaceName) + 1;
589 str = (char *) OCMalloc(size);
593 strncpy(str, resourceInterfaceName, size);
596 pointer->allowedMethods = allowedMethods;
598 // Bind the resourceinterface to the resource
599 insertResourceInterface(resource, pointer);
601 result = OC_STACK_OK;
602 exit: if (result != OC_STACK_OK) {
610 * Get the number of resources that have been created in the stack.
612 * @param numResources - pointer to count variable
615 * OC_STACK_OK - no errors
616 * OC_STACK_ERROR - stack process error
619 OCStackResult OCGetNumberOfResources(uint8_t *numResources) {
620 OCResource *pointer = headResource;
622 OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResources"));
623 VERIFY_NON_NULL(numResources, ERROR, OC_STACK_INVALID_PARAM);
626 *numResources = *numResources + 1;
627 pointer = pointer->next;
633 * Get a resource handle by index.
635 * @param index - index of resource, 0 to Count - 1
638 * Resource handle - if found
639 * NULL - if not found
641 OCResourceHandle OCGetResourceHandle(uint8_t index) {
642 OCResource *pointer = headResource;
645 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandle"));
647 // Iterate through the list
648 while ((i < index) && pointer) {
650 pointer = pointer->next;
652 return (OCResourceHandle) pointer;
656 * Delete resource specified by handle. Deletes resource and all resourcetype and resourceinterface
659 * @param handle - handle of resource to be deleted
662 * OC_STACK_OK - no errors
663 * OC_STACK_ERROR - stack process error
665 OCStackResult OCDeleteResource(OCResourceHandle handle) {
666 OC_LOG(INFO, TAG, PCF("Entering OCDeleteResource"));
669 OC_LOG(ERROR, TAG, PCF("Resource not found"));
670 return OC_STACK_INVALID_PARAM;
673 if (deleteResource((OCResource *) handle) == 0) {
674 OC_LOG(ERROR, TAG, PCF("Error deleting resource"));
675 return OC_STACK_ERROR;
682 * Get the URI of the resource specified by handle.
684 * @param handle - handle of resource
686 * URI string - if resource found
687 * NULL - resource not found
689 const char *OCGetResourceUri(OCResourceHandle handle) {
690 OCResource *resource;
691 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceUri"));
693 resource = findResource((OCResource *) handle);
695 return resource->uri;
697 return (const char *) NULL;
701 * Get the properties of the resource specified by handle.
702 * NOTE: that after a resource is created, the OC_ACTIVE property is set
703 * for the resource by the stack.
705 * @param handle - handle of resource
707 * property bitmap - if resource found
708 * NULL - resource not found
710 uint8_t OCGetResourceProperties(OCResourceHandle handle) {
711 OCResource *resource;
712 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceProperties"));
714 resource = findResource((OCResource *) handle);
716 return resource->resourceProperties;
722 * Get the number of resource types of the resource.
724 * @param handle - handle of resource
725 * @param numResourceTypes - pointer to count variable
728 * OC_STACK_OK - no errors
729 * OC_STACK_ERROR - stack process error
731 OCStackResult OCGetNumberOfResourceTypes(OCResourceHandle handle,
732 uint8_t *numResourceTypes) {
733 OCResource *resource;
734 OCResourceType *pointer;
736 OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceTypes"));
737 VERIFY_NON_NULL(numResourceTypes, ERROR, OC_STACK_INVALID_PARAM);
738 VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
740 *numResourceTypes = 0;
742 resource = findResource((OCResource *) handle);
744 pointer = resource->rsrcType;
746 *numResourceTypes = *numResourceTypes + 1;
747 pointer = pointer->next;
754 * Get name of resource type of the resource.
756 * @param handle - handle of resource
757 * @param index - index of resource, 0 to Count - 1
760 * resource type name - if resource found
761 * NULL - resource not found
763 const char *OCGetResourceTypeName(OCResourceHandle handle, uint8_t index) {
764 OCResourceType *resourceType;
766 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceTypeName"));
768 resourceType = findResourceTypeAtIndex(handle, index);
770 return resourceType->resourcetypename;
772 return (const char *) NULL;
776 * Get attributes of resource type of the resource.
778 * @param handle - handle of resource
779 * @param index - index of resource, 0 to Count - 1
782 * resource type attributes - if resource found
783 * NULL - resource not found
785 const char *OCGetResourceAttributeRepresentation(OCResourceHandle handle,
787 OCResourceType *resourceType;
789 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceAttributeRepresentation"));
791 resourceType = findResourceTypeAtIndex(handle, index);
793 return resourceType->typerepresentation;
795 return (const char *) NULL;
799 * Get the number of resource interfaces of the resource.
801 * @param handle - handle of resource
802 * @param numResources - pointer to count variable
805 * OC_STACK_OK - no errors
806 * OC_STACK_ERROR - stack process error
809 OCStackResult OCGetNumberOfResourceInterfaces(OCResourceHandle handle,
810 uint8_t *numResourceInterfaces) {
811 OCResourceInterface *pointer;
812 OCResource *resource;
814 OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceInterfaces"));
816 VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
817 VERIFY_NON_NULL(numResourceInterfaces, ERROR, OC_STACK_INVALID_PARAM);
819 *numResourceInterfaces = 0;
820 resource = findResource((OCResource *) handle);
822 pointer = resource->rsrcInterface;
824 *numResourceInterfaces = *numResourceInterfaces + 1;
825 pointer = pointer->next;
832 * Get name of resource interface of the resource.
834 * @param handle - handle of resource
835 * @param index - index of resource, 0 to Count - 1
838 * resource interface name - if resource found
839 * NULL - resource not found
841 const char *OCGetResourceInterfaceName(OCResourceHandle handle, uint8_t index) {
842 OCResourceInterface *resourceInterface;
844 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceInterfaceName"));
846 resourceInterface = findResourceInterfaceAtIndex(handle, index);
847 if (resourceInterface) {
848 return resourceInterface->name;
850 return (const char *) NULL;
854 * Get methods of resource interface of the resource.
856 * @param handle - handle of resource
857 * @param index - index of resource, 0 to Count - 1
860 * allowed methods - if resource found
861 * NULL - resource not found
863 uint8_t OCGetResourceInterfaceAllowedMethods(OCResourceHandle handle,
865 OCResourceInterface *resourceInterface;
867 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceInterfaceAllowedMethods"));
869 resourceInterface = findResourceInterfaceAtIndex(handle, index);
870 if (resourceInterface) {
871 return resourceInterface->allowedMethods;
877 * Get name of resource interface of the resource.
879 * @param containerHandle - handle of container resource
880 * @param index - index of contained resource, 0 to Count - 1
883 * handle to contained resource - if resource found
884 * NULL - resource not found
886 OCResourceHandle OCGetContainedResourceHandle(OCResourceHandle containerHandle,
888 OCResource *resource;
890 OC_LOG(INFO, TAG, PCF("Entering OCGetContainedResource"));
892 if (index >= MAX_CONTAINED_RESOURCES) {
896 resource = findResource((OCResource *) containerHandle);
901 return resource->rsrcResources[index];
905 * Bind an entity handler to the resource.
907 * @param handle - handle to the resource that the contained resource is to be bound
908 * @param entityHandler - entity handler function that is called by ocstack to handle requests, etc
910 * OC_STACK_OK - no errors
911 * OC_STACK_ERROR - stack process error
913 OCStackResult OCBindResourceHandler(OCResourceHandle handle,
914 OCEntityHandler entityHandler) {
915 OCResource *resource;
917 OC_LOG(INFO, TAG, PCF("Entering OCBindResourceHandler"));
919 // Validate parameters
920 VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
921 VERIFY_NON_NULL(entityHandler, ERROR, OC_STACK_INVALID_PARAM);
923 // Use the handle to find the resource in the resource linked list
924 resource = findResource(handle);
926 OC_LOG(ERROR, TAG, PCF("Resource not found"));
927 return OC_STACK_ERROR;
931 resource->entityHandler = entityHandler;
937 * Get the entity handler for a resource.
939 * @param handle - handle of resource
942 * entity handler - if resource found
943 * NULL - resource not found
945 OCEntityHandler OCGetResourceHandler(OCResourceHandle handle) {
946 OCResource *resource;
948 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandler"));
950 // Use the handle to find the resource in the resource linked list
951 resource = findResource(handle);
953 OC_LOG(ERROR, TAG, PCF("Resource not found"));
958 return resource->entityHandler;
962 * Notify observers that an observed value has changed.
964 * **NOTE: This API has NOT been finalized!!!**
966 * @param handle - handle of resource
969 * OC_STACK_OK - no errors
970 * OC_STACK_ERROR - stack not initialized
972 OCStackResult OCNotifyObservers(OCResourceHandle handle) {
974 TODO ("This API has NOT been finalized");
976 OC_LOG(INFO, TAG, PCF("Entering OCNotifyObservers"));
980 return OC_STACK_NOTIMPL;
983 //-----------------------------------------------------------------------------
984 // Private internal function definitions
985 //-----------------------------------------------------------------------------
988 * Initialize resource data structures, variables, etc.
990 void initResources() {
991 TODO ("Do we need to create a resource for /oc/core???");
992 // Init resource vars
997 * Add a resource to the end of the linked list of resources.
999 * @param resource - resource to be added
1001 void insertResource(OCResource *resource) {
1002 OCResource *pointer;
1004 if (!headResource) {
1005 headResource = resource;
1007 pointer = headResource;
1009 while (pointer->next) {
1010 pointer = pointer->next;
1012 pointer->next = resource;
1014 resource->next = NULL;
1018 * Find a resource in the linked list of resources.
1020 * @param resource - resource to be found
1022 * NULL - resource not found
1023 * pointer to resource - pointer to resource that was found in the linked list
1025 OCResource *findResource(OCResource *resource) {
1026 OCResource *pointer = headResource;
1029 if (pointer == resource) {
1032 pointer = pointer->next;
1038 * Delete the resource from the linked list.
1040 * @param resource - resource to be deleted
1045 int deleteResource(OCResource *resource) {
1046 OCResource *prev = NULL;
1049 temp = headResource;
1051 if (temp == resource) {
1052 if (temp == headResource) {
1053 headResource = temp->next;
1055 prev->next = temp->next;
1057 deleteResourceElements(temp);
1070 * Delete all of the dynamically allocated elements that were created for the resource.
1072 * @param resource - specified resource
1074 void deleteResourceElements(OCResource *resource) {
1080 OCFree(resource->uri);
1082 // Delete resourcetype linked list
1083 deleteResourceType(resource->rsrcType);
1085 // Delete resourceinterface linked list
1086 deleteResourceInterface(resource->rsrcInterface);
1090 * Delete all of the dynamically allocated elements that were created for the resource type.
1092 * @param resourceType - specified resource type
1094 void deleteResourceType(OCResourceType *resourceType) {
1095 OCResourceType *pointer = resourceType;
1096 OCResourceType *next;
1099 next = pointer->next;
1100 OCFree(pointer->resourcetypename);
1101 OCFree(pointer->typerepresentation);
1108 * Delete all of the dynamically allocated elements that were created for the resource interface.
1110 * @param resourceInterface - specified resource interface
1112 void deleteResourceInterface(OCResourceInterface *resourceInterface) {
1113 OCResourceInterface *pointer = resourceInterface;
1114 OCResourceInterface *next;
1117 next = pointer->next;
1118 OCFree(pointer->name);
1125 * Insert a resource type into a resource's resource type linked list.
1127 * @param resource - resource where resource type is to be inserted
1128 * @param resourceType - resource type to be inserted
1130 void insertResourceType(OCResource *resource, OCResourceType *resourceType) {
1131 OCResourceType *pointer;
1133 if (!resource->rsrcType) {
1134 resource->rsrcType = resourceType;
1136 pointer = resource->rsrcType;
1137 while (pointer->next) {
1138 pointer = pointer->next;
1140 pointer->next = resourceType;
1142 resourceType->next = NULL;
1146 * Get a resource type at the specified index within a resource.
1148 * @param handle - handle of resource
1149 * @param index - index of resource type
1152 * resourcetype - if found
1155 OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle, uint8_t index) {
1156 OCResource *resource;
1157 OCResourceType *pointer;
1160 // Find the specified resource
1161 resource = findResource((OCResource *) handle);
1166 // Make sure a resource has a resourcetype
1167 if (!resource->rsrcType) {
1171 // Iterate through the list
1172 pointer = resource->rsrcType;
1174 while ((i < index) && pointer) {
1176 pointer = pointer->next;
1182 * Insert a resource interface into a resource's resource interface linked list.
1184 * @param resource - resource where resource interface is to be inserted
1185 * @param resourceInterface - resource interface to be inserted
1187 void insertResourceInterface(OCResource *resource,
1188 OCResourceInterface *resourceInterface) {
1189 OCResourceInterface *pointer;
1191 if (!resource->rsrcInterface) {
1192 resource->rsrcInterface = resourceInterface;
1194 pointer = resource->rsrcInterface;
1195 while (pointer->next) {
1196 pointer = pointer->next;
1198 pointer->next = resourceInterface;
1200 resourceInterface->next = NULL;
1204 * Get a resource interface at the specified index within a resource.
1206 * @param handle - handle of resource
1207 * @param index - index of resource interface
1210 * resourceinterface - if found
1213 OCResourceInterface *findResourceInterfaceAtIndex(OCResourceHandle handle,
1215 OCResource *resource;
1216 OCResourceInterface *pointer;
1219 // Find the specified resource
1220 resource = findResource((OCResource *) handle);
1225 // Make sure a resource has a resourceinterface
1226 if (!resource->rsrcInterface) {
1230 // Iterate through the list
1231 pointer = resource->rsrcInterface;
1233 while ((i < index) && pointer) {
1235 pointer = pointer->next;
1240 // TODO: Remove these! Should be in an ocmalloc module
1241 void *OCMalloc(size_t size) {
1242 TODO ("This should be moved into an ocmalloc dir and implemented as a separate OC module");
1243 return malloc(size);
1246 void OCFree(void *ptr) {
1247 TODO ("This should be moved into an ocmalloc dir and implemented as a separate OC module");