Merge branch 'master' into notification-service
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommunication.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 "NSConstants.h"
22 #include "NSConsumerCommon.h"
23 #include "NSConsumerCommunication.h"
24 #include "oic_malloc.h"
25 #include "oic_string.h"
26 #include "ocpayload.h"
27
28 const char NS_MESSAGE_ACCEPTANCE[] = "0000-0000-0000-0000";
29
30 NSMessage_consumer * NSGetNSMessage(OCClientResponse * clientResponse);
31 NSSyncInfo * NSGetNSSyncInfo(OCClientResponse * clientResponse);
32 NSProvider * NSGetNSProvider(OCClientResponse * clientResponse);
33 OCRepPayload * NSGetPayloadofSyncInfo(NSMessage_consumer * message, int type);
34
35
36 NSResult NSPushToCache(OCClientResponse * clientResponse, NSTaskType type);
37
38 OCStackResult NSSendSyncInfo(NSMessage_consumer * message, int type);
39
40 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
41 {
42     OCStackResult ret = NSInvokeRequest(&(provider->messageHandle),
43                           OC_REST_OBSERVE, (OCDevAddr *) provider->mUserData,
44                           provider->messageUri, NULL, NSConsumerMessageListener, NULL);
45     NS_VERTIFY_STACK_OK(ret, NS_ERROR);
46
47     ret = NSInvokeRequest(&(provider->syncHandle),
48                           OC_REST_OBSERVE, (OCDevAddr *) provider->mUserData,
49                           provider->syncUri, NULL, NSConsumerSyncInfoListener, NULL);
50     NS_VERTIFY_STACK_OK(ret, NS_ERROR);
51
52     return NS_OK;
53 }
54
55 OCStackApplicationResult NSConsumerPostResultCheck(
56         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
57 {
58     (void) ctx;
59     (void) handle;
60
61     NS_VERTIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
62     NS_VERTIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
63
64     return OC_STACK_KEEP_TRANSACTION;
65 }
66
67 NSResult NSConsumerPostProvider(OCDevAddr * addr, OCPayload * payload, const char * uri)
68 {
69     OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr, uri, payload,
70                                         NSConsumerPostResultCheck, NULL);
71     NS_VERTIFY_STACK_OK(ret, NS_ERROR);
72
73     return NS_OK;
74 }
75
76 OCStackApplicationResult NSConsumerSyncInfoListener(
77         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
78 {
79     (void) ctx;
80     (void) handle;
81
82     NS_VERTIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
83     NS_VERTIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
84
85     NSSyncInfo * newNoti = NULL;
86
87     NS_LOG(ERROR, "get provider");
88     NSProvider * provider = NSGetNSProvider(clientResponse);
89     NS_VERTIFY_NOT_NULL(provider, OC_STACK_KEEP_TRANSACTION);
90
91     newNoti = NSGetNSSyncInfo(clientResponse);
92     NS_VERTIFY_NOT_NULL_WITH_POST_CLEANING(
93             newNoti, OC_STACK_KEEP_TRANSACTION, OICFree(provider));
94
95     NSTaskType taskType = TASK_RECV_READ;
96
97     if (newNoti->state != NS_SYNC_READ)
98     {
99         NS_LOG(DEBUG, "newNoti->type : Dismiss");
100         taskType = TASK_RECV_DISMISS;
101     }
102     else
103     {
104         NS_LOG(DEBUG, "newNoti->type : Read");
105     }
106
107     NSNotificationSync(provider, newNoti);
108
109     NSResult ret = NSPushToCache(clientResponse, taskType);
110     NS_VERTIFY_NOT_NULL(ret == NS_OK ? (void *)1 : NULL, OC_STACK_KEEP_TRANSACTION);
111
112     return OC_STACK_KEEP_TRANSACTION;
113 }
114
115 OCStackApplicationResult NSConsumerMessageListener(
116         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
117 {
118     (void) ctx;
119     (void) handle;
120
121     NS_VERTIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
122     NS_VERTIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
123
124     NS_LOG(DEBUG, "build NSProvider");
125     NSProvider * provider = NSGetNSProvider(clientResponse);
126     NS_VERTIFY_NOT_NULL(provider, OC_STACK_KEEP_TRANSACTION);
127
128     NS_LOG(DEBUG, "build NSMessage");
129     NSMessage_consumer * newNoti = NSGetNSMessage(clientResponse);
130     NS_VERTIFY_NOT_NULL_WITH_POST_CLEANING(
131             newNoti, OC_STACK_KEEP_TRANSACTION, OICFree(provider));
132
133     if (newNoti->messageId == 0)
134     {
135         // TODO update provider list.
136         NS_LOG(DEBUG, "Receive Subscribe confirm");
137         OICFree(provider->mUserData);
138         OICFree(provider);
139         NSRemoveMessage(newNoti);
140         return OC_STACK_KEEP_TRANSACTION;
141     }
142
143     NS_LOG(DEBUG, "newNoti->type == Notification");
144     NSNotificationPost(provider, (NSMessage *) newNoti);
145
146     NSResult ret = NSPushToCache(clientResponse, TASK_CONSUMER_RECV_MESSAGE);
147     NS_VERTIFY_NOT_NULL(ret == NS_OK ? (void *)1 : NULL, OC_STACK_KEEP_TRANSACTION);
148
149     return OC_STACK_KEEP_TRANSACTION;
150 }
151
152 NSResult NSPushToCache(OCClientResponse * clientResponse, NSTaskType type)
153 {
154     NSMessage_consumer * cachedNoti = NSGetNSMessage(clientResponse);
155     NS_LOG(DEBUG, "build NSMessage");
156     NS_VERTIFY_NOT_NULL(cachedNoti, NS_ERROR);
157
158     NS_LOG(DEBUG, "build NSTask");
159     NSTask * task = NSMakeTask(type, (void *) cachedNoti);
160     NS_VERTIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveMessage(cachedNoti));
161
162     NSConsumerPushEvent(task);
163
164     return NS_OK;
165 }
166
167 NSMessage_consumer * NSGetNSMessage(OCClientResponse * clientResponse)
168 {
169     NS_VERTIFY_NOT_NULL(clientResponse->payload, NULL);
170
171     NS_LOG(DEBUG, "get msg id");
172     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
173     uint64_t id = NULL;
174     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
175     NS_VERTIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
176
177     NS_LOG(DEBUG, "get provider id");
178     char * pId = NULL;
179     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
180     NS_VERTIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
181
182     NS_LOG(DEBUG, "create NSMessage");
183     NSMessage_consumer * retNoti = (NSMessage_consumer *)OICMalloc(sizeof(NSMessage_consumer));
184     NS_VERTIFY_NOT_NULL(retNoti, NULL);
185
186     retNoti->messageId = id;
187     retNoti->providerId = pId;
188     retNoti->title = NULL;
189     retNoti->contentText = NULL;
190     retNoti->sourceName = NULL;
191
192     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retNoti->title);
193     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retNoti->contentText);
194     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retNoti->sourceName);
195
196     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retNoti->type);
197     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retNoti->dateTime);
198     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retNoti->ttl);
199
200     NS_LOG_V(DEBUG, "Msg Address : %s", clientResponse->addr->addr);
201     NS_LOG_V(DEBUG, "Msg ID : %ld", retNoti->messageId);
202     NS_LOG_V(DEBUG, "Msg Title : %s", retNoti->title);
203     NS_LOG_V(DEBUG, "Msg Content : %s", retNoti->contentText);
204     NS_LOG_V(DEBUG, "Msg Source : %s", retNoti->sourceName);
205     NS_LOG_V(DEBUG, "Msg Type : %d", retNoti->type);
206     NS_LOG_V(DEBUG, "Msg Date : %s", retNoti->dateTime);
207     NS_LOG_V(DEBUG, "Msg ttl : %ld", retNoti->ttl);
208
209     NS_LOG(DEBUG, "copy target address");
210     retNoti->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
211     NS_VERTIFY_NOT_NULL(retNoti->addr, NULL);
212     memcpy(retNoti->addr, clientResponse->addr, sizeof(OCDevAddr));
213
214     retNoti->messageTypes = Notification;
215
216     return retNoti;
217 }
218
219 NSSyncInfo * NSGetNSSyncInfo(OCClientResponse * clientResponse)
220 {
221     NS_VERTIFY_NOT_NULL(clientResponse->payload, NULL);
222
223     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
224
225     NS_LOG(DEBUG, "get state");
226     int64_t state = 0;
227     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state);
228     NS_VERTIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
229
230     NS_LOG(DEBUG, "get msg id");
231     uint64_t id = NULL;
232     getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
233     NS_VERTIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
234
235     NS_LOG(DEBUG, "get provider id");
236     char * pId = NULL;
237     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
238     NS_VERTIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
239
240     NS_LOG(DEBUG, "create NSSyncInfo");
241     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
242     NS_VERTIFY_NOT_NULL(retSync, NULL);
243
244     retSync->messageId = id;
245     retSync->state = (NSSyncType) state;
246     retSync->providerId = pId;
247
248     NS_LOG_V(DEBUG, "Sync ID : %ld", retSync->messageId);
249     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
250     NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
251
252     return retSync;
253 }
254
255 NSProvider * NSGetNSProvider(OCClientResponse * clientResponse)
256 {
257     NS_LOG(DEBUG, "create NSProvider");
258     NSProvider * newProvider = (NSProvider *)OICMalloc(sizeof(NSProvider));
259     NS_VERTIFY_NOT_NULL(newProvider, NULL);
260
261     // TODO set id
262     newProvider->mId = NULL;
263     newProvider->mUserData = (void *)OICMalloc(sizeof(OCDevAddr));
264     NS_VERTIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL, OICFree(newProvider));
265
266     memcpy(newProvider->mUserData, clientResponse->addr, sizeof(OCDevAddr));
267
268     return newProvider;
269 }
270
271 void NSConsumerNotificationTaskProcessing(NSTask * task)
272 {
273     NS_VERTIFY_NOT_NULL_V(task);
274
275     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
276     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
277     {
278         NS_LOG(DEBUG, "Request Subscribe");
279         NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
280         NS_VERTIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
281     }
282     else if (task->taskType == TASK_SEND_READ || task->taskType == TASK_SEND_DISMISS)
283     {
284         NSMessage_consumer * message = (NSMessage_consumer *) task->taskData;
285         NS_VERTIFY_NOT_NULL_V(message);
286
287         OCStackResult ret = NSSendSyncInfo(message, (task->taskType == TASK_SEND_READ) ? 0 : 1);
288         NS_VERTIFY_STACK_OK_V(ret);
289
290     }
291     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
292     {
293         NSProvider * provider = (NSProvider *)task->taskData;
294
295         OCCancel(provider->messageHandle, NS_QOS, NULL, 0);
296         OCCancel(provider->syncHandle, NS_QOS, NULL, 0);
297     }
298     else
299     {
300         NS_LOG(ERROR, "Unknown type message");
301     }
302 }
303
304 OCRepPayload * NSGetPayloadofSyncInfo(NSMessage_consumer * message, int type)
305 {
306     OCRepPayload * payload = OCRepPayloadCreate();
307     NS_VERTIFY_NOT_NULL(payload, NULL);
308
309     OCRepPayloadSetPropInt(payload, "ID", (int64_t)message->messageId);
310     OCRepPayloadSetPropInt(payload, "STATE", type);
311     if (message->sourceName)
312     {
313         OCRepPayloadSetPropString(payload, "SOURCE", (char *) message->sourceName);
314     }
315
316     return payload;
317 }
318
319 OCStackResult NSSendSyncInfo(NSMessage_consumer * message, int type)
320 {
321     OCRepPayload * payload = NSGetPayloadofSyncInfo(message, type);
322     NS_VERTIFY_NOT_NULL(payload, OC_STACK_ERROR);
323
324     return NSInvokeRequest(NULL, OC_REST_POST, message->addr,
325                            "/notification/sync", (OCPayload*)payload,
326                            NSConsumerPostResultCheck, NULL);
327 }