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