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