Fixed bug for duplicated request to subscribe and invalid storage logic.
[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 #define NS_SYNC_URI "/notification/sync"
29
30 unsigned long NS_MESSAGE_ACCEPTANCE = 1;
31
32 NSMessage_consumer * NSCreateMessage_internal(uint64_t msgId, const char * providerId);
33 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state);
34
35 NSMessage_consumer * NSGetMessage(OCClientResponse * clientResponse);
36 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
37
38 char * NSGetCloudUri(const char * providerId, char * uri);
39
40 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
41 {
42     NSProvider_internal * provider_internal = (NSProvider_internal *) provider;
43     NS_VERIFY_NOT_NULL(provider_internal, NS_ERROR);
44
45     NSProviderConnectionInfo * connections = provider_internal->connection;
46     while(connections)
47     {
48         if (connections->isSubscribing == true)
49         {
50             connections = connections->next;
51             continue;
52         }
53
54         char * msgUri = OICStrdup(provider_internal->messageUri);
55         char * syncUri = OICStrdup(provider_internal->syncUri);
56
57         OCConnectivityType type = CT_DEFAULT;
58         if (connections->addr->adapter == OC_ADAPTER_TCP)
59         {
60             type = CT_ADAPTER_TCP;
61             if (connections->isCloudConnection == true)
62             {
63                 msgUri = NSGetCloudUri(provider_internal->providerId, msgUri);
64                 syncUri = NSGetCloudUri(provider_internal->providerId, syncUri);
65             }
66         }
67
68         NS_LOG_V(DEBUG, "subscribe to %s:%d", connections->addr->addr, connections->addr->port);
69
70         NS_LOG(DEBUG, "get subscribe message query");
71         char * query = NULL;
72         query = NSMakeRequestUriWithConsumerId(msgUri);
73         NS_VERIFY_NOT_NULL(query, NS_ERROR);
74
75         NS_LOG(DEBUG, "subscribe message");
76         NS_LOG_V(DEBUG, "subscribe query : %s", query);
77         OCStackResult ret = NSInvokeRequest(&(connections->messageHandle),
78                               OC_REST_OBSERVE, connections->addr, query, NULL,
79                               NSConsumerMessageListener, NULL, type);
80         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(
81                 NSOCResultToSuccess(ret), NS_ERROR, NSOICFree(query));
82         NSOICFree(query);
83         NSOICFree(msgUri);
84
85         NS_LOG(DEBUG, "get subscribe sync query");
86         query = NSMakeRequestUriWithConsumerId(syncUri);
87         NS_VERIFY_NOT_NULL(query, NS_ERROR);
88
89         NS_LOG(DEBUG, "subscribe sync");
90         NS_LOG_V(DEBUG, "subscribe query : %s", query);
91         ret = NSInvokeRequest(&(connections->syncHandle),
92                               OC_REST_OBSERVE, connections->addr, query, NULL,
93                               NSConsumerSyncInfoListener, NULL, type);
94         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(
95                 NSOCResultToSuccess(ret), NS_ERROR, NSOICFree(query));
96         NSOICFree(query);
97         NSOICFree(syncUri);
98
99         connections->isSubscribing = true;
100
101         connections = connections->next;
102     }
103
104     return NS_OK;
105 }
106
107 OCStackApplicationResult NSConsumerCheckPostResult(
108         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
109 {
110     (void) ctx;
111     (void) handle;
112
113     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
114     NS_VERIFY_STACK_SUCCESS(
115             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
116
117     return OC_STACK_KEEP_TRANSACTION;
118 }
119
120 void NSRemoveSyncInfoObj(NSSyncInfo * sync)
121 {
122     NSOICFree(sync);
123 }
124
125 OCStackApplicationResult NSConsumerSyncInfoListener(
126         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
127 {
128     (void) ctx;
129     (void) handle;
130
131     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
132     NS_VERIFY_STACK_SUCCESS(
133             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
134
135     NS_LOG(DEBUG, "get NSSyncInfo");
136     NSSyncInfo * newSync = NSGetSyncInfoc(clientResponse);
137     NS_VERIFY_NOT_NULL(newSync, OC_STACK_KEEP_TRANSACTION);
138
139     NSTaskType taskType = TASK_RECV_SYNCINFO;
140
141     NS_LOG(DEBUG, "build NSTask");
142     NSTask * task = NSMakeTask(taskType, (void *) newSync);
143     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
144                OC_STACK_KEEP_TRANSACTION, NSRemoveSyncInfoObj(newSync));
145
146     NSConsumerPushEvent(task);
147
148     return OC_STACK_KEEP_TRANSACTION;
149 }
150
151 OCStackApplicationResult NSConsumerMessageListener(
152         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
153 {
154     (void) ctx;
155     (void) handle;
156
157     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
158     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
159
160     NS_LOG(DEBUG, "build NSMessage");
161     NSMessage_consumer * newNoti = NSGetMessage(clientResponse);
162     NS_VERIFY_NOT_NULL(newNoti, OC_STACK_KEEP_TRANSACTION);
163
164     NSTaskType type = TASK_CONSUMER_RECV_MESSAGE;
165
166     if (newNoti->messageId == NS_MESSAGE_ACCEPTANCE)
167     {
168         NS_LOG(DEBUG, "Receive Subscribe confirm");
169         type = TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED;
170     }
171     else
172     {
173         NS_LOG(DEBUG, "Receive new message");
174     }
175
176     NS_LOG(DEBUG, "build NSTask");
177     NSTask * task = NSMakeTask(type, (void *) newNoti);
178     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveMessage(newNoti));
179
180     NSConsumerPushEvent(task);
181
182     return OC_STACK_KEEP_TRANSACTION;
183 }
184
185 void NSGetMessagePostClean(char * pId, OCDevAddr * addr)
186 {
187     NSOICFree(pId);
188     NSOICFree(addr);
189 }
190
191 NSMessage_consumer * NSGetMessage(OCClientResponse * clientResponse)
192 {
193     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
194     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
195
196     NS_LOG(DEBUG, "get msg id");
197     uint64_t id = NULL;
198     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
199     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
200
201     NS_LOG(DEBUG, "get provider id");
202     char * pId = NULL;
203     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
204     NS_LOG_V (DEBUG, "provider id: %s", pId);
205     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
206
207     NS_LOG(DEBUG, "get provider address");
208     OCDevAddr * addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
209     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(addr, NULL, NSGetMessagePostClean(pId, addr));
210     memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
211
212     NS_LOG(DEBUG, "create NSMessage");
213     NSMessage_consumer * retMsg = NSCreateMessage_internal(id, pId);
214     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSGetMessagePostClean(pId, addr));
215     NSOICFree(pId);
216
217     retMsg->i_addr = addr;
218     retMsg->i_messageTypes = NS_SYNC_UNREAD;
219
220     NS_LOG(DEBUG, "get msg optional field");
221     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
222     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
223     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
224
225     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
226     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
227     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
228
229     NS_LOG_V(DEBUG, "Msg Address : %s", retMsg->i_addr->addr);
230     NS_LOG_V(DEBUG, "Msg ID      : %lld", retMsg->messageId);
231     NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
232     NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
233     NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
234     NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
235     NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
236     NS_LOG_V(DEBUG, "Msg ttl     : %lld", retMsg->ttl);
237
238     return retMsg;
239 }
240
241 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
242 {
243     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
244
245     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
246
247     NS_LOG(DEBUG, "get msg id");
248     uint64_t id = NULL;
249     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
250     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
251
252     NS_LOG(DEBUG, "get provider id");
253     char * pId = NULL;
254     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
255     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
256
257     NS_LOG(DEBUG, "get state");
258     int64_t state = 0;
259     getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state);
260     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
261
262     NS_LOG(DEBUG, "create NSSyncInfo");
263     NSSyncInfo * retSync = NSCreateSyncInfo_consumer(id, pId, (NSSyncType)state);
264     NS_VERIFY_NOT_NULL(retSync, NULL);
265
266     NS_LOG_V(DEBUG, "Sync ID : %lld", retSync->messageId);
267     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
268     NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
269
270     return retSync;
271 }
272
273 NSMessage_consumer * NSCreateMessage_internal(uint64_t id, const char * providerId)
274 {
275     NSMessage_consumer * retMsg = (NSMessage_consumer *)OICMalloc(sizeof(NSMessage_consumer));
276     NS_VERIFY_NOT_NULL(retMsg, NULL);
277
278     retMsg->messageId = id;
279     OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
280     retMsg->title = NULL;
281     retMsg->contentText = NULL;
282     retMsg->sourceName = NULL;
283     retMsg->type = NS_MESSAGE_INFO;
284     retMsg->dateTime = NULL;
285     retMsg->ttl = 0;
286     retMsg->i_addr = NULL;
287
288     return retMsg;
289 }
290
291 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state)
292 {
293     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
294     NS_VERIFY_NOT_NULL(retSync, NULL);
295
296     retSync->messageId = msgId;
297     retSync->state = state;
298     OICStrcpy(retSync->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
299
300     return retSync;
301 }
302
303 OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
304 {
305     OCRepPayload * payload = OCRepPayloadCreate();
306     NS_VERIFY_NOT_NULL(payload, OC_STACK_ERROR);
307
308     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t)syncInfo->messageId);
309     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, syncInfo->state);
310     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, syncInfo->providerId);
311
312     char * uri = (char*)OICStrdup(NS_SYNC_URI);
313     OCConnectivityType type = CT_DEFAULT;
314     if(addr->adapter == OC_ADAPTER_TCP)
315     {
316         type = CT_ADAPTER_TCP;
317         uri = NSGetCloudUri(syncInfo->providerId, uri);
318     }
319
320     OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr,
321                             uri, (OCPayload*)payload,
322                             NSConsumerCheckPostResult, NULL, type);
323     NSOICFree(uri);
324
325     return ret;
326 }
327
328 char * NSGetCloudUri(const char * providerId, char * uri)
329 {
330     size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1;
331     char * retUri = (char *)OICMalloc(uriLen);
332     snprintf(retUri, uriLen, "/%s%s", providerId, uri);
333     NSOICFree(uri);
334     NS_LOG_V(DEBUG, "TCP uri : %s", retUri);
335
336     return retUri;
337 }
338
339 void NSConsumerCommunicationTaskProcessing(NSTask * task)
340 {
341     NS_VERIFY_NOT_NULL_V(task);
342
343     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
344     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
345     {
346         NS_VERIFY_NOT_NULL_V(task->taskData);
347         NS_LOG(DEBUG, "Request Subscribe");
348         NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
349         NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
350     }
351     else if (task->taskType == TASK_SEND_SYNCINFO)
352     {
353         NS_VERIFY_NOT_NULL_V(task->taskData);
354         NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)task->taskData;
355         NSProviderConnectionInfo * info = syncInfo->connection;
356
357         while(info)
358         {
359             OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), info->addr);
360             if (ret != OC_STACK_OK)
361             {
362                 NS_LOG_V(ERROR, "send sync info fail : %d", info->addr->adapter);
363             }
364
365             info = info->next;
366         }
367
368         NSRemoveConnections(syncInfo->connection);
369         NSOICFree(syncInfo);
370     }
371     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
372     {
373         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
374
375         NSProviderConnectionInfo * connections = provider->connection;
376         while(connections)
377         {
378             if (connections->isSubscribing == false)
379             {
380                 NS_LOG_V(DEBUG, "unsubscribed to %s:%d",
381                      connections->addr->addr, connections->addr->port);
382                 connections = connections->next;
383                 continue;
384             }
385             NS_LOG_V(DEBUG, "cancel subscribe to %s:%d",
386                      connections->addr->addr, connections->addr->port);
387             OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
388             OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
389             connections->messageHandle = NULL;
390             connections->syncHandle = NULL;
391             connections->isSubscribing = false;
392             connections = connections->next;
393         }
394     }
395     else
396     {
397         NS_LOG(ERROR, "Unknown type message");
398     }
399     NSOICFree(task);
400 }