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