OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge, OCQualityOfService qos) #endif { OC_LOG(INFO, TAG, PCF("Entering SendObserverNotification")); OCStackResult result = OC_STACK_ERROR; ResourceObserver * resourceObserver = serverObsList; uint8_t numObs = 0; OCServerRequest * request = NULL; OCEntityHandlerRequest ehRequest = {0}; OCEntityHandlerResult ehResult = OC_EH_ERROR; // Find clients that are observing this resource while (resourceObserver) { if (resourceObserver->resource == resPtr) { numObs++; #ifdef WITH_PRESENCE if(method != OC_REST_PRESENCE) { #endif qos = DetermineObserverQoS(method, resourceObserver, qos); result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET, 0, resPtr->sequenceNum, qos, resourceObserver->query, NULL, NULL, &resourceObserver->token, resourceObserver->addr, resourceObserver->resUri, 0); request->observeResult = OC_STACK_OK; if(request && result == OC_STACK_OK) { result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request, request->method, (OCResourceHandle) resPtr, request->query, request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions, request->rcvdVendorSpecificHeaderOptions, OC_OBSERVE_NO_OPTION, 0); if(result == OC_STACK_OK) { ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest); if(ehResult == OC_EH_ERROR) { FindAndDeleteServerRequest(request); } } } #ifdef WITH_PRESENCE } else { OCEntityHandlerResponse ehResponse = {0}; unsigned char presenceResBuf[MAX_RESPONSE_LENGTH] = {0}; //This is effectively the implementation for the presence entity handler. OC_LOG(DEBUG, TAG, PCF("This notification is for Presence")); result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET, 0, OC_OBSERVE_NO_OPTION, OC_LOW_QOS, NULL, NULL, NULL, &resourceObserver->token, resourceObserver->addr, resourceObserver->resUri, 0); if(result == OC_STACK_OK) { // we create the payload here if(resourceType && resourceType->resourcetypename) { snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u:%s", resPtr->sequenceNum, maxAge, resourceType->resourcetypename); } else { snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u", resPtr->sequenceNum, maxAge); } ehResponse.ehResult = OC_EH_OK; ehResponse.payload = presenceResBuf; ehResponse.payloadSize = strlen((const char *)presenceResBuf) + 1; ehResponse.persistentBufferFlag = 0; ehResponse.requestHandle = (OCRequestHandle) request; ehResponse.resourceHandle = (OCResourceHandle) resPtr; strcpy((char *)ehResponse.resourceUri, (const char *)resourceObserver->resUri); result = OCDoResponse(&ehResponse); } } #endif } resourceObserver = resourceObserver->next; } if (numObs == 0) { OC_LOG(INFO, TAG, PCF("Resource has no observers")); result = OC_STACK_NO_OBSERVERS; } return result; }
OCStackResult SendListObserverNotification (OCResource * resource, OCObservationId *obsIdList, uint8_t numberOfIds, const OCRepPayload *payload, uint32_t maxAge, OCQualityOfService qos) { (void)maxAge; if(!resource || !obsIdList || !payload) { return OC_STACK_INVALID_PARAM; } uint8_t numIds = numberOfIds; ResourceObserver *observer = NULL; uint8_t numSentNotification = 0; OCServerRequest * request = NULL; OCStackResult result = OC_STACK_ERROR; bool observeErrorFlag = false; OC_LOG(INFO, TAG, "Entering SendListObserverNotification"); while(numIds) { observer = GetObserverUsingId (*obsIdList); if(observer) { // Found observer - verify if it matches the resource handle if (observer->resource == resource) { qos = DetermineObserverQoS(OC_REST_GET, observer, qos); result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET, 0, resource->sequenceNum, qos, observer->query, NULL, NULL, observer->token, observer->tokenLength, observer->resUri, 0, observer->acceptFormat, &observer->devAddr); if(request) { request->observeResult = OC_STACK_OK; if(result == OC_STACK_OK) { OCEntityHandlerResponse ehResponse = {0}; ehResponse.ehResult = OC_EH_OK; ehResponse.payload = (OCPayload*)OCRepPayloadCreate(); if(!ehResponse.payload) { FindAndDeleteServerRequest(request); continue; } memcpy(ehResponse.payload, payload, sizeof(*payload)); ehResponse.persistentBufferFlag = 0; ehResponse.requestHandle = (OCRequestHandle) request; ehResponse.resourceHandle = (OCResourceHandle) resource; result = OCDoResponse(&ehResponse); if(result == OC_STACK_OK) { OC_LOG_V(INFO, TAG, "Observer id %d notified.", *obsIdList); // Increment only if OCDoResponse is successful numSentNotification++; OICFree(ehResponse.payload); FindAndDeleteServerRequest(request); } else { OC_LOG_V(INFO, TAG, "Error notifying observer id %d.", *obsIdList); } } else { FindAndDeleteServerRequest(request); } } // Since we are in a loop, set an error flag to indicate // at least one error occurred. if (result != OC_STACK_OK) { observeErrorFlag = true; } } } obsIdList++; numIds--; } if(numSentNotification == numberOfIds && !observeErrorFlag) { return OC_STACK_OK; } else if(numSentNotification == 0) { return OC_STACK_NO_OBSERVERS; } else { OC_LOG(ERROR, TAG, "Observer notification error"); return OC_STACK_ERROR; } }
OCStackResult SendListObserverNotification (OCResource * resource, OCObservationId *obsIdList, uint8_t numberOfIds, unsigned char *notificationJSONPayload, uint32_t maxAge, OCQualityOfService qos) { uint8_t numIds = numberOfIds; ResourceObserver *observation = NULL; uint8_t numSentNotification = 0; OCServerRequest * request = NULL; OCStackResult result = OC_STACK_ERROR; OCEntityHandlerResponse ehResponse = {0}; OC_LOG(INFO, TAG, PCF("Entering SendListObserverNotification")); while(numIds) { OC_LOG_V(INFO, TAG, "Need to notify observation id %d", *obsIdList); observation = NULL; observation = GetObserverUsingId (*obsIdList); if(observation) { // Found observation - verify if it matches the resource handle if (observation->resource == resource) { qos = DetermineObserverQoS(OC_REST_GET, observation, qos); result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET, 0, resource->sequenceNum, qos, observation->query, NULL, NULL, &observation->token, observation->addr, observation->resUri, 0); request->observeResult = OC_STACK_OK; if(request && result == OC_STACK_OK) { memset(&ehResponse, 0, sizeof(OCEntityHandlerResponse)); ehResponse.ehResult = OC_EH_OK; ehResponse.payload = (unsigned char *) OCMalloc(MAX_RESPONSE_LENGTH); if(!ehResponse.payload) { FindAndDeleteServerRequest(request); continue; } strcpy((char *)ehResponse.payload, (const char *)notificationJSONPayload); ehResponse.payloadSize = strlen((const char *)ehResponse.payload) + 1; ehResponse.persistentBufferFlag = 0; ehResponse.requestHandle = (OCRequestHandle) request; ehResponse.resourceHandle = (OCResourceHandle) resource; result = OCDoResponse(&ehResponse); if(result == OC_STACK_OK) { OCFree(ehResponse.payload); FindAndDeleteServerRequest(request); } } else { FindAndDeleteServerRequest(request); } numSentNotification++; } } obsIdList++; numIds--; } if(numSentNotification == numberOfIds) { return OC_STACK_OK; } else if(numSentNotification == 0) { return OC_STACK_NO_OBSERVERS; } else { //TODO: we need to signal that not every one in the // list got an update, should we also indicate who did not receive on? return OC_STACK_OK; } }
OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge, OCQualityOfService qos) #endif { OC_LOG(INFO, TAG, "Entering SendObserverNotification"); if(!resPtr) { return OC_STACK_INVALID_PARAM; } OCStackResult result = OC_STACK_ERROR; ResourceObserver * resourceObserver = serverObsList; uint8_t numObs = 0; OCServerRequest * request = NULL; OCEntityHandlerRequest ehRequest = {0}; OCEntityHandlerResult ehResult = OC_EH_ERROR; bool observeErrorFlag = false; // Find clients that are observing this resource while (resourceObserver) { if (resourceObserver->resource == resPtr) { numObs++; #ifdef WITH_PRESENCE if(method != OC_REST_PRESENCE) { #endif qos = DetermineObserverQoS(method, resourceObserver, qos); result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET, 0, resPtr->sequenceNum, qos, resourceObserver->query, NULL, NULL, resourceObserver->token, resourceObserver->tokenLength, resourceObserver->resUri, 0, resourceObserver->acceptFormat, &resourceObserver->devAddr); if(request) { request->observeResult = OC_STACK_OK; if(result == OC_STACK_OK) { result = FormOCEntityHandlerRequest( &ehRequest, (OCRequestHandle) request, request->method, &request->devAddr, (OCResourceHandle) resPtr, request->query, PAYLOAD_TYPE_REPRESENTATION, request->payload, request->payloadSize, request->numRcvdVendorSpecificHeaderOptions, request->rcvdVendorSpecificHeaderOptions, OC_OBSERVE_NO_OPTION, 0); if(result == OC_STACK_OK) { ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest, resPtr->entityHandlerCallbackParam); if(ehResult == OC_EH_ERROR) { FindAndDeleteServerRequest(request); } } OCPayloadDestroy(ehRequest.payload); } } #ifdef WITH_PRESENCE } else { OCEntityHandlerResponse ehResponse = {0}; //This is effectively the implementation for the presence entity handler. OC_LOG(DEBUG, TAG, "This notification is for Presence"); result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET, 0, resPtr->sequenceNum, qos, resourceObserver->query, NULL, NULL, resourceObserver->token, resourceObserver->tokenLength, resourceObserver->resUri, 0, resourceObserver->acceptFormat, &resourceObserver->devAddr); if(result == OC_STACK_OK) { OCPresencePayload* presenceResBuf = OCPresencePayloadCreate( resPtr->sequenceNum, maxAge, trigger, resourceType ? resourceType->resourcetypename : NULL); if(!presenceResBuf) { return OC_STACK_NO_MEMORY; } if(result == OC_STACK_OK) { ehResponse.ehResult = OC_EH_OK; ehResponse.payload = (OCPayload*)presenceResBuf; ehResponse.persistentBufferFlag = 0; ehResponse.requestHandle = (OCRequestHandle) request; ehResponse.resourceHandle = (OCResourceHandle) resPtr; OICStrcpy(ehResponse.resourceUri, sizeof(ehResponse.resourceUri), resourceObserver->resUri); result = OCDoResponse(&ehResponse); } OCPresencePayloadDestroy(presenceResBuf); } } #endif // Since we are in a loop, set an error flag to indicate at least one error occurred. if (result != OC_STACK_OK) { observeErrorFlag = true; } } resourceObserver = resourceObserver->next; } if (numObs == 0) { OC_LOG(INFO, TAG, "Resource has no observers"); result = OC_STACK_NO_OBSERVERS; } else if (observeErrorFlag) { OC_LOG(ERROR, TAG, "Observer notification error"); result = OC_STACK_ERROR; } return result; }