Update snapshot(2017-12-06)
[platform/upstream/iotivity.git] / resource / csdk / resource-directory / src / RDClient.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 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 <thread>
22 #include <mutex>
23
24 #ifdef RD_CLIENT
25 #include "RDClient.h"
26 #include "rd_client.h"
27
28 #include "OCApi.h"
29 #include "OCRepresentation.h"
30 #include "OCResourceRequest.h"
31 #include "OCResourceResponse.h"
32 #include "OCPlatform.h"
33 #include "OCException.h"
34 #include "ocpayload.h"
35 #include "oic_malloc.h"
36
37 using namespace OC;
38
39
40 OCRepresentation parseRDResponseCallback(OCClientResponse* clientResponse)
41 {
42     if (nullptr == clientResponse || nullptr == clientResponse->payload ||
43         PAYLOAD_TYPE_REPRESENTATION != clientResponse->payload->type)
44     {
45         return OCRepresentation();
46     }
47
48     MessageContainer oc;
49     oc.setPayload(clientResponse->payload);
50
51     std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
52     if (it == oc.representations().end())
53     {
54         return OCRepresentation();
55     }
56
57     // first one is considered the root, everything else is considered a child of this one.
58     OCRepresentation root = *it;
59     root.setDevAddr(clientResponse->devAddr);
60     root.setUri(clientResponse->resourceUri);
61     ++it;
62
63     std::for_each(it, oc.representations().end(),
64             [&root](const OCRepresentation& repItr)
65             {root.addChild(repItr);});
66     return root;
67 }
68
69 OCStackApplicationResult publishResourceToRDCallback(void* ctx, OCDoHandle /*handle*/,
70                                                      OCClientResponse* clientResponse)
71 {
72     ServerCallbackContext::PublishContext* context =
73     static_cast<ServerCallbackContext::PublishContext*>(ctx);
74
75     try
76     {
77         // Update resource unique id in stack.
78         if (clientResponse)
79         {
80             if (clientResponse->payload)
81             {
82                 OCRepPayload *rdPayload = (OCRepPayload *) clientResponse->payload;
83                 OCRepPayload **links = NULL;
84
85                 size_t dimensions[MAX_REP_ARRAY_DEPTH];
86                 OCRepPayloadGetPropObjectArray(rdPayload, OC_RSRVD_LINKS, &links, dimensions);
87                 for(size_t i = 0; i < dimensions[0]; i++)
88                 {
89                     char *uri = NULL;
90                     OCRepPayloadGetPropString(links[i], OC_RSRVD_HREF, &uri);
91                     OCResourceHandle handle = OCGetResourceHandleAtUri(uri);
92
93                     int64_t ins = 0;
94                     OCRepPayloadGetPropInt(links[i], OC_RSRVD_INS, &ins);
95                     OCBindResourceInsToResource(handle, ins);
96
97                     OICFree(uri);
98                 }
99
100                 // Free links
101                 size_t count = calcDimTotal(dimensions);
102                 for (size_t k = 0; k < count; k++)
103                 {
104                     OCRepPayloadDestroy(links[k]);
105                 }
106                 OICFree(links);
107             }
108             OCRepresentation rep = parseRDResponseCallback(clientResponse);
109             std::thread exec(context->callback, rep, clientResponse->result);
110             exec.detach();
111         }
112     }
113     catch (OC::OCException& e)
114     {
115         oclog() <<"Exception in publishResourceToRDCallback, ignoring response: "
116             <<e.what() <<std::flush;
117     }
118
119     return OC_STACK_KEEP_TRANSACTION;
120 }
121
122 OCStackResult RDClient::publishResourceToRD(const std::string& host,
123                                             OCConnectivityType connectivityType,
124                                             ResourceHandles& resourceHandles,
125                                             PublishResourceCallback callback)
126 {
127     return publishResourceToRD(host, connectivityType, resourceHandles, callback, static_cast<QualityOfService>(m_qos));
128 }
129
130 OCStackResult RDClient::publishResourceToRD(const std::string& host,
131                                             OCConnectivityType connectivityType,
132                                             PublishResourceCallback callback,
133                                             QualityOfService qos)
134 {
135     ResourceHandles resourceHandles;
136     return publishResourceToRD(host, connectivityType, resourceHandles, callback, qos);
137 }
138
139 OCStackResult RDClient::publishResourceToRD(const std::string& host,
140                                    OCConnectivityType connectivityType,
141                                    ResourceHandles& resourceHandles,
142                                    PublishResourceCallback callback,
143                                    QualityOfService qos)
144 {
145     ServerCallbackContext::PublishContext* ctx =
146         new ServerCallbackContext::PublishContext(callback);
147     OCCallbackData cbdata(
148             static_cast<void*>(ctx),
149             publishResourceToRDCallback,
150             [](void* c)
151             {delete static_cast<ServerCallbackContext::PublishContext*>(c);}
152             );
153
154     auto cLock = m_csdkLock.lock();
155     OCStackResult result = OC_STACK_ERROR;
156     if (cLock)
157     {
158         std::lock_guard<std::recursive_mutex> lock(*cLock);
159         result = OCRDPublish(nullptr, host.c_str(), connectivityType, &resourceHandles[0],
160                              resourceHandles.size(), &cbdata, static_cast<OCQualityOfService>(qos));
161     }
162
163     if (OC_STACK_OK != result)
164     {
165         throw OCException(OC::Exception::PUBLISH_RESOURCE_FAILED, result);
166     }
167     return result;
168 }
169
170 OCStackApplicationResult deleteResourceFromRDCallback(void* ctx, OCDoHandle /*handle*/,
171                                                       OCClientResponse* clientResponse)
172 {
173     ServerCallbackContext::DeleteContext* context =
174     static_cast<ServerCallbackContext::DeleteContext*>(ctx);
175
176     std::thread exec(context->callback, clientResponse->result);
177     exec.detach();
178     return OC_STACK_DELETE_TRANSACTION;
179 }
180
181 OCStackResult RDClient::deleteResourceFromRD(const std::string& host,
182                                 OCConnectivityType connectivityType,
183                                 ResourceHandles& resourceHandles,
184                                 DeleteResourceCallback callback)
185 {
186     return deleteResourceFromRD(host, connectivityType, resourceHandles, callback, static_cast<QualityOfService>(m_qos));
187 }
188
189
190 OCStackResult RDClient::deleteResourceFromRD(const std::string& host,
191                                 OCConnectivityType connectivityType,
192                                 DeleteResourceCallback callback,
193                                 QualityOfService qos)
194 {
195     ResourceHandles resourceHandles;
196     return deleteResourceFromRD(host, connectivityType, resourceHandles, callback, qos);
197 }
198
199 OCStackResult RDClient::deleteResourceFromRD(const std::string& host,
200                                 OCConnectivityType connectivityType,
201                                 ResourceHandles& resourceHandles,
202                                 DeleteResourceCallback callback,
203                                 QualityOfService qos)
204 {
205     ServerCallbackContext::DeleteContext* ctx =
206         new ServerCallbackContext::DeleteContext(callback);
207     OCCallbackData cbdata(
208             static_cast<void*>(ctx),
209             deleteResourceFromRDCallback,
210             [](void* c)
211             {delete static_cast<ServerCallbackContext::DeleteContext*>(c);}
212             );
213
214     auto cLock = m_csdkLock.lock();
215     OCStackResult result = OC_STACK_ERROR;
216     if (cLock)
217     {
218         std::lock_guard<std::recursive_mutex> lock(*cLock);
219         result = OCRDDelete(nullptr, host.c_str(), connectivityType, &resourceHandles[0],
220                             resourceHandles.size(), &cbdata, static_cast<OCQualityOfService>(qos));
221     }
222
223     if (OC_STACK_OK != result)
224     {
225         throw OCException(OC::Exception::PUBLISH_RESOURCE_FAILED, result);
226     }
227     return result;
228 }
229 #endif