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