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