1 //******************************************************************
3 // Copyright 2014 Intel Corporation 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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 //-----------------------------------------------------------------------------
24 //-----------------------------------------------------------------------------
26 #include "ocstackinternal.h"
27 #include "ocserverrequest.h"
28 #include "ocresource.h"
29 #include "occlientcb.h"
30 #include "ocobserve.h"
35 //-----------------------------------------------------------------------------
37 //-----------------------------------------------------------------------------
39 OC_STACK_UNINITIALIZED = 0, OC_STACK_INITIALIZED
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
45 static OCStackState stackState = OC_STACK_UNINITIALIZED;
46 OCResource *headResource = NULL;
48 //-----------------------------------------------------------------------------
50 //-----------------------------------------------------------------------------
51 #define TAG PCF("OCStack")
52 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
53 TAG, PCF(#arg " is NULL")); return (retVal); } }
55 //-----------------------------------------------------------------------------
56 // Internal API function
57 //-----------------------------------------------------------------------------
59 //This function will be called back by occoap layer when a request is received
60 OCStackResult HandleStackRequests(OCRequest * request) {
61 OC_LOG(INFO, TAG, "Entering OCStackHandleReceiveRequest (OCStack Layer)");
67 VERIFY_NON_NULL(request, ERROR, OC_STACK_ERROR);
68 VERIFY_NON_NULL(request->entityHandlerRequest, ERROR, OC_STACK_ERROR);
70 if (IsVirtualResource((const char*)request->resourceUrl))
72 result = ValidateUrlQuery(request->resourceUrl,
73 request->entityHandlerRequest->query, &filterOn,
76 if (result == OC_STACK_OK)
78 result = ProcessResourceDiscoverReq(request->entityHandlerRequest,
85 OCResource* resource = FindResourceByUri((const char*)request->resourceUrl);
88 request->entityHandlerRequest->resource = (OCResourceHandle)resource;
89 result = resource->entityHandler(OC_REQUEST_FLAG, request->entityHandlerRequest);
93 OC_LOG(INFO, TAG, "Resource Not found");
94 result = OC_STACK_NO_RESOURCE;
96 if (request->observe != NULL)
98 result = ProcessObserveRequest (resource, request);
105 //This function will be called back by occoap layer when a response is received
106 void HandleStackResponses(OCResponse * response) {
107 OCStackApplicationResult result = OC_STACK_DELETE_TRANSACTION;
108 OC_LOG(INFO, TAG, "Entering HandleStackResponses (OCStack Layer)");
110 if (response->cbNode) {
111 OC_LOG(INFO, TAG, PCF("Calling into application address space"));
112 result = response->cbNode->callBack(response->cbNode->context, response->cbNode->handle, response->clientResponse);
113 if (result == OC_STACK_DELETE_TRANSACTION) {
114 FindAndDeleteClientCB(response->cbNode);
119 int ParseIPv4Address(unsigned char * ipAddrStr, uint8_t * ipAddr) {
121 unsigned char *itr, *coap;
122 uint8_t dotCount = 0;
124 /* search for scheme */
126 if (!isdigit((unsigned char) *ipAddrStr)) {
127 coap = (unsigned char *) OC_COAP_SCHEME;
128 while (*coap && tolower(*itr) == *coap) {
136 if (isdigit((unsigned char) *ipAddrStr)) {
138 ipAddr[index] += *ipAddrStr - '0';
139 } else if ((unsigned char) *ipAddrStr == '.') {
148 if (ipAddr[0] < 255 && ipAddr[1] < 255 && ipAddr[2] < 255 && ipAddr[3] < 255
155 //-----------------------------------------------------------------------------
156 // Private internal function prototypes
157 //-----------------------------------------------------------------------------
159 static OCDoHandle GenerateInvocationHandle();
160 static void initResources();
161 static void insertResource(OCResource *resource);
162 static OCResource *findResource(OCResource *resource);
163 static void insertResourceType(OCResource *resource,
164 OCResourceType *resourceType);
165 static OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle,
167 static void insertResourceInterface(OCResource *resource,
168 OCResourceInterface *resourceInterface);
169 static OCResourceInterface *findResourceInterfaceAtIndex(
170 OCResourceHandle handle, uint8_t index);
171 static void deleteResourceType(OCResourceType *resourceType);
172 static void deleteResourceInterface(OCResourceInterface *resourceInterface);
173 static void deleteResourceElements(OCResource *resource);
174 static int deleteResource(OCResource *resource);
175 static void deleteAllResources();
177 //-----------------------------------------------------------------------------
178 // Default resource entity handler function
179 //-----------------------------------------------------------------------------
180 void defaultResourceEHandler(OCEntityHandlerFlag flag,
181 OCEntityHandlerRequest * request) {
182 TODO ("Implement me!!!!");
183 // TODO: remove silence unused param warnings
188 //-----------------------------------------------------------------------------
190 //-----------------------------------------------------------------------------
193 * Initialize the OC Stack. Must be called prior to starting the stack.
196 * IP Address of host device
198 * Port of host device
200 * Host device is client, server, or client-server
203 * OC_STACK_OK - no errors
204 * OC_STACK_ERROR - stack init error
206 OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode) {
207 OC_LOG(INFO, TAG, PCF("Entering OCInit"));
210 OC_LOG_V(INFO, TAG, "IP Address = %s", ipAddr);
215 OC_LOG(INFO, TAG, PCF("Client mode"));
218 OC_LOG(INFO, TAG, PCF("Server mode"));
220 case OC_CLIENT_SERVER:
221 OC_LOG(INFO, TAG, PCF("Client-server mode"));
224 OC_LOG(ERROR, TAG, PCF("Invalid mode"));
225 return OC_STACK_ERROR;
229 // Initialize resource
232 // Make call to OCCoAP layer
233 if (OCInitCoAP(ipAddr, (uint16_t) port, mode) == 0) {
234 stackState = OC_STACK_INITIALIZED;
238 OC_LOG(ERROR, TAG, PCF("Stack initialization error"));
239 return OC_STACK_ERROR;
243 * Stop the OC stack. Use for a controlled shutdown.
245 * OC_STACK_OK - no errors
246 * OC_STACK_ERROR - stack not initialized
248 OCStackResult OCStop() {
249 OCStackResult result = OC_STACK_ERROR;
251 OC_LOG(INFO, TAG, PCF("Entering OCStop"));
253 if (stackState != OC_STACK_INITIALIZED) {
254 OC_LOG(ERROR, TAG, PCF("Stack not initialized"));
255 return OC_STACK_ERROR;
258 // Make call to OCCoAP layer
259 if (OCStopCoAP() == 0) {
260 // Remove all observers
261 DeleteObserverList();
262 // Remove all the client callbacks
263 DeleteClientCBList();
264 stackState = OC_STACK_UNINITIALIZED;
265 result = OC_STACK_OK;
267 result = OC_STACK_ERROR;
270 // Free memory dynamically allocated for resources
271 deleteAllResources();
273 if (result != OC_STACK_OK) {
274 OC_LOG(ERROR, TAG, PCF("Stack stop error"));
281 * Discover or Perform requests on a specified resource (specified by that Resource's respective URI).
283 * @param handle - @ref OCDoHandle to refer to the request sent out on behalf of calling this API.
284 * @param method - @ref OCMethod to perform on the resource
285 * @param requiredUri - URI of the resource to interact with
286 * @param referenceUri - URI of the reference resource
287 * @param request - JSON encoded request
288 * @param qos - quality of service
289 * @param cbData - struct that contains asynchronous callback function that is invoked
290 * by the stack when discovery or resource interaction is complete
293 * OC_STACK_OK - no errors
294 * OC_STACK_INVALID_CALLBACK - invalid callback function pointer
295 * OC_STACK_INVALID_METHOD - invalid resource method
296 * OC_STACK_INVALID_URI - invalid required or reference URI
299 OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requiredUri,
300 const char *referenceUri, const char *request,
301 OCQualityOfService qos, OCCallbackData *cbData)
303 OCStackResult result = OC_STACK_ERROR;
304 OCCoAPToken * token = NULL;
305 ClientCB *clientCB = NULL;
308 OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
310 // Validate input parameters
311 VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
312 VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
314 TODO ("Need to form the final query by concatenating require and reference URI's");
315 VERIFY_NON_NULL(requiredUri, FATAL, OC_STACK_INVALID_URI);
322 case OC_REST_OBSERVE:
323 case OC_REST_OBSERVE_ALL:
326 return OC_STACK_INVALID_METHOD;
329 *handle = GenerateInvocationHandle();
330 VERIFY_NON_NULL(*handle, FATAL, OC_STACK_ERROR);
331 token = OCGenerateCoAPToken();
336 if((result = AddClientCB(&clientCB, cbData, token, *handle, method)) != OC_STACK_OK)
341 // Make call to OCCoAP layer
342 result = OCDoCoAPResource(method, qos, token, requiredUri, request);
346 if (result != OC_STACK_OK)
348 OC_LOG(ERROR, TAG, PCF("OCDoResource error"));
351 DeleteClientCB(clientCB);
363 * Cancel a request associated with a specific @ref OCDoResource invocation.
365 * @param handle - Used to identify a specific OCDoResource invocation.
368 * OC_STACK_OK - No errors; Success
369 * OC_STACK_INVALID_PARAM - The handle provided is invalid.
371 OCStackResult OCCancel(OCDoHandle handle) {
373 * This ftn can be implemented one of two ways:
375 * 1. When observe is unobserved..Remove the callback associated on client side.
376 * When the next notification comes in from server, reply with RST message to server.
378 * 2. When OCCancel is called, and it is associated with an observe request
379 * (i.e. ClientCB->method == OC_REST_OBSERVE || OC_REST_OBSERVE_ALL),
380 * Send Observe request to server with observe flag = OC_RESOURCE_OBSERVE_DEREGISTER.
381 * Remove the callback associated on client side.
383 * Number 1 is implemented here.
386 return OC_STACK_INVALID_PARAM;
389 OC_LOG(INFO, TAG, PCF("Entering OCCancel"));
391 ClientCB *clientCB = GetClientCB(NULL, handle);
394 switch (clientCB->method)
396 case OC_REST_OBSERVE:
397 case OC_REST_OBSERVE_ALL:
398 // Make call to OCCoAP layer
399 DeleteClientCB(clientCB);
402 return OC_STACK_INVALID_METHOD;
409 * Called in main loop of OC client or server. Allows low-level processing of
413 * OC_STACK_OK - no errors
414 * OC_STACK_ERROR - stack process error
416 OCStackResult OCProcess() {
418 OC_LOG(INFO, TAG, PCF("Entering OCProcess"));
426 * @param handle - pointer to handle to newly created resource. Set by ocstack. Used to refer to resource
427 * @param resourceTypeName - name of resource type. Example: "core.led"
428 * @param resourceInterfaceName - name of resource interface. Example: "core.rw"
429 * @param uri - URI of the resource. Example: "/a/led"
430 * @param entityHandler - entity handler function that is called by ocstack to handle requests, etc
431 * NULL for default entity handler
432 * @param resourceProperties - properties supported by resource. Example: OC_DISCOVERABLE|OC_OBSERVABLE
435 * OC_STACK_OK - no errors
436 * OC_STACK_ERROR - stack process error
438 OCStackResult OCCreateResource(OCResourceHandle *handle,
439 const char *resourceTypeName,
440 const char *resourceInterfaceName,
441 const char *uri, OCEntityHandler entityHandler,
442 uint8_t resourceProperties) {
444 OCResource *pointer = NULL;
447 OCStackResult result = OC_STACK_ERROR;
449 OC_LOG(INFO, TAG, PCF("Entering OCCreateResource"));
451 // Validate parameters
452 // Is it presented during resource discovery?
453 if (!handle || !resourceTypeName || !resourceInterfaceName || !uri) {
454 OC_LOG(ERROR, TAG, PCF("Input parameter is NULL"));
455 return OC_STACK_INVALID_PARAM;
458 // Make sure resourceProperties bitmask has allowed properties specified
459 if (resourceProperties
460 > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW)) {
461 OC_LOG(ERROR, TAG, PCF("Invalid property"));
462 return OC_STACK_INVALID_PARAM;
465 // If the headResource is NULL, then no resources have been created...
466 pointer = headResource;
468 // At least one resources is in the resource list, so we need to search for
469 // repeated URLs, which are not allowed. If a repeat is found, exit with an error
471 if (strcmp(uri, pointer->uri) == 0) {
472 OC_LOG(ERROR, TAG, PCF("URI already in use"));
473 return OC_STACK_INVALID_PARAM;
475 pointer = pointer->next;
478 // Create the pointer and insert it into the resource list
479 pointer = (OCResource *) OCMalloc(sizeof(OCResource));
483 memset(pointer, 0, sizeof(OCResource));
485 insertResource(pointer);
488 size = strlen(uri) + 1;
489 str = (char *) OCMalloc(size);
493 strncpy(str, uri, size);
496 // Set properties. Set OC_ACTIVE
497 pointer->resourceProperties = (OCResourceProperty) (resourceProperties
500 // Add the resourcetype to the resource
501 result = OCBindResourceTypeToResource((OCResourceHandle) pointer,
503 if (result != OC_STACK_OK) {
504 OC_LOG(ERROR, TAG, PCF("Error adding resourcetype"));
508 // Add the resourceinterface to the resource
509 result = OCBindResourceInterfaceToResource((OCResourceHandle) pointer,
510 resourceInterfaceName);
511 if (result != OC_STACK_OK) {
512 OC_LOG(ERROR, TAG, PCF("Error adding resourceinterface"));
516 // If an entity handler has been passed, attach it to the newly created
517 // resource. Otherwise, set the default entity handler.
520 pointer->entityHandler = entityHandler;
524 pointer->entityHandler = defaultResourceEHandler;
528 result = OC_STACK_OK;
531 if (result != OC_STACK_OK)
533 // Deep delete of resource and other dynamic elements that it contains
534 deleteResource(pointer);
541 * Add a resource to a collection resource.
543 * @param collectionHandle - handle to the collection resource
544 * @param resourceHandle - handle to resource to be added to the collection resource
547 * OC_STACK_OK - no errors
548 * OC_STACK_ERROR - stack process error
549 * OC_STACK_INVALID_PARAM - invalid collectionhandle
551 OCStackResult OCBindResource(
552 OCResourceHandle collectionHandle, OCResourceHandle resourceHandle) {
553 OCResource *resource;
556 OC_LOG(INFO, TAG, PCF("Entering OCBindResource"));
558 // Validate parameters
559 VERIFY_NON_NULL(collectionHandle, ERROR, OC_STACK_ERROR);
560 VERIFY_NON_NULL(resourceHandle, ERROR, OC_STACK_ERROR);
561 // Container cannot contain itself
562 if (collectionHandle == resourceHandle) {
563 OC_LOG(ERROR, TAG, PCF("Added handle equals collection handle"));
564 return OC_STACK_INVALID_PARAM;
567 // Use the handle to find the resource in the resource linked list
568 resource = findResource((OCResource *) collectionHandle);
570 OC_LOG(ERROR, TAG, PCF("Collection handle not found"));
571 return OC_STACK_INVALID_PARAM;
574 // Look for an open slot to add add the child resource.
575 // If found, add it and return success
576 for (i = 0; i < MAX_CONTAINED_RESOURCES; i++) {
577 if (!resource->rsrcResources[i]) {
578 resource->rsrcResources[i] = (OCResourceHandle) resourceHandle;
579 OC_LOG(INFO, TAG, PCF("resource bound"));
584 // Unable to add resourceHandle, so return error
585 return OC_STACK_ERROR;
589 * Remove a resource from a collection resource.
591 * @param collectionHandle - handle to the collection resource
592 * @param resourceHandle - handle to resource to be added to the collection resource
595 * OC_STACK_OK - no errors
596 * OC_STACK_ERROR - stack process error
597 * OC_STACK_INVALID_PARAM - invalid collectionHandle
599 OCStackResult OCUnBindResource(
600 OCResourceHandle collectionHandle, OCResourceHandle resourceHandle) {
601 OCResource *resource;
604 OC_LOG(INFO, TAG, PCF("Entering OCUnBindResource"));
606 // Validate parameters
607 VERIFY_NON_NULL(collectionHandle, ERROR, OC_STACK_ERROR);
608 VERIFY_NON_NULL(resourceHandle, ERROR, OC_STACK_ERROR);
609 // Container cannot contain itself
610 if (collectionHandle == resourceHandle) {
611 OC_LOG(ERROR, TAG, PCF("removing handle equals collection handle"));
612 return OC_STACK_INVALID_PARAM;
615 // Use the handle to find the resource in the resource linked list
616 resource = findResource((OCResource *) collectionHandle);
618 OC_LOG(ERROR, TAG, PCF("Collection handle not found"));
619 return OC_STACK_INVALID_PARAM;
622 // Look for an open slot to add add the child resource.
623 // If found, add it and return success
624 for (i = 0; i < MAX_CONTAINED_RESOURCES; i++) {
625 if (resourceHandle == resource->rsrcResources[i]) {
626 resource->rsrcResources[i] = (OCResourceHandle) 0;
627 OC_LOG(INFO, TAG, PCF("resource unbound"));
632 OC_LOG(INFO, TAG, PCF("resource not found in collection"));
634 // Unable to add resourceHandle, so return error
635 return OC_STACK_ERROR;
640 * Bind a resourcetype to a resource.
642 * @param handle - handle to the resource
643 * @param resourceTypeName - name of resource type. Example: "core.led"
646 * OC_STACK_OK - no errors
647 * OC_STACK_ERROR - stack process error
649 OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle,
650 const char *resourceTypeName) {
652 OCResourceType *pointer = NULL;
655 OCResource *resource;
656 OCStackResult result = OC_STACK_ERROR;
658 OC_LOG(INFO, TAG, PCF("Entering OCBindResourceTypeToResource"));
660 // Validate parameters
661 VERIFY_NON_NULL(resourceTypeName, ERROR, OC_STACK_INVALID_PARAM);
662 // TODO: Does resource attribute resentation really have to be maintained in stack?
663 // Is it presented during resource discovery?
665 // Make sure resource exists
666 resource = findResource((OCResource *) handle);
668 OC_LOG(ERROR, TAG, PCF("Resource not found"));
669 return OC_STACK_ERROR;
672 TODO ("Make sure that the resourcetypename doesn't already exist in the resource");
674 // Create the resourcetype and insert it into the resource list
675 pointer = (OCResourceType *) OCMalloc(sizeof(OCResourceType));
679 memset(pointer, 0, sizeof(OCResourceType));
681 // Set the resourceTypeName
682 size = strlen(resourceTypeName) + 1;
683 str = (char *) OCMalloc(size);
687 strncpy(str, resourceTypeName, size);
688 pointer->resourcetypename = str;
690 // Bind the resourcetype to the resource
691 insertResourceType(resource, pointer);
693 result = OC_STACK_OK;
695 exit: if (result != OC_STACK_OK) {
703 * Bind a resourceinterface to a resource.
705 * @param handle - handle to the resource
706 * @param resourceInterfaceName - name of resource interface. Example: "core.rw"
709 * OC_STACK_OK - no errors
710 * OC_STACK_ERROR - stack process error
712 OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
713 const char *resourceInterfaceName) {
715 OCResourceInterface *pointer = NULL;
718 OCResource *resource;
719 OCStackResult result = OC_STACK_ERROR;
721 OC_LOG(INFO, TAG, PCF("Entering OCBindResourceInterfaceToResource"));
723 // Validate parameters
724 VERIFY_NON_NULL(resourceInterfaceName, ERROR, OC_STACK_INVALID_PARAM);
726 // Make sure resource exists
727 resource = findResource((OCResource *) handle);
729 OC_LOG(ERROR, TAG, PCF("Resource not found"));
730 return OC_STACK_INVALID_PARAM;
733 TODO ("Make sure that the resourceinterface name doesn't already exist in the resource");
735 // Create the resourceinterface and insert it into the resource list
736 pointer = (OCResourceInterface *) OCMalloc(sizeof(OCResourceInterface));
740 memset(pointer, 0, sizeof(OCResourceInterface));
742 // Set the resourceinterface name
743 size = strlen(resourceInterfaceName) + 1;
744 str = (char *) OCMalloc(size);
748 strncpy(str, resourceInterfaceName, size);
751 // Bind the resourceinterface to the resource
752 insertResourceInterface(resource, pointer);
754 result = OC_STACK_OK;
755 exit: if (result != OC_STACK_OK) {
763 * Get the number of resources that have been created in the stack.
765 * @param numResources - pointer to count variable
768 * OC_STACK_OK - no errors
769 * OC_STACK_ERROR - stack process error
772 OCStackResult OCGetNumberOfResources(uint8_t *numResources) {
773 OCResource *pointer = headResource;
775 OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResources"));
776 VERIFY_NON_NULL(numResources, ERROR, OC_STACK_INVALID_PARAM);
779 *numResources = *numResources + 1;
780 pointer = pointer->next;
786 * Get a resource handle by index.
788 * @param index - index of resource, 0 to Count - 1
791 * Resource handle - if found
792 * NULL - if not found
794 OCResourceHandle OCGetResourceHandle(uint8_t index) {
795 OCResource *pointer = headResource;
798 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandle"));
800 // Iterate through the list
801 while ((i < index) && pointer) {
803 pointer = pointer->next;
805 return (OCResourceHandle) pointer;
809 * Delete resource specified by handle. Deletes resource and all resourcetype and resourceinterface
812 * @param handle - handle of resource to be deleted
815 * OC_STACK_OK - no errors
816 * OC_STACK_ERROR - stack process error
818 OCStackResult OCDeleteResource(OCResourceHandle handle) {
819 OC_LOG(INFO, TAG, PCF("Entering OCDeleteResource"));
822 OC_LOG(ERROR, TAG, PCF("Resource not found"));
823 return OC_STACK_INVALID_PARAM;
826 if (deleteResource((OCResource *) handle) == 0) {
827 OC_LOG(ERROR, TAG, PCF("Error deleting resource"));
828 return OC_STACK_ERROR;
835 * Get the URI of the resource specified by handle.
837 * @param handle - handle of resource
839 * URI string - if resource found
840 * NULL - resource not found
842 const char *OCGetResourceUri(OCResourceHandle handle) {
843 OCResource *resource;
844 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceUri"));
846 resource = findResource((OCResource *) handle);
848 return resource->uri;
850 return (const char *) NULL;
854 * Get the properties of the resource specified by handle.
855 * NOTE: that after a resource is created, the OC_ACTIVE property is set
856 * for the resource by the stack.
858 * @param handle - handle of resource
860 * property bitmap - if resource found
861 * NULL - resource not found
863 uint8_t OCGetResourceProperties(OCResourceHandle handle) {
864 OCResource *resource;
865 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceProperties"));
867 resource = findResource((OCResource *) handle);
869 return resource->resourceProperties;
875 * Get the number of resource types of the resource.
877 * @param handle - handle of resource
878 * @param numResourceTypes - pointer to count variable
881 * OC_STACK_OK - no errors
882 * OC_STACK_ERROR - stack process error
884 OCStackResult OCGetNumberOfResourceTypes(OCResourceHandle handle,
885 uint8_t *numResourceTypes) {
886 OCResource *resource;
887 OCResourceType *pointer;
889 OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceTypes"));
890 VERIFY_NON_NULL(numResourceTypes, ERROR, OC_STACK_INVALID_PARAM);
891 VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
893 *numResourceTypes = 0;
895 resource = findResource((OCResource *) handle);
897 pointer = resource->rsrcType;
899 *numResourceTypes = *numResourceTypes + 1;
900 pointer = pointer->next;
907 * Get name of resource type of the resource.
909 * @param handle - handle of resource
910 * @param index - index of resource, 0 to Count - 1
913 * resource type name - if resource found
914 * NULL - resource not found
916 const char *OCGetResourceTypeName(OCResourceHandle handle, uint8_t index) {
917 OCResourceType *resourceType;
919 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceTypeName"));
921 resourceType = findResourceTypeAtIndex(handle, index);
923 return resourceType->resourcetypename;
925 return (const char *) NULL;
931 * Get the number of resource interfaces of the resource.
933 * @param handle - handle of resource
934 * @param numResources - pointer to count variable
937 * OC_STACK_OK - no errors
938 * OC_STACK_ERROR - stack process error
941 OCStackResult OCGetNumberOfResourceInterfaces(OCResourceHandle handle,
942 uint8_t *numResourceInterfaces) {
943 OCResourceInterface *pointer;
944 OCResource *resource;
946 OC_LOG(INFO, TAG, PCF("Entering OCGetNumberOfResourceInterfaces"));
948 VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
949 VERIFY_NON_NULL(numResourceInterfaces, ERROR, OC_STACK_INVALID_PARAM);
951 *numResourceInterfaces = 0;
952 resource = findResource((OCResource *) handle);
954 pointer = resource->rsrcInterface;
956 *numResourceInterfaces = *numResourceInterfaces + 1;
957 pointer = pointer->next;
964 * Get name of resource interface of the resource.
966 * @param handle - handle of resource
967 * @param index - index of resource, 0 to Count - 1
970 * resource interface name - if resource found
971 * NULL - resource not found
973 const char *OCGetResourceInterfaceName(OCResourceHandle handle, uint8_t index) {
974 OCResourceInterface *resourceInterface;
976 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceInterfaceName"));
978 resourceInterface = findResourceInterfaceAtIndex(handle, index);
979 if (resourceInterface) {
980 return resourceInterface->name;
982 return (const char *) NULL;
986 * Get resource handle from the collection resource by index.
988 * @param collectionHandle - handle of collection resource
989 * @param index - index of contained resource, 0 to Count - 1
992 * handle to resource - if resource found
993 * NULL - resource not found
995 OCResourceHandle OCGetResourceHandleFromCollection(OCResourceHandle collectionHandle,
997 OCResource *resource;
999 OC_LOG(INFO, TAG, PCF("Entering OCGetContainedResource"));
1001 if (index >= MAX_CONTAINED_RESOURCES) {
1005 resource = findResource((OCResource *) collectionHandle);
1010 return resource->rsrcResources[index];
1014 * Bind an entity handler to the resource.
1016 * @param handle - handle to the resource that the contained resource is to be bound
1017 * @param entityHandler - entity handler function that is called by ocstack to handle requests, etc
1019 * OC_STACK_OK - no errors
1020 * OC_STACK_ERROR - stack process error
1022 OCStackResult OCBindResourceHandler(OCResourceHandle handle,
1023 OCEntityHandler entityHandler) {
1024 OCResource *resource;
1026 OC_LOG(INFO, TAG, PCF("Entering OCBindResourceHandler"));
1028 // Validate parameters
1029 VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
1030 VERIFY_NON_NULL(entityHandler, ERROR, OC_STACK_INVALID_PARAM);
1032 // Use the handle to find the resource in the resource linked list
1033 resource = findResource(handle);
1035 OC_LOG(ERROR, TAG, PCF("Resource not found"));
1036 return OC_STACK_ERROR;
1040 resource->entityHandler = entityHandler;
1046 * Get the entity handler for a resource.
1048 * @param handle - handle of resource
1051 * entity handler - if resource found
1052 * NULL - resource not found
1054 OCEntityHandler OCGetResourceHandler(OCResourceHandle handle) {
1055 OCResource *resource;
1057 OC_LOG(INFO, TAG, PCF("Entering OCGetResourceHandler"));
1059 // Use the handle to find the resource in the resource linked list
1060 resource = findResource(handle);
1062 OC_LOG(ERROR, TAG, PCF("Resource not found"));
1067 return resource->entityHandler;
1071 * Notify observers that an observed value has changed.
1074 * @param handle - handle of resource
1077 * OC_STACK_OK - no errors
1078 * OC_STACK_ERROR - stack not initialized
1080 OCStackResult OCNotifyObservers(OCResourceHandle handle) {
1081 OCResource *resPtr = NULL;
1082 OCStackResult result;
1084 OC_LOG(INFO, TAG, PCF("Entering OCNotifyObservers"));
1086 VERIFY_NON_NULL(handle, ERROR, OC_STACK_ERROR);
1088 // Verify that the resource exists
1089 resPtr = findResource ((OCResource *) handle);
1092 return OC_STACK_NO_RESOURCE;
1094 result = SendObserverNotification (handle, resPtr);
1099 //-----------------------------------------------------------------------------
1100 // Private internal function definitions
1101 //-----------------------------------------------------------------------------
1103 * Generate handle of OCDoResource invocation for callback management.
1105 static OCDoHandle GenerateInvocationHandle()
1107 OCDoHandle handle = NULL;
1108 // Generate token here, it will be deleted when the transaction is deleted
1109 handle = (OCDoHandle) malloc(sizeof(uint8_t[MAX_TOKEN_LENGTH]));
1112 OCFillRandomMem((uint8_t*)handle, sizeof(uint8_t[MAX_TOKEN_LENGTH]));
1119 * Initialize resource data structures, variables, etc.
1121 void initResources() {
1122 TODO ("Do we need to create a resource for /oc/core???");
1123 // Init resource vars
1124 headResource = NULL;
1128 * Add a resource to the end of the linked list of resources.
1130 * @param resource - resource to be added
1132 void insertResource(OCResource *resource) {
1133 OCResource *pointer;
1135 if (!headResource) {
1136 headResource = resource;
1138 pointer = headResource;
1140 while (pointer->next) {
1141 pointer = pointer->next;
1143 pointer->next = resource;
1145 resource->next = NULL;
1149 * Find a resource in the linked list of resources.
1151 * @param resource - resource to be found
1153 * NULL - resource not found
1154 * pointer to resource - pointer to resource that was found in the linked list
1156 OCResource *findResource(OCResource *resource) {
1157 OCResource *pointer = headResource;
1160 if (pointer == resource) {
1163 pointer = pointer->next;
1168 void deleteAllResources()
1170 OCResource *pointer = headResource;
1175 temp = pointer->next;
1176 deleteResource(pointer);
1182 * Delete the resource from the linked list.
1184 * @param resource - resource to be deleted
1189 int deleteResource(OCResource *resource) {
1190 OCResource *prev = NULL;
1193 temp = headResource;
1195 if (temp == resource) {
1196 if (temp == headResource) {
1197 headResource = temp->next;
1199 prev->next = temp->next;
1201 deleteResourceElements(temp);
1214 * Delete all of the dynamically allocated elements that were created for the resource.
1216 * @param resource - specified resource
1218 void deleteResourceElements(OCResource *resource) {
1224 OCFree(resource->uri);
1226 // Delete resourcetype linked list
1227 deleteResourceType(resource->rsrcType);
1229 // Delete resourceinterface linked list
1230 deleteResourceInterface(resource->rsrcInterface);
1234 * Delete all of the dynamically allocated elements that were created for the resource type.
1236 * @param resourceType - specified resource type
1238 void deleteResourceType(OCResourceType *resourceType) {
1239 OCResourceType *pointer = resourceType;
1240 OCResourceType *next;
1243 next = pointer->next;
1244 OCFree(pointer->resourcetypename);
1251 * Delete all of the dynamically allocated elements that were created for the resource interface.
1253 * @param resourceInterface - specified resource interface
1255 void deleteResourceInterface(OCResourceInterface *resourceInterface) {
1256 OCResourceInterface *pointer = resourceInterface;
1257 OCResourceInterface *next;
1260 next = pointer->next;
1261 OCFree(pointer->name);
1268 * Insert a resource type into a resource's resource type linked list.
1270 * @param resource - resource where resource type is to be inserted
1271 * @param resourceType - resource type to be inserted
1273 void insertResourceType(OCResource *resource, OCResourceType *resourceType) {
1274 OCResourceType *pointer;
1276 if (!resource->rsrcType) {
1277 resource->rsrcType = resourceType;
1279 pointer = resource->rsrcType;
1280 while (pointer->next) {
1281 pointer = pointer->next;
1283 pointer->next = resourceType;
1285 resourceType->next = NULL;
1289 * Get a resource type at the specified index within a resource.
1291 * @param handle - handle of resource
1292 * @param index - index of resource type
1295 * resourcetype - if found
1298 OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle, uint8_t index) {
1299 OCResource *resource;
1300 OCResourceType *pointer;
1303 // Find the specified resource
1304 resource = findResource((OCResource *) handle);
1309 // Make sure a resource has a resourcetype
1310 if (!resource->rsrcType) {
1314 // Iterate through the list
1315 pointer = resource->rsrcType;
1317 while ((i < index) && pointer) {
1319 pointer = pointer->next;
1325 * Insert a resource interface into a resource's resource interface linked list.
1327 * @param resource - resource where resource interface is to be inserted
1328 * @param resourceInterface - resource interface to be inserted
1330 void insertResourceInterface(OCResource *resource,
1331 OCResourceInterface *resourceInterface) {
1332 OCResourceInterface *pointer;
1334 if (!resource->rsrcInterface) {
1335 resource->rsrcInterface = resourceInterface;
1337 pointer = resource->rsrcInterface;
1338 while (pointer->next) {
1339 pointer = pointer->next;
1341 pointer->next = resourceInterface;
1343 resourceInterface->next = NULL;
1347 * Get a resource interface at the specified index within a resource.
1349 * @param handle - handle of resource
1350 * @param index - index of resource interface
1353 * resourceinterface - if found
1356 OCResourceInterface *findResourceInterfaceAtIndex(OCResourceHandle handle,
1358 OCResource *resource;
1359 OCResourceInterface *pointer;
1362 // Find the specified resource
1363 resource = findResource((OCResource *) handle);
1368 // Make sure a resource has a resourceinterface
1369 if (!resource->rsrcInterface) {
1373 // Iterate through the list
1374 pointer = resource->rsrcInterface;
1376 while ((i < index) && pointer) {
1378 pointer = pointer->next;
1383 // TODO: Remove these! Should be in an ocmalloc module
1384 void *OCMalloc(size_t size) {
1385 TODO ("This should be moved into an ocmalloc dir and implemented as a separate OC module");
1386 return malloc(size);
1389 void OCFree(void *ptr) {
1390 TODO ("This should be moved into an ocmalloc dir and implemented as a separate OC module");