X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=service%2Fnotification%2Fsrc%2Fprovider%2FNSProviderTopic.c;h=e398e65acfe1b9179984ac8f67439cc1a3569c55;hb=5479d22c2eab0b2055f2b05c8ad8fef576950b84;hp=93577d8c4ed4e73ba82ed327d3ebddb46a4ce6e8;hpb=6583b09dde1ff496a1b4a14d3acef64f9a47cdc8;p=platform%2Fupstream%2Fiotivity.git diff --git a/service/notification/src/provider/NSProviderTopic.c b/service/notification/src/provider/NSProviderTopic.c index 93577d8..e398e65 100644 --- a/service/notification/src/provider/NSProviderTopic.c +++ b/service/notification/src/provider/NSProviderTopic.c @@ -19,70 +19,71 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "NSProviderTopic.h" +#include "oic_string.h" +#include "oic_malloc.h" +#include -static bool isTopicList = false; - -NSResult NSStoreTopics(const char * topicName); NSResult NSSendTopicUpdation(); NSResult NSInitTopicList() { NS_LOG(DEBUG, "NSInitTopicList - IN"); - if(isTopicList) - { - NS_LOG(DEBUG, "topic list has already initiated"); - return NS_FAIL; - } - - consumerTopicList = NSStorageCreate(); + consumerTopicList = NSProviderStorageCreate(); + NS_VERIFY_NOT_NULL(consumerTopicList, NS_FAIL); consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME; - registeredTopicList = NSStorageCreate(); + registeredTopicList = NSProviderStorageCreate(); + NS_VERIFY_NOT_NULL(registeredTopicList, NS_FAIL); registeredTopicList->cacheType = NS_PROVIDER_CACHE_REGISTER_TOPIC; - isTopicList = true; - NS_LOG(DEBUG, "NSInitTopicList - OUT"); return NS_OK; } -NSTopicList * NSGetTopics(char *consumerId) +size_t NSProviderGetTopicListSize(NSTopicLL * firstElement) { - NS_LOG(DEBUG, "NSGetTopics()"); - - NSTopicList * topicList; - - if(consumerId == NULL) + if (!firstElement) { - NS_LOG(DEBUG, "All registered topic list"); - //TODO: get registered topic list + return 0; } - else + + int cnt = 0; + + NSTopicLL * iter = firstElement; + + while (iter) { - NS_LOG_V(DEBUG, "Subscribed topic list for consumerId(%s)", consumerId); - //TODO: get subscribed topic list for consumer + cnt++; + iter = iter->next; } - NS_LOG(DEBUG, "NSGetTopics() NS_OK"); - return topicList; + return cnt; } -NSResult NSAddTopics(const char * topicName) +NSResult NSRegisterTopic(const char * topicName) { NS_LOG(DEBUG, "NSWriteTopicsToStorage()"); - NSCacheTopicData * data = (NSCacheTopicData *)OICMalloc(sizeof(NSCacheTopicData)); - data->topicName = topicName; + NSCacheTopicData * data = (NSCacheTopicData *) OICMalloc(sizeof(NSCacheTopicData)); + NS_VERIFY_NOT_NULL(data, NS_FAIL); + data->topicName = (char *) topicName; data->state = NS_TOPIC_UNSUBSCRIBED; NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement)); + if (!element) + { + OICFree(data->topicName); + OICFree(data); + return NS_FAIL; + } element->data = (void *) data; element->next = NULL; - if(NSStorageWrite(registeredTopicList, element) != NS_OK) + if(NSProviderStorageWrite(registeredTopicList, element) != NS_OK) { NS_LOG(DEBUG, "fail to write cache"); + return NS_FAIL; } NSSendTopicUpdation(); @@ -90,50 +91,28 @@ NSResult NSAddTopics(const char * topicName) return NS_OK; } -NSResult NSDeleteTopics(const char * topicName) +NSResult NSUnregisterTopic(const char * topicName) { NS_LOG(DEBUG, "NSDeleteTopics()"); + NSResult result = NS_OK; - if(!topicName) + if (!topicName) { NS_LOG(ERROR, "topicName is NULL"); return NS_ERROR; } - NSStorageDelete(registeredTopicList, topicName); - while(NSStorageDelete(consumerTopicList, topicName) != NS_FAIL); - - return NS_OK; -} - -NSResult NSSubscribeTopicList(char *consumerId, NSTopicList *topicList) -{ - NS_LOG(DEBUG, "NSSubscribeTopicList()"); - - if(!topicList) + result = NSProviderStorageDelete(registeredTopicList, topicName); + while (NSProviderStorageDelete(consumerTopicList, topicName) != NS_FAIL) { - NS_LOG(ERROR, "no topics"); - return NS_ERROR; } - if(!consumerId) + if (result == NS_OK) { - NS_LOG(ERROR, "invalid consumer id"); - return NS_ERROR; + NSSendTopicUpdation(); } - OCResourceHandle rHandle = NULL; - if(NSPutTopicResource(topicList, &rHandle) != NS_OK) - { - NS_LOG(ERROR, "Fail to put topic resource"); - return NS_ERROR; - } - - //TODO it will change logic. - //NSStoreTopics(consumerId, topicList->head); - - NS_LOG(DEBUG, "NSSubscribeTopicList() NS_OK"); - return NS_OK; + return result; } NSResult NSSendTopicUpdation() @@ -159,7 +138,8 @@ NSResult NSSendTopicUpdation() OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC); OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId); - OCObservationId obArray[255] = { 0, }; + OCObservationId obArray[255] = + { 0, }; int obCount = 0; NSCacheElement * it = consumerSubList->head; @@ -170,30 +150,28 @@ NSResult NSSendTopicUpdation() if (subData->isWhite) { - if(subData->messageObId != 0) + if (subData->messageObId != 0) { obArray[obCount++] = subData->messageObId; } -#ifdef WITH_CLOUD +#if(defined WITH_CLOUD && defined RD_CLIENT) if(subData->remote_messageObId != 0) { obArray[obCount++] = subData->remote_messageObId; } #endif - } it = it->next; } - if(!obCount) + if (!obCount) { NS_LOG(ERROR, "observer count is zero"); return NS_ERROR; } - if (OCNotifyListOfObservers(rHandle, obArray, obCount, payload, OC_HIGH_QOS) - != OC_STACK_OK) + if (OCNotifyListOfObservers(rHandle, obArray, obCount, payload, OC_HIGH_QOS) != OC_STACK_OK) { NS_LOG(ERROR, "fail to send topic updation"); OCRepPayloadDestroy(payload); @@ -229,9 +207,9 @@ NSResult NSSendTopicUpdationToConsumer(char *consumerId) OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC); OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId); - NSCacheElement * element = NSStorageRead(consumerSubList, consumerId); + NSCacheElement * element = NSProviderStorageRead(consumerSubList, consumerId); - if(element == NULL) + if (element == NULL) { NS_LOG(ERROR, "element is NULL"); return NS_ERROR; @@ -239,13 +217,12 @@ NSResult NSSendTopicUpdationToConsumer(char *consumerId) NSCacheSubData * subData = (NSCacheSubData*) element->data; - if (OCNotifyListOfObservers(rHandle, (OCObservationId*)&subData->messageObId, 1, payload, OC_HIGH_QOS) - != OC_STACK_OK) + if (OCNotifyListOfObservers(rHandle, (OCObservationId*) &subData->messageObId, 1, payload, + OC_HIGH_QOS) != OC_STACK_OK) { NS_LOG(ERROR, "fail to send topic updation"); OCRepPayloadDestroy(payload); return NS_ERROR; - } OCRepPayloadDestroy(payload); @@ -259,17 +236,21 @@ NSResult NSSendTopicList(OCEntityHandlerRequest * entityHandlerRequest) NS_LOG(DEBUG, "NSSendTopicList - IN"); char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID); - if(!id) + NSTopicLL * topics = NULL; + + if (!id) { NS_LOG(DEBUG, "Send registered topic list"); - //TODO: get registered topic list - // NSGetTopics(NULL); + topics = NSProviderGetTopicsCacheData(registeredTopicList); } else { NS_LOG(DEBUG, "Send subscribed topic list to consumer"); - //TODO: get subscribed topic list for consumer - // NSGetTopics(consumerid); + topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList, consumerTopicList, id); + if (!topics) + { + topics = NSProviderGetTopicsCacheData(registeredTopicList); + } } // make response for the Get Request @@ -286,28 +267,68 @@ NSResult NSSendTopicList(OCEntityHandlerRequest * entityHandlerRequest) return NS_ERROR; } - // set topics to the array of resource property - const int TOPIC_MAX_SIZE = 100; - int dimensions = 0; - OCRepPayload* payloadTopicArray[TOPIC_MAX_SIZE]; - //TODO: use while(NSTopicList) - OCRepPayload* payloadTopic1; - OCRepPayload* payloadTopic2; + OCRepPayloadSetUri(payload, NS_COLLECTION_TOPIC_URI); + if (id) + { + OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, id); + } + OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId); + + if (topics) + { + NS_LOG(DEBUG, "topicList is NULL"); + size_t dimensionSize = (size_t) NSProviderGetTopicListSize(topics); - OCRepPayloadSetPropString(payloadTopic1, NS_ATTRIBUTE_TOPIC_NAME, "test topic name1"); - OCRepPayloadSetPropBool(payloadTopic1, NS_ATTRIBUTE_TOPIC_SELECTION, true); + NS_LOG_V(DEBUG, "dimensionSize = %d", (int)dimensionSize); - OCRepPayloadSetPropString(payloadTopic2, NS_ATTRIBUTE_TOPIC_NAME, "test topic name2"); - OCRepPayloadSetPropBool(payloadTopic2, NS_ATTRIBUTE_TOPIC_SELECTION, false); + if (!dimensionSize) + { + return NS_ERROR; + } - payloadTopicArray[dimensions++] = payloadTopic1; - payloadTopicArray[dimensions++] = payloadTopic2; - // end of set topics + OCRepPayload** payloadTopicArray = (OCRepPayload **) OICMalloc( + sizeof(OCRepPayload *) * dimensionSize); + NS_VERIFY_NOT_NULL(payloadTopicArray, NS_ERROR); - OCRepPayloadSetUri(payload, NS_COLLECTION_TOPIC_URI); - OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, id); - // TODO: add PayLoadSet with topic list got above - OCRepPayloadSetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, (const OCRepPayload**)(payloadTopicArray), dimensions); + size_t dimensions[3] = + { dimensionSize, 0, 0 }; + + for (int i = 0; i < (int) dimensionSize; i++) + { + NS_LOG_V(DEBUG, "topicName = %s", topics->topicName); + NS_LOG_V(DEBUG, "topicState = %d",(int) topics->state); + + payloadTopicArray[i] = OCRepPayloadCreate(); + NS_VERIFY_NOT_NULL(payloadTopicArray[i], NS_ERROR); + OCRepPayloadSetPropString(payloadTopicArray[i], NS_ATTRIBUTE_TOPIC_NAME, + topics->topicName); + OCRepPayloadSetPropInt(payloadTopicArray[i], NS_ATTRIBUTE_TOPIC_SELECTION, + (int) topics->state); + + topics = topics->next; + } + + OCRepPayloadSetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, + (const OCRepPayload**) (payloadTopicArray), dimensions); + } + else + { + size_t dimensions[3] = + { 0, 0, 0 }; + + OCRepPayloadSetPropObjectArrayAsOwner(payload, NS_ATTRIBUTE_TOPIC_LIST, + (OCRepPayload **) NULL, dimensions); + } + + char * reqInterface = + NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_INTERFACE); + + if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) == 0) + { + OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_BASELINE); + OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READ); + OCResourcePayloadAddStringLL(&payload->types, NS_ROOT_TYPE); + } response.requestHandle = entityHandlerRequest->requestHandle; response.resourceHandle = entityHandlerRequest->resource; @@ -315,23 +336,85 @@ NSResult NSSendTopicList(OCEntityHandlerRequest * entityHandlerRequest) response.ehResult = OC_EH_OK; response.payload = (OCPayload *) payload; - // Send Response if (OCDoResponse(&response) != OC_STACK_OK) { NS_LOG(ERROR, "Fail to response topic list"); return NS_ERROR; } OCRepPayloadDestroy(payload); - NSFreeOCEntityHandlerRequest(entityHandlerRequest); NS_LOG(DEBUG, "NSSendTopicList - OUT"); return NS_OK; } -bool NSIsTopicSubscribed(char * consumerId, char * topic) +NSResult NSPostConsumerTopics(OCEntityHandlerRequest * entityHandlerRequest) { - //TODO: implement function - return true; + NS_LOG(DEBUG, "NSPostConsumerTopics() - IN"); + + char * consumerId = NULL; + OCRepPayload * payload = (OCRepPayload *) entityHandlerRequest->payload; + OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, &consumerId); + + if (!consumerId) + { + NS_LOG(DEBUG, "Invalid consumer ID"); + return NS_FAIL; + } + + NS_LOG_V(DEBUG, "TOPIC consumer ID = %s", consumerId); + + consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID; + + while (NSProviderStorageDelete(consumerTopicList, consumerId) != NS_FAIL) + { + } + consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME; + + OCRepPayload ** topicListPayload = NULL; + OCRepPayloadValue * payloadValue = NULL; + payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST); + size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions); + size_t dimensions[3] = { dimensionSize, 0, 0 }; + OCRepPayloadGetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, &topicListPayload, dimensions); + + for (int i = 0; i < (int) dimensionSize; i++) + { + char * topicName = NULL; + int64_t topicState = 0; + + OCRepPayloadGetPropString(topicListPayload[i], NS_ATTRIBUTE_TOPIC_NAME, &topicName); + OCRepPayloadGetPropInt(topicListPayload[i], NS_ATTRIBUTE_TOPIC_SELECTION, &topicState); + NS_LOG_V(DEBUG, "Topic Name(state): %s(%d)", topicName, (int)topicState); + + if (NS_TOPIC_SUBSCRIBED == (NSTopicState) topicState) + { + NSCacheTopicSubData * topicSubData = (NSCacheTopicSubData *) OICMalloc( + sizeof(NSCacheTopicSubData)); + NS_VERIFY_NOT_NULL(topicSubData, NS_FAIL); + + OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId); + topicSubData->topicName = topicName; + + NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement)); + + if (!newObj) + { + OICFree(topicSubData->topicName); + OICFree(topicSubData); + OICFree(consumerId); + return NS_FAIL; + } + + newObj->data = (NSCacheData *) topicSubData; + newObj->next = NULL; + + NSProviderStorageWrite(consumerTopicList, newObj); + } + } + NSSendTopicUpdationToConsumer(consumerId); + OICFree(consumerId); + NS_LOG(DEBUG, "NSPostConsumerTopics() - OUT"); + return NS_OK; } void * NSTopicSchedule(void * ptr) @@ -356,30 +439,89 @@ void * NSTopicSchedule(void * ptr) case TASK_SEND_TOPICS: NS_LOG(DEBUG, "CASE TASK_SEND_TOPICS : "); NSSendTopicList((OCEntityHandlerRequest*) node->taskData); + NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData); break; case TASK_SUBSCRIBE_TOPIC: + { NS_LOG(DEBUG, "CASE TASK_SUBSCRIBE_TOPIC : "); NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement)); - newObj->data = node->taskData; - newObj->next = NULL; - NSStorageWrite(consumerTopicList, newObj); + if (newObj) + { + newObj->data = node->taskData; + newObj->next = NULL; + if (NSProviderStorageWrite(consumerTopicList, newObj) == NS_OK) + { + NSCacheTopicSubData * topicSubData = + (NSCacheTopicSubData *) node->taskData; + NSSendTopicUpdationToConsumer(topicSubData->id); + } + } + } break; case TASK_UNSUBSCRIBE_TOPIC: - consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID; - NSStorageDelete(consumerTopicList, (const char *) node->taskData); - consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME; - OICFree((char *)node->taskData); + { + NS_LOG(DEBUG, "CASE TASK_SUBSCRIBE_TOPIC : "); + NSCacheTopicSubData * topicSubData = (NSCacheTopicSubData *) node->taskData; + if (NSProviderDeleteConsumerTopic(consumerTopicList, + (NSCacheTopicSubData *) node->taskData) == NS_OK) + { + NSSendTopicUpdationToConsumer(topicSubData->id); + } + OICFree(topicSubData->topicName); + OICFree(topicSubData); + } break; - case TASK_ADD_TOPIC: + case TASK_REGISTER_TOPIC: { NS_LOG(DEBUG, "CASE TASK_ADD_TOPIC : "); - NSAddTopics((const char *) node->taskData); + NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData; + + pthread_mutex_lock(topicSyncResult->mutex); + topicSyncResult->result = NSRegisterTopic( + (const char *) topicSyncResult->topicName); + pthread_cond_signal(topicSyncResult->condition); + pthread_mutex_unlock(topicSyncResult->mutex); } break; - case TASK_DELETE_TOPIC: + case TASK_UNREGISTER_TOPIC: { NS_LOG(DEBUG, "CASE_TASK_DELETE_TOPIC : "); - NSDeleteTopics((const char *) node->taskData); + NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData; + pthread_mutex_lock(topicSyncResult->mutex); + topicSyncResult->result = NSUnregisterTopic( + (const char *) topicSyncResult->topicName); + pthread_cond_signal(topicSyncResult->condition); + pthread_mutex_unlock(topicSyncResult->mutex); + } + break; + case TASK_POST_TOPIC: + { + NS_LOG(DEBUG, "TASK_POST_TOPIC : "); + NSPostConsumerTopics((OCEntityHandlerRequest*) node->taskData); + NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData); + } + break; + case TASK_GET_TOPICS: + { + NS_LOG(DEBUG, "TASK_GET_TOPICS : "); + NSTopicSync * topicSync = (NSTopicSync *) node->taskData; + pthread_mutex_lock(topicSync->mutex); + NSTopicLL * topics = NSProviderGetTopicsCacheData(registeredTopicList); + topicSync->topics = topics; + pthread_cond_signal(topicSync->condition); + pthread_mutex_unlock(topicSync->mutex); + } + break; + case TAST_GET_CONSUMER_TOPICS: + { + NS_LOG(DEBUG, "TASK_GET_CONSUMER_TOPICS : "); + NSTopicSync * topicSync = (NSTopicSync *) node->taskData; + pthread_mutex_lock(topicSync->mutex); + NSTopicLL * topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList, + consumerTopicList, topicSync->consumerId); + topicSync->topics = topics; + pthread_cond_signal(topicSync->condition); + pthread_mutex_unlock(topicSync->mutex); } break; default: