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