OCStackResult GenerateObserverId (OCObservationId *observationId) { ResourceObserver *resObs = NULL; OC_LOG(INFO, TAG, PCF("Entering GenerateObserverId")); VERIFY_NON_NULL (observationId); do { *observationId = OCGetRandomByte(); // Check if observation Id already exists resObs = GetObserverUsingId (*observationId); } while (NULL != resObs); OC_LOG_V(INFO, TAG, "Observation ID is %u", *observationId); return OC_STACK_OK; exit: 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 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; } }