Merge "Partial Implementation of US1574:"
[platform/upstream/iotivity.git] / csdk / controller / core / test / MockProtocol.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 // ============================================================================
22 // Includes
23 // ============================================================================
24 #include "MockProtocol.h"
25 #include "SimpleLogger.h"
26 #include "InternalApi.h"
27 #include "Link.hpp"
28 #include "Description.hpp"
29 #include "Service.hpp"
30 #include "Characteristic.hpp"
31 #include <set>
32
33 #include <boost/uuid/uuid.hpp>
34 #include <boost/uuid/uuid_generators.hpp>
35 #include <boost/uuid/uuid_io.hpp>
36 // ============================================================================
37 // Namespace
38 // ============================================================================
39 namespace Intel {
40 namespace CCFL {
41 namespace Protocols {
42
43 static const char TAG[] = "MockProtocol";
44
45 const std::string MockProtocol::MOCK_DEVICE_ID = "7c34ad16-ae8c-415b-94cc-d8053f4f9f8e";
46 static std::string characteristic0Value = "CHARACTERISTIC_0_VALUE";
47
48 // ============================================================================
49 // PropertyGetResult Implementation Class
50 // ============================================================================
51 class PropertyGetResultImpl : public API::PropertyGetResult {
52 public:
53         PropertyGetResultImpl() {
54                 name_ = "";
55                 value_ = "";
56         }
57         virtual ~PropertyGetResultImpl() {}
58
59 public:
60         virtual API::QueryResultType getResult() const {
61                 return API::QueryResultType::SUCCESS;
62         }
63
64         virtual const std::string& getName() const {
65                 return name_;
66         }
67
68         virtual const std::string& getValue() const {
69                 return value_;
70         }
71
72 public:
73         std::string name_;
74         std::string value_;
75 };
76
77 // ============================================================================
78 // PropertySetResult Implementation Class
79 // ============================================================================
80 class PropertySetResultImpl : public API::PropertySetResult {
81 public:
82         PropertySetResultImpl() {
83                 name_ = "";
84                 value_ = "";
85         }
86         virtual ~PropertySetResultImpl() {}
87
88 public:
89         virtual API::QueryResultType getResult() const {
90                 return API::QueryResultType::SUCCESS;
91         }
92
93         virtual const std::string& getName() const {
94                 return name_;
95         }
96
97         virtual const std::string& getValue() const {
98                 return value_;
99         }
100
101 public:
102         std::string name_;
103         std::string value_;
104
105 };
106
107 // ============================================================================
108 // Characteristic Implementation Class
109 // ============================================================================
110 class CharacteristicImpl : public API::Characteristic {
111 public:
112         CharacteristicImpl() {
113                 name_ = "";
114                 isReadable_ = true;
115                 isWritable_ = true;
116                 isConstant_ = false;
117         }
118         virtual ~CharacteristicImpl() {}
119
120 public:
121         virtual const std::string& getName() const {
122                 return name_;
123         }
124         virtual bool isReadable() const {
125                 return isReadable_;
126         }
127         virtual bool isWritable() const {
128                 return isWritable_;
129         }
130         virtual bool isConstant() const {
131                 return isConstant_;
132         }
133
134 public:
135         std::string name_;
136         bool isReadable_;
137         bool isWritable_;
138         bool isConstant_;
139 };
140
141 // ============================================================================
142 // Service Implementation Class
143 // ============================================================================
144 class ServiceImpl : public API::Service {
145 public:
146         ServiceImpl() {
147                 name_ = "";
148         }
149
150         virtual ~ServiceImpl() {}
151
152 public:
153
154         virtual const std::string& getName() const {
155                 return name_;
156         }
157
158         virtual const std::set<API::Characteristic::SharedPtr>& getCharacteristics() const {
159                 return characteristicSet_;
160         }
161 public:
162         std::string name_;
163         std::set<API::Characteristic::SharedPtr> characteristicSet_;
164 };
165 // ============================================================================
166 // DescriptionGetResult Implementation Class
167 // ============================================================================
168 class DescriptionGetResultImpl : public API::DescriptionGetResult {
169 public:
170         virtual ~DescriptionGetResultImpl() {}
171
172 public:
173         virtual API::QueryResultType getResult() const {
174                 return API::QueryResultType::SUCCESS;
175         };
176
177         virtual const std::set<API::Service::SharedPtr>& getServices() const {
178                 return serviceSet_;
179         }
180
181 public:
182         std::set<API::Service::SharedPtr> serviceSet_;
183 };
184
185 // ============================================================================
186 // RegisteredSetPropFunction
187 // ============================================================================
188 void setPropertyFunction(const std::string& propertyName, const std::string& propertyValue, const API::PropertySetFunction& asyncReturnFunc) {
189         logDebug(TAG, "Entering MockProtocol::setPropertyFunction");
190
191         PropertySetResultImpl result;
192
193         if (propertyName == "CHARACTERISTIC_0") {
194                 // CHARACTERISTIC_0 is read/write, non-constant, so allow it to be set to new value
195                 result.name_ = "CHARACTERISTIC_0";
196                 characteristic0Value = propertyValue;
197                 result.value_ = characteristic0Value;
198         }
199         else if (propertyName == "CHARACTERISTIC_1") {
200                 // CHARACTERISTIC_1 is constant, so ignore new value
201                 result.name_ = "CHARACTERISTIC_1";
202                 result.value_ = "CHARACTERISTIC_1_VALUE";
203         }
204
205         asyncReturnFunc(result);
206 }
207 // ============================================================================
208 // RegisteredGetPropFunction
209 // ============================================================================
210 void getPropertyFunction(const std::string& propertyName, const API::PropertyGetFunction& asyncReturnFunc) {
211         logDebug(TAG, "Entering MockProtocol::getPropertyFunction");
212
213         PropertyGetResultImpl result;
214
215         if (propertyName == "CHARACTERISTIC_0") {
216                 result.name_ = "CHARACTERISTIC_0";
217                 result.value_ = characteristic0Value;
218         }
219         else if (propertyName == "CHARACTERISTIC_1") {
220                 result.name_ = "CHARACTERISTIC_1";
221                 result.value_ = "CHARACTERISTIC_1_VALUE";
222         }
223
224         asyncReturnFunc(result);
225 }
226
227 // ============================================================================
228 // RegisteredGetDescriptionFunction
229 // ============================================================================
230 void getDescriptionFunction(const API::DescriptionGetFunction& asyncReturnFunc) {
231         logDebug(TAG, "Entering MockProtocol::getDescriptionFunction");
232
233         DescriptionGetResultImpl result;
234
235         std::shared_ptr<ServiceImpl> service = std::make_shared<ServiceImpl>();
236         if (service) {
237                 service->name_ = "SERVICE_A";
238                 std::shared_ptr<CharacteristicImpl> characteristic0 = std::make_shared<CharacteristicImpl>();
239                 if (characteristic0) {
240                         characteristic0->name_ = "CHARACTERISTIC_0";
241                         service->characteristicSet_.insert(characteristic0);
242                 }
243                 std::shared_ptr<CharacteristicImpl> characteristic1 = std::make_shared<CharacteristicImpl>();
244                 if (characteristic1) {
245                         characteristic1->name_ = "CHARACTERISTIC_1";
246                         characteristic1->isReadable_ = true;
247                         characteristic1->isWritable_ = false;
248                         characteristic1->isConstant_ = true;
249
250                         service->characteristicSet_.insert(characteristic1);
251                 }
252
253                 result.serviceSet_.insert(service);
254         }
255
256
257   // Invoke the callback
258   asyncReturnFunc(result);
259 }
260
261 // ============================================================================
262 // Class
263 // ============================================================================
264 MockProtocol::MockProtocol()
265 {
266         logDebug(TAG, "Entering MockProtocol::MockProtocol");
267
268         name_ = "Mock Protocol";
269         handle_ = Protocol::INVALID_HANDLE;
270 }
271
272 MockProtocol::~MockProtocol()
273 {
274         logDebug(TAG, "Entering MockProtocol::~MockProtocol");
275 }
276
277 void MockProtocol::setModel(const std::shared_ptr<Intel::CCFL::API::Model>& model) {
278         logDebug(TAG, "Entering MockProtocol::setModel");
279         model_ = model;
280 }
281
282 const Intel::CCFL::Protocols::Protocol::Handle MockProtocol::getHandle() {
283         logDebug(TAG, "Entering MockProtocol::getHandle");
284         return 0;
285 }
286
287 void MockProtocol::setHandle(const Handle handle) {
288         logDebug(TAG, "Entering MockProtocol::setHandle");
289         handle_ = handle;
290 }
291
292 const std::string& MockProtocol::getName() {
293 //      logDebug(TAG, "Entering MockProtocol::getName");
294         return name_;
295 }
296
297 void MockProtocol::setName(const std::string& name)
298 {
299         logDebug(TAG, "Entering MockProtocol::setName, name = %s", name.c_str());
300         name_ = name;
301 }
302
303 void MockProtocol::forceDeviceDiscovery() {
304         logDebug(TAG, "Entering MockProtocol::forceDeviceDiscovery");
305 }
306
307 // Test interface
308 void MockProtocol::testAddDevice(const UUID_t& deviceId, const std::string deviceName) {
309         logDebug(TAG, "Entering MockProtocol::testAddDevice, device name = %s, device UUID = %s", deviceName.c_str(), to_string(deviceId).c_str());
310
311         std::shared_ptr<API::Model> sharedModel = model_.lock();
312         if (sharedModel) {
313                 API::Device::SharedPtr device = sharedModel->getDevice(deviceId);
314                 if (device) {
315                         device->setName(deviceName);
316                         // Add a link to the device
317                         API::Link::SharedPtr link = std::make_shared<API::Link>();
318
319                         // Register property functions for the link
320                         API::Link::RegisteredGetDescriptionFunction regGetDescriptionFunction = getDescriptionFunction;
321                         link->registerGetDescriptionFunction(regGetDescriptionFunction);
322                         API::Link::RegisteredGetPropFunction regGetPropFunction = getPropertyFunction;
323                         link->registerGetPropertyFunction(regGetPropFunction);
324                         API::Link::RegisteredSetPropFunction regSetPropFunction = setPropertyFunction;
325                         link->registerSetPropertyFunction(regSetPropFunction);
326
327                         // Add the link to the device and signal the model that the device changed
328                         device->addLink(link);
329                         sharedModel->signalDeviceChange(deviceId, API::DeviceEvent::DeviceChange::DEVICE_ADDED);
330                 }
331         }
332 }
333
334 void MockProtocol::testRemoveDevice(const UUID_t& deviceId) {
335         logDebug(TAG, "Entering MockProtocol::testRemoveDevice, device UUID = %s", to_string(deviceId).c_str());
336
337         std::shared_ptr<API::Model> sharedModel = model_.lock();
338         if (sharedModel) {
339                 API::Device::SharedPtr device = sharedModel->getDevice(deviceId);
340                 if (device) {
341                         // Remove the link
342                         uint32_t linkCnt = device->getLinkCount();
343                         logDebug(TAG, "MockProtocol::testRemoveDevice, link count = %d", linkCnt);
344                         if (linkCnt > 0) {
345                                 API::Device::LinkList linkList = device->getLinks();
346                                 API::Link::SharedPtr link = linkList.front();
347                                 if (link) {
348                                         logDebug(TAG, "MockProtocol::testRemoveDevice, removing link");
349                                         if (device->removeLink(link)) {
350                                                 logDebug(TAG, "MockProtocol::testRemoveDevice, link removed, signaling device change");
351                                                 sharedModel->signalDeviceChange(deviceId, API::DeviceEvent::DeviceChange::DEVICE_REMOVED);
352                                         }
353                                 }
354                         }
355                 }
356         }
357 }
358
359 }
360 }
361 }