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