fix issue related to wrong messageId
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderNotification.c
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "NSProviderNotification.h"
22
23 NSResult NSSetMessagePayload(NSMessage *msg, OCRepPayload** msgPayload)
24 {
25     NS_LOG(DEBUG, "NSSetMessagePayload - IN");
26
27     *msgPayload = msg->extraInfo != NULL ? msg->extraInfo : OCRepPayloadCreate();
28
29     if (!*msgPayload)
30     {
31         NS_LOG(ERROR, "Failed to allocate payload");
32         return NS_ERROR;
33     }
34
35     OCRepPayloadSetUri(*msgPayload, NS_COLLECTION_MESSAGE_URI);
36     OCRepPayloadSetPropInt(*msgPayload, NS_ATTRIBUTE_MESSAGE_ID, msg->messageId);
37     OCRepPayloadSetPropString(*msgPayload, NS_ATTRIBUTE_PROVIDER_ID, msg->providerId);
38
39     NSDuplicateSetPropertyInt(msgPayload, NS_ATTRIBUTE_TYPE, msg->type);
40     NSDuplicateSetPropertyInt(msgPayload, NS_ATTRIBUTE_TTL, msg->ttl);
41     NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_DATETIME, msg->dateTime);
42     NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_TITLE, msg->title);
43     NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_TEXT, msg->contentText);
44     NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_SOURCE, msg->sourceName);
45     NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_TOPIC_NAME, msg->topic);
46
47     if (msg->mediaContents)
48     {
49         NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_ICON_IMAGE,
50                 msg->mediaContents->iconImage);
51     }
52
53     NS_LOG(DEBUG, "NSSetMessagePayload - OUT");
54     return NS_OK;
55 }
56
57 NSResult NSSetSyncPayload(NSSyncInfo *sync, OCRepPayload** syncPayload)
58 {
59     NS_LOG(DEBUG, "NSSetSyncPayload - IN");
60
61     *syncPayload = OCRepPayloadCreate();
62
63     if (!*syncPayload)
64     {
65         NS_LOG(ERROR, "Failed to allocate payload");
66         return NS_ERROR;
67     }
68
69     OCRepPayloadSetUri(*syncPayload, NS_COLLECTION_SYNC_URI);
70
71     OCRepPayloadSetPropString(*syncPayload, NS_ATTRIBUTE_PROVIDER_ID, sync->providerId);
72     OCRepPayloadSetPropInt(*syncPayload, NS_ATTRIBUTE_MESSAGE_ID, sync->messageId);
73     OCRepPayloadSetPropInt(*syncPayload, NS_ATTRIBUTE_STATE, sync->state);
74
75     NS_LOG(DEBUG, "NSSetSyncPayload - OUT");
76     return NS_OK;
77 }
78
79 NSResult NSSendNotification(NSMessage *msg)
80 {
81     NS_LOG(DEBUG, "NSSendMessage - IN");
82
83     OCResourceHandle rHandle;
84     OCObservationId obArray[255] = { 0, };
85     int obCount = 0, i;
86
87     if (NSPutMessageResource(msg, &rHandle) != NS_OK)
88     {
89         NS_LOG(ERROR, "fail to Put notification resource");
90         return NS_ERROR;
91     }
92
93     if (consumerSubList->head == NULL)
94     {
95         NS_LOG(ERROR, "SubList->head is NULL, empty SubList");
96         return NS_ERROR;
97     }
98
99     OCRepPayload* payload = NULL;
100
101     if (NSSetMessagePayload(msg, &payload) != NS_OK)
102     {
103         NS_LOG(ERROR, "fail to Get message payload");
104         return NS_ERROR;
105     }
106
107     NSCacheElement * it = consumerSubList->head;
108
109     while (it)
110     {
111         NSCacheSubData * subData = (NSCacheSubData *) it->data;
112         NS_LOG_V(DEBUG, "message subData->id = %s", subData->id);
113         NS_LOG_V(DEBUG, "subData->messageId = %d", subData->messageObId);
114         NS_LOG_V(DEBUG, "subData->cloud_messageId = %d", subData->remote_messageObId);
115         NS_LOG_V(DEBUG, "subData->syncId = %d", subData->syncObId);
116         NS_LOG_V(DEBUG, "subData->cloud_syncId = %d", subData->remote_syncObId);
117         NS_LOG_V(DEBUG, "subData->isWhite = %d", subData->isWhite);
118
119         if (subData->isWhite)
120         {
121             if(subData->messageObId != 0)
122             {
123                 if(msg->topic && (msg->topic)[0] != '\0')
124                 {
125                     NS_LOG_V(DEBUG, "this is topic message: %s", msg->topic);
126
127                     if(NSProviderIsTopicSubScribed(consumerTopicList->head, subData->id, msg->topic))
128                     {
129                         obArray[obCount++] = subData->messageObId;
130                     }
131                 }
132                 else
133                 {
134                     obArray[obCount++] = subData->messageObId;
135                 }
136             }
137
138 #if(defined WITH_CLOUD && defined RD_CLIENT)
139             if(subData->remote_messageObId != 0)
140             {
141                 if(msg->topic && (msg->topic)[0] != '\0')
142                 {
143                     NS_LOG_V(DEBUG, "this is topic message via remote server: %s", msg->topic);
144                     if(NSProviderIsTopicSubScribed(consumerTopicList->head, subData->id, msg->topic))
145                     {
146                         obArray[obCount++] = subData->remote_messageObId;
147                     }
148                 }
149                 else
150                 {
151                     obArray[obCount++] = subData->remote_messageObId;
152                 }
153             }
154 #endif
155
156         }
157         it = it->next;
158     }
159
160     for (i = 0; i < obCount; ++i)
161     {
162         NS_LOG(DEBUG, "-------------------------------------------------------message\n");
163         NS_LOG_V(DEBUG, "SubScription WhiteList[%d] = %d", i, obArray[i]);
164         NS_LOG(DEBUG, "-------------------------------------------------------message\n");
165     }
166
167     if(!obCount)
168     {
169         NS_LOG(ERROR, "observer count is zero");
170         return NS_ERROR;
171     }
172
173     OCStackResult ocstackResult = OCNotifyListOfObservers(rHandle, obArray, obCount, payload,
174             OC_LOW_QOS);
175
176     NS_LOG_V(DEBUG, "Message ocstackResult = %d", ocstackResult);
177
178     if (ocstackResult != OC_STACK_OK)
179     {
180         NS_LOG(ERROR, "fail to send message");
181         OCRepPayloadDestroy(payload);
182         msg->extraInfo = NULL;
183         return NS_ERROR;
184     }
185
186     OCRepPayloadDestroy(payload);
187     msg->extraInfo = NULL;
188
189     NS_LOG(DEBUG, "NSSendMessage - OUT");
190     return NS_OK;
191 }
192
193 NSResult NSSendSync(NSSyncInfo *sync)
194 {
195     NS_LOG(DEBUG, "NSSendSync - IN");
196
197     OCObservationId obArray[255] = { 0, };
198     int obCount = 0;
199     int i;
200
201     OCResourceHandle rHandle;
202     if (NSPutSyncResource(sync, &rHandle) != NS_OK)
203     {
204         NS_LOG(ERROR, PCF("Fail to put sync resource"));
205         return NS_ERROR;
206     }
207
208     NSCacheElement * it = consumerSubList->head;
209
210     while (it)
211     {
212         NSCacheSubData * subData = (NSCacheSubData *) it->data;
213         NS_LOG_V(DEBUG, "sync subData->id = %s", subData->id);
214         NS_LOG_V(DEBUG, "subData->messageId = %d", subData->messageObId);
215         NS_LOG_V(DEBUG, "subData->cloud_messageId = %d", subData->remote_messageObId);
216         NS_LOG_V(DEBUG, "subData->syncId = %d", subData->syncObId);
217         NS_LOG_V(DEBUG, "subData->cloud_syncId = %d", subData->remote_syncObId);
218         NS_LOG_V(DEBUG, "subData->isWhite = %d", subData->isWhite);
219
220         if (subData->isWhite)
221         {
222             if(subData->syncObId != 0)
223             {
224                 obArray[obCount++] = subData->syncObId;
225             }
226
227 #if(defined WITH_CLOUD && defined RD_CLIENT)
228             if(subData->remote_syncObId != 0)
229             {
230                 obArray[obCount++] = subData->remote_syncObId;
231             }
232 #endif
233         }
234         it = it->next;
235     }
236
237     OCRepPayload* payload;
238     if (NSSetSyncPayload(sync, &payload) != NS_OK)
239     {
240         NS_LOG(ERROR, "Failed to allocate payload");
241         return NS_ERROR;
242     }
243
244     for (i = 0; i < obCount; ++i)
245     {
246         NS_LOG(DEBUG, "-------------------------------------------------------message\n");
247         NS_LOG_V(DEBUG, "Sync WhiteList[%d] = %d", i, obArray[i]);
248         NS_LOG(DEBUG, "-------------------------------------------------------message\n");
249     }
250
251     OCStackResult ocstackResult = OCNotifyListOfObservers(rHandle, obArray,
252             obCount, payload, OC_LOW_QOS);
253
254     NS_LOG_V(DEBUG, "Sync ocstackResult = %d", ocstackResult);
255
256     if (ocstackResult != OC_STACK_OK)
257     {
258         NS_LOG(ERROR, "fail to send Sync");
259         OCRepPayloadDestroy(payload);
260         return NS_ERROR;
261     }
262
263     OCRepPayloadDestroy(payload);
264
265     NS_LOG(DEBUG, "NSSendSync - OUT");
266     return NS_OK;
267 }
268
269 void * NSNotificationSchedule(void *ptr)
270 {
271     if (ptr == NULL)
272     {
273         NS_LOG(DEBUG, "Create NSNotifiactionSchedule");
274     }
275
276     while (NSIsRunning[NOTIFICATION_SCHEDULER])
277     {
278         sem_wait(&NSSemaphore[NOTIFICATION_SCHEDULER]);
279         pthread_mutex_lock(&NSMutex[NOTIFICATION_SCHEDULER]);
280
281         if (NSHeadMsg[NOTIFICATION_SCHEDULER] != NULL)
282         {
283             NSTask *node = NSHeadMsg[NOTIFICATION_SCHEDULER];
284             NSHeadMsg[NOTIFICATION_SCHEDULER] = node->nextTask;
285
286             switch (node->taskType)
287             {
288                 case TASK_SEND_NOTIFICATION:
289                 {
290                     NS_LOG(DEBUG, "CASE TASK_SEND_NOTIFICATION : ");
291                     NSSendNotification((NSMessage *)node->taskData);
292                     NSFreeMessage((NSMessage *)node->taskData);
293                 }
294                     break;
295                 case TASK_SEND_READ:
296                     NS_LOG(DEBUG, "CASE TASK_SEND_READ : ");
297                     NSSendSync((NSSyncInfo*) node->taskData);
298                     NSFreeSync((NSSyncInfo*) node->taskData);
299                     break;
300                 case TASK_RECV_READ:
301                     NS_LOG(DEBUG, "CASE TASK_RECV_READ : ");
302                     NSSendSync((NSSyncInfo*) node->taskData);
303                     NSPushQueue(CALLBACK_RESPONSE_SCHEDULER, TASK_CB_SYNC, node->taskData);
304                     break;
305                 default:
306                     NS_LOG(ERROR, "Unknown type message");
307                     break;
308
309             }
310             OICFree(node);
311         }
312
313         pthread_mutex_unlock(&NSMutex[NOTIFICATION_SCHEDULER]);
314
315     }
316
317     NS_LOG(INFO, "Destroy NSNotificationSchedule");
318     return NULL;
319 }