[IOT-1386] Update ins value after deleting resource from rd
[platform/upstream/iotivity.git] / resource / csdk / resource-directory / src / rd_client.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 a
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 #include "rd_client.h"
21
22 #include <stdlib.h>
23
24 #include "oic_malloc.h"
25 #include "oic_string.h"
26 #include "octypes.h"
27 #include "ocstack.h"
28 #include "ocpayload.h"
29 #include "payload_logging.h"
30
31 #define TAG "RD_CLIENT"
32
33 #ifdef RD_CLIENT
34
35 OCStackResult OCRDDiscover(OCConnectivityType connectivityType, OCCallbackData *cbBiasFactor,
36                            OCQualityOfService qos)
37 {
38     if (!cbBiasFactor || !cbBiasFactor->cb)
39     {
40         OIC_LOG(DEBUG, TAG, "No callback function specified.");
41         return OC_STACK_INVALID_CALLBACK;
42     }
43
44     /* Start a discovery query*/
45     char queryUri[MAX_URI_LENGTH] = { '\0' };
46     snprintf(queryUri, MAX_URI_LENGTH, "coap://%s%s", OC_MULTICAST_PREFIX, OC_RSRVD_RD_URI);
47     OIC_LOG_V(DEBUG, TAG, "Querying RD: %s\n", queryUri);
48
49     return OCDoResource(NULL, OC_REST_DISCOVER, queryUri, NULL, NULL, connectivityType, qos,
50                         cbBiasFactor, NULL, 0);
51 }
52
53 OCStackResult OCRDPublish(const char *host, OCConnectivityType connectivityType,
54                           OCResourceHandle *resourceHandles, uint8_t nHandles,
55                           OCCallbackData *cbData, OCQualityOfService qos)
56 {
57     // Validate input parameters.
58     if (!host)
59     {
60         return OC_STACK_INVALID_IP;
61     }
62
63     if (!cbData || !cbData->cb)
64     {
65         return OC_STACK_INVALID_CALLBACK;
66     }
67
68     // Get Device ID from stack.
69     const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
70
71     return OCRDPublishWithDeviceId(host, id, connectivityType, resourceHandles, nHandles,
72                                    cbData, qos);
73 }
74
75 OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
76                                       OCConnectivityType connectivityType,
77                                       OCResourceHandle *resourceHandles, uint8_t nHandles,
78                                       OCCallbackData *cbData, OCQualityOfService qos)
79 {
80     // Validate input parameters.
81     if (!host || !cbData || !cbData->cb || !id)
82     {
83         return OC_STACK_INVALID_CALLBACK;
84     }
85
86     OIC_LOG_V(DEBUG, TAG, "Publish Resource to RD with device id [%s]", id);
87
88     OCResourceHandle *pubResHandle = resourceHandles;
89     OCResourceHandle defaultResHandles[OIC_RD_DEFAULT_RESOURCE] = { 0 };
90     uint8_t nPubResHandles = nHandles;
91
92     // if resource handles is null, "/oic/p" and "/oic/d" resource will be published to RD.
93     if (!pubResHandle)
94     {
95         // get "/oic/d" and "/oic/p" resource handle from stack.
96         defaultResHandles[0] = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
97         defaultResHandles[1] = OCGetResourceHandleAtUri(OC_RSRVD_PLATFORM_URI);
98
99         for (uint8_t j = 0; j < OIC_RD_DEFAULT_RESOURCE; j++)
100         {
101             if (defaultResHandles[j])
102             {
103                 OIC_LOG_V(DEBUG, TAG, "Add virtual resource(%s) to resource handle list",
104                           OCGetResourceUri(defaultResHandles[j]));
105             }
106         }
107
108         pubResHandle = defaultResHandles;
109         nPubResHandles = OIC_RD_DEFAULT_RESOURCE;
110     }
111
112     char targetUri[MAX_URI_LENGTH] = { 0 };
113     snprintf(targetUri, MAX_URI_LENGTH, "%s%s?rt=%s", host,
114              OC_RSRVD_RD_URI, OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
115     OIC_LOG_V(DEBUG, TAG, "Target URI: %s", targetUri);
116
117     OCRepPayload *rdPayload =  (OCRepPayload *)OCRepPayloadCreate();
118     if (!rdPayload)
119     {
120         return OC_STACK_NO_MEMORY;
121     }
122
123     const char *deviceId = OCGetServerInstanceIDString();
124     if (deviceId)
125     {
126         OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_ID, deviceId);
127     }
128     OCRepPayloadSetPropInt(rdPayload, OC_RSRVD_DEVICE_TTL, OIC_RD_PUBLISH_TTL);
129
130     OCRepPayload **linkArr = OICCalloc(nPubResHandles, sizeof(OCRepPayload *));
131     if (!linkArr)
132     {
133        OCRepPayloadDestroy(rdPayload);
134        return OC_STACK_NO_MEMORY;
135     }
136     size_t dimensions[MAX_REP_ARRAY_DEPTH] = {nPubResHandles, 0, 0};
137
138     for (uint8_t j = 0; j < nPubResHandles; j++)
139     {
140         OCResourceHandle handle = pubResHandle[j];
141         if (handle)
142         {
143             OCRepPayload *link = OCRepPayloadCreate();
144
145             const char *uri = OCGetResourceUri(handle);
146             if (uri)
147             {
148                 OCRepPayloadSetPropString(link, OC_RSRVD_HREF, uri);
149             }
150
151             uint8_t numElement = 0;
152             if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
153             {
154                 size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
155                 char **rt = (char **)OICMalloc(sizeof(char *) * numElement);
156                 for (uint8_t i = 0; i < numElement; ++i)
157                 {
158                     const char *value = OCGetResourceTypeName(handle, i);
159                     OIC_LOG_V(DEBUG, TAG, "value: %s", value);
160                     rt[i] = OICStrdup(value);
161                 }
162                 OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_RESOURCE_TYPE, rt, rtDim);
163             }
164
165             numElement = 0;
166             if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement))
167             {
168                 size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
169                 char **itf = (char **)OICMalloc(sizeof(char *) * numElement);
170                 for (uint8_t i = 0; i < numElement; ++i)
171                 {
172                     const char *value = OCGetResourceInterfaceName(handle, i);
173                     OIC_LOG_V(DEBUG, TAG, "value: %s", value);
174                     itf[i] = OICStrdup(value);
175                 }
176                 OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_INTERFACE, itf, ifDim);
177             }
178
179             uint8_t ins = 0;
180             if (OC_STACK_OK == OCGetResourceIns(handle, &ins))
181             {
182                 OCRepPayloadSetPropInt(link, OC_RSRVD_INS, ins);
183             }
184
185             size_t mtDim[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
186             char **mediaType = (char **)OICMalloc(sizeof(char *) * 1);
187             mediaType[0] = OICStrdup(DEFAULT_MESSAGE_TYPE);
188             OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_MEDIA_TYPE, mediaType, mtDim);
189
190             OCResourceProperty p = OCGetResourceProperties(handle);
191             p = (OCResourceProperty) ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE));
192             OCRepPayload *policy = OCRepPayloadCreate();
193             OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, p);
194             OCRepPayloadSetPropObjectAsOwner(link, OC_RSRVD_POLICY, policy);
195
196             linkArr[j] = link;
197         }
198     }
199
200     OCRepPayloadSetPropObjectArray(rdPayload, OC_RSRVD_LINKS, linkArr, dimensions);
201     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *) rdPayload);
202
203     for (uint8_t i = 0; i < nPubResHandles; i++)
204     {
205         OCRepPayloadDestroy(linkArr[i]);
206     }
207     OICFree(linkArr);
208
209     return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
210                         connectivityType, qos, cbData, NULL, 0);
211 }
212
213 OCStackResult OCRDDelete(const char *host, OCConnectivityType connectivityType,
214                          OCResourceHandle *resourceHandles, uint8_t nHandles,
215                          OCCallbackData *cbData, OCQualityOfService qos)
216 {
217     // Validate input parameters
218     if (!host)
219     {
220         return OC_STACK_INVALID_IP;
221     }
222
223     if (!cbData || !cbData->cb)
224     {
225         return OC_STACK_INVALID_CALLBACK;
226     }
227
228     const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
229
230     return OCRDDeleteWithDeviceId(host, id, connectivityType, resourceHandles, nHandles,
231                                   cbData, qos);
232 }
233
234 OCStackResult OCRDDeleteWithDeviceId(const char *host, const unsigned char *id,
235                                      OCConnectivityType connectivityType,
236                                      OCResourceHandle *resourceHandles, uint8_t nHandles,
237                                      OCCallbackData *cbData, OCQualityOfService qos)
238 {
239     // Validate input parameters
240     if (!host || !cbData || !cbData->cb || !id)
241     {
242         return OC_STACK_INVALID_CALLBACK;
243     }
244
245     OIC_LOG_V(DEBUG, TAG, "Delete Resource to RD with device id [%s]", id);
246
247     char targetUri[MAX_URI_LENGTH] = { 0 };
248     snprintf(targetUri, MAX_URI_LENGTH, "%s%s?di=%s", host, OC_RSRVD_RD_URI, id);
249
250     uint8_t len = 0;
251     char queryParam[MAX_URI_LENGTH] = { 0 };
252     for (uint8_t j = 0; j < nHandles; j++)
253     {
254         OCResource *handle = (OCResource *) resourceHandles[j];
255         uint8_t ins = 0;
256         OCGetResourceIns(handle, &ins);
257         len += snprintf(queryParam + len, MAX_URI_LENGTH, "&ins=%d", ins);
258         OIC_LOG_V(DEBUG, TAG, "queryParam [%s]", queryParam);
259     }
260
261     OICStrcatPartial(targetUri, sizeof(targetUri), queryParam, strlen(queryParam));
262     OIC_LOG_V(DEBUG, TAG, "Target URI: %s", targetUri);
263
264     return OCDoResource(NULL, OC_REST_DELETE, targetUri, NULL, NULL, connectivityType,
265                         qos, cbData, NULL, 0);
266 }
267
268 #endif