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