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