added cacheadapter interface and memorycache of notification.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerNotification.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 "NSConsumerNotification.h"
22
23 #include "NSConstants.h"
24 #include "NSConsumerCommon.h"
25 #include "oic_malloc.h"
26 #include "oic_string.h"
27 #include "ocpayload.h"
28
29 NSMessage_consumer * NSBuildOICNotification(OCClientResponse * clientResponse);
30 NSSync * NSBuildOICNotificationSync(OCClientResponse * clientResponse);
31
32 NSProvider * NSGetProvider(OCClientResponse * clientResponse);
33 NSResult NSPushToCache(OCClientResponse * clientResponse, NSTaskType type);
34
35 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
36 {
37     if (OC_STACK_OK != NSRequestToResourceIntrospection(&(provider->messageHandle),
38             OC_REST_OBSERVE, (OCDevAddr *) provider->mUserData,
39             provider->messageUri, NULL, NSConsumerNotificationListener))
40     {
41         return NS_ERROR;
42     }
43
44     if (OC_STACK_OK != NSRequestToResourceIntrospection(&(provider->syncHandle),
45             OC_REST_OBSERVE, (OCDevAddr *) provider->mUserData,
46             provider->syncUri, NULL, NSConsumerSyncListener))
47     {
48         return NS_ERROR;
49     }
50
51     return NS_OK;
52 }
53
54 NSResult NSConsumerPostProvider(OCDevAddr * addr, OCPayload * payload, const char * uri)
55 {
56
57     if (OC_STACK_OK != NSRequestToResourceIntrospection(NULL, OC_REST_POST, addr,
58             uri, payload, NULL))
59     {
60         return NS_ERROR;
61     }
62
63     return NS_OK;
64 }
65
66 OCStackApplicationResult NSConsumerSyncListener(
67         OCDoHandle handle, OCClientResponse * clientResponse)
68 {
69     (void) handle;
70
71     NSSync * newNoti = NULL;
72     NSProvider * provider = NSGetProvider(clientResponse);
73     if (!provider)
74     {
75         NS_LOG(ERROR, "getting provider is failed");
76         return OC_STACK_KEEP_TRANSACTION;
77     }
78
79     newNoti = NSBuildOICNotificationSync(clientResponse);
80     if (!newNoti)
81     {
82         return OC_STACK_KEEP_TRANSACTION;
83     }
84
85     NSTaskType taskType = TASK_RECV_READ;
86
87     if (newNoti->mState != Notification_Read)
88     {
89         NS_LOG(DEBUG, "newNoti->type : Dismiss");
90         taskType = TASK_RECV_DISMISS;
91     }
92     else
93     {
94         NS_LOG(DEBUG, "newNoti->type : Read");
95     }
96
97     NSNotificationSync(provider, newNoti);
98
99     if (NS_OK != NSPushToCache(clientResponse, taskType))
100     {
101         return OC_STACK_KEEP_TRANSACTION;
102     }
103
104     return OC_STACK_KEEP_TRANSACTION;
105 }
106
107 OCStackApplicationResult NSConsumerNotificationListener(
108         OCDoHandle handle, OCClientResponse * clientResponse)
109 {
110     (void) handle;
111
112     NSProvider * provider = NSGetProvider(clientResponse);
113     if (!provider)
114     {
115         NS_LOG(ERROR, "getting provider is failed");
116         return OC_STACK_KEEP_TRANSACTION;
117     }
118
119     NSMessage_consumer * newNoti = NSBuildOICNotification(clientResponse);
120     if (!newNoti)
121     {
122         return OC_STACK_KEEP_TRANSACTION;
123     }
124
125     NSTaskType taskType = TASK_CONSUMER_RECV_NOTIFICATION;
126
127     NS_LOG(DEBUG, "newNoti->type == Notification");
128     NSNotificationPost(provider, (NSMessage *) newNoti);
129
130     if (NS_OK != NSPushToCache(clientResponse, taskType))
131     {
132         NSRemoveMessage(newNoti);
133         return OC_STACK_KEEP_TRANSACTION;
134     }
135
136     return OC_STACK_KEEP_TRANSACTION;
137 }
138
139 NSResult NSPushToCache(OCClientResponse * clientResponse, NSTaskType type)
140 {
141     NSMessage_consumer * cachedNoti = NSBuildOICNotification(clientResponse);
142     if (!cachedNoti)
143     {
144         return NS_ERROR;
145     }
146     NSTask * task = NSMakeTask(type, (void *) cachedNoti);
147     if (!task)
148     {
149         NS_LOG(ERROR, "NSTask allocation fail");
150         NSRemoveMessage(cachedNoti);
151         return NS_ERROR;
152     }
153     NSConsumerPushEvent(task);
154
155     return NS_OK;
156 }
157
158 NSMessage_consumer * NSBuildOICNotification(OCClientResponse * clientResponse)
159 {
160     if(!clientResponse->payload)
161     {
162         return NULL;
163     }
164
165     NSMessage_consumer * retNoti = (NSMessage_consumer *)OICMalloc(sizeof(NSMessage_consumer));
166     if (!retNoti)
167     {
168         return NULL;
169     }
170
171     retNoti->mId = NULL;
172     retNoti->mTitle = NULL;
173     retNoti->mContentText = NULL;
174
175     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
176     if (!OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_ID, &retNoti->mId))
177     {
178         NS_LOG(ERROR, "id of received notification is null");
179         OICFree(retNoti);
180         return NULL;
181     }
182
183     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retNoti->mTitle);
184     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retNoti->mContentText);
185
186     NS_LOG_V(DEBUG, "Msg Address : %s", clientResponse->addr->addr);
187     NS_LOG_V(DEBUG, "Msg ID : %s", retNoti->mId);
188     NS_LOG_V(DEBUG, "Msg Title : %s", retNoti->mTitle);
189     NS_LOG_V(DEBUG, "Msg Content : %s", retNoti->mContentText);
190
191     retNoti->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
192     memcpy(retNoti->addr, clientResponse->addr, sizeof(OCDevAddr));
193
194     retNoti->type = Notification;
195
196     return retNoti;
197 }
198
199 NSSync * NSBuildOICNotificationSync(OCClientResponse * clientResponse)
200 {
201     if(!clientResponse->payload)
202     {
203         return NULL;
204     }
205     NSSync * retSync = (NSSync *)OICMalloc(sizeof(NSSync));
206     if (!retSync)
207     {
208         return NULL;
209     }
210
211     retSync->mMessageId = NULL;
212     retSync->mState = Notification_Read;
213
214     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
215     if (!OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_ID, &retSync->mMessageId))
216     {
217         NS_LOG(ERROR, "id of received sync is null");
218         OICFree(retSync);
219         return NULL;
220     }
221     int64_t state;
222     if (!OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state))
223     {
224         NS_LOG(ERROR, "state of received sync is null");
225         OICFree(retSync->mMessageId);
226         OICFree(retSync);
227         return NULL;
228     }
229
230     retSync->mState = (NSSyncTypes) state;
231
232     NS_LOG_V(DEBUG, "Sync ID : %s", retSync->mMessageId);
233     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->mState);
234
235     return retSync;
236 }
237
238 NSProvider * NSGetProvider(OCClientResponse * clientResponse)
239 {
240     NSProvider * newProvider = (NSProvider *)OICMalloc(sizeof(NSProvider));
241     if (!newProvider)
242     {
243         NS_LOG(DEBUG, "NSProvider allocation fail");
244         return NULL;
245     }
246
247     // TODO set id
248     newProvider->mId = NULL;
249     newProvider->mUserData = (void *)OICMalloc(sizeof(OCDevAddr));
250     if (!newProvider->mUserData)
251     {
252         NS_LOG(DEBUG, "OCDevAddr allocation fail");
253         OICFree(newProvider);
254         return NULL;
255     }
256     memcpy(newProvider->mUserData, clientResponse->addr, sizeof(OCDevAddr));
257
258     return newProvider;
259 }
260
261 void NSConsumerNotificationHandleMsg(NSTask * task)
262 {
263     if (!task)
264     {
265         NS_LOG(ERROR, "task is null");
266         return;
267     }
268
269     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
270     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
271     {
272         if (NS_OK != NSConsumerSubscribeProvider((NSProvider *)task->taskData))
273         {
274             NS_LOG(ERROR, "Subscribe fail");
275             return;
276         }
277     }
278     else if (task->taskType == TASK_SEND_READ || task->taskType == TASK_SEND_DISMISS)
279     {
280         NSMessage_consumer * nsConsumer = (NSMessage_consumer *) task->taskData;
281         if (!nsConsumer)
282         {
283             NS_LOG(ERROR, "taskData is NULL");
284             return;
285         }
286
287         OCRepPayload * payload = OCRepPayloadCreate ();
288         if (!payload)
289         {
290             NS_LOG(ERROR, "Failed to create POST payload object");
291             return;
292         }
293
294         int type = (task->taskType == TASK_SEND_READ) ? 0 : 1;
295         OCRepPayloadSetPropString(payload, "ID", (char *) nsConsumer->mId);
296         OCRepPayloadSetPropInt(payload, "STATE", type);
297
298         // TODO fix param for uri
299         if (NS_OK != NSConsumerPostProvider(
300                 (OCDevAddr *) nsConsumer->addr, (OCPayload *) payload, "/notification/sync"))
301         {
302             NS_LOG(ERROR, "Subscribe fail");
303             return;
304         }
305     }
306     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
307     {
308         NSProvider * provider = (NSProvider *)task->taskData;
309
310         OCCancel(provider->messageHandle, NS_QOS, NULL, 0);
311         OCCancel(provider->syncHandle, NS_QOS, NULL, 0);
312     }
313     else
314     {
315         NS_LOG(ERROR, "Unknown type message");
316     }
317 }