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