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