Merge branch 'master' into group-manager
[platform/upstream/iotivity.git] / service / scene-manager / src / SceneMemberResource.cpp
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 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 "SceneMemberResource.h"
22
23 #include <atomic>
24 #include "OCPlatform.h"
25
26 namespace OIC
27 {
28     namespace Service
29     {
30         namespace
31         {
32             std::atomic_int numOfSceneMember(0);
33         }
34
35         SceneMemberResource::Ptr
36         SceneMemberResource::createSceneMemberResource(
37                 RCSRemoteResourceObject::Ptr remoteObject)
38         {
39             auto instance = new SceneMemberResource();
40             SceneMemberResource::Ptr newSceneMemberObject;
41             newSceneMemberObject.reset(instance);
42
43             newSceneMemberObject->m_Uri = PREFIX_SCENE_MEMBER_URI + "/" +
44                 std::to_string(numOfSceneMember++);
45             newSceneMemberObject->m_SceneMemberResourceObj
46                 = RCSResourceObject::Builder(
47                         newSceneMemberObject->m_Uri,
48                         SCENE_MEMBER_RT, OC_RSRVD_INTERFACE_DEFAULT).
49                         setDiscoverable(true).setObservable(false).build();
50             newSceneMemberObject->m_RequestHandler.m_Owner
51                 = std::weak_ptr<SceneMemberResource>(newSceneMemberObject);
52
53             newSceneMemberObject->m_RemoteMemberObj = remoteObject;
54
55             auto resourceObj = newSceneMemberObject->m_SceneMemberResourceObj;
56
57             RCSResourceObject::LockGuard guard(resourceObj);
58             resourceObj->setAttribute(SCENE_KEY_ID, SceneUtils::OICGenerateUUIDStr());
59             resourceObj->setAttribute(SCENE_KEY_NAME, std::string());
60
61             RCSResourceAttributes subAtt;
62             subAtt[SCENE_KEY_HREF]
63                     = RCSResourceAttributes::Value(
64                             remoteObject->getAddress() + remoteObject->getUri());
65             subAtt[SCENE_KEY_IF] = RCSResourceAttributes::Value(remoteObject->getInterfaces());
66             subAtt[SCENE_KEY_RT] = RCSResourceAttributes::Value(remoteObject->getTypes());
67             resourceObj->setAttribute(SCENE_KEY_PAYLOAD_LINK, subAtt);
68
69             resourceObj->setAttribute(
70                     SCENE_KEY_SCENEMAPPINGS, std::vector<RCSResourceAttributes>());
71
72             resourceObj->setSetRequestHandler(std::bind(
73                     &SceneMemberResource::SceneMemberRequestHandler::onSetRequest,
74                     newSceneMemberObject->m_RequestHandler,
75                     std::placeholders::_1, std::placeholders::_2));
76
77             return newSceneMemberObject;
78         }
79
80         SceneMemberResource::Ptr
81         SceneMemberResource::createSceneMemberResource(const RCSResourceAttributes & link)
82         {
83             return createSceneMemberResource(RCSResourceAttributes(link));
84         }
85
86         SceneMemberResource::Ptr
87         SceneMemberResource::createSceneMemberResource(RCSResourceAttributes && link)
88         {
89             auto href = link.at(SCENE_KEY_HREF).get<std::string>();
90
91             std::string address;
92             std::string uri;
93
94             SceneUtils::getHostUriString(href, &address, &uri);
95
96             auto ocResourcePtr
97                 = OC::OCPlatform::constructResourceObject(
98                     address, uri, OCConnectivityType::CT_ADAPTER_IP, false,
99                     link.at(SCENE_KEY_RT).get<std::vector<std::string>>(),
100                     link.at(SCENE_KEY_IF).get<std::vector<std::string>>());
101
102             return createSceneMemberResource(RCSRemoteResourceObject::fromOCResource(ocResourcePtr));
103         }
104
105         void SceneMemberResource::addMappingInfo(MappingInfo && mInfo)
106         {
107             RCSResourceAttributes newAtt;
108             {
109                 RCSResourceObject::LockGuard guard(m_SceneMemberResourceObj);
110                 newAtt = m_SceneMemberResourceObj->getAttributes();
111             }
112
113             auto mappingInfo = newAtt.at(SCENE_KEY_SCENEMAPPINGS).
114                     get<std::vector<RCSResourceAttributes>>();
115
116             struct FindSceneName
117             {
118                 bool operator()(RCSResourceAttributes att) const
119                 {
120                     return att.at(SCENE_KEY_SCENE).get<std::string>() == name;
121                 }
122                 std::string name;
123             };
124
125             FindSceneName fScene;
126             fScene.name = mInfo.sceneName;
127             auto foundMInfo = std::find_if(mappingInfo.begin(), mappingInfo.end(), fScene);
128
129             if (foundMInfo != mappingInfo.end() &&
130                     (* foundMInfo).at(SCENE_KEY_MEMBERPROPERTY).get<std::string>() == mInfo.key)
131             {
132                 mappingInfo.erase(foundMInfo);
133             }
134             RCSResourceAttributes newMapInfo;
135             newMapInfo[SCENE_KEY_SCENE] = RCSResourceAttributes::Value(mInfo.sceneName);
136             newMapInfo[SCENE_KEY_MEMBERPROPERTY] = RCSResourceAttributes::Value(mInfo.key);
137             newMapInfo[SCENE_KEY_MEMBERVALUE] = mInfo.value;
138             mappingInfo.push_back(newMapInfo);
139
140             RCSResourceObject::LockGuard guard(m_SceneMemberResourceObj);
141             m_SceneMemberResourceObj->setAttribute(SCENE_KEY_SCENEMAPPINGS, mappingInfo);
142         }
143
144         void SceneMemberResource::addMappingInfo(const MappingInfo & mInfo)
145         {
146             addMappingInfo(MappingInfo(mInfo));
147         }
148
149         std::vector<SceneMemberResource::MappingInfo>
150         SceneMemberResource::getMappingInfo()
151         {
152             auto mappingInfo
153                 = m_SceneMemberResourceObj->getAttributeValue(SCENE_KEY_SCENEMAPPINGS).
154                   get<std::vector<RCSResourceAttributes>>();
155
156             std::vector<MappingInfo> retMInfo;
157             for(unsigned int it = 0; it < mappingInfo.size(); ++it)
158             {
159                 MappingInfo info(mappingInfo[it].at(
160                                          SCENE_KEY_SCENE).get<std::string>(),
161                                  mappingInfo[it].at(
162                                          SCENE_KEY_MEMBERPROPERTY).get<std::string>(),
163                                  mappingInfo[it].at(
164                                          SCENE_KEY_MEMBERVALUE));
165                 retMInfo.push_back(info);
166             }
167
168             return retMInfo;
169         }
170
171         std::string SceneMemberResource::getId() const
172         {
173             return m_SceneMemberResourceObj->getAttributeValue(SCENE_KEY_ID).get<std::string>();
174         }
175
176         std::string SceneMemberResource::getFullUri() const
177         {
178             return std::string(COAP_TAG + SceneUtils::getNetAddress() + m_Uri);
179         }
180
181         RCSRemoteResourceObject::Ptr SceneMemberResource::getRemoteResourceObject() const
182         {
183             return m_RemoteMemberObj;
184         }
185
186         RCSResourceObject::Ptr SceneMemberResource::getRCSResourceObject() const
187         {
188             return m_SceneMemberResourceObj;
189         }
190
191         void SceneMemberResource::execute(std::string && sceneName)
192         {
193             execute(std::move(sceneName), nullptr);
194         }
195
196         void SceneMemberResource::execute(const std::string & sceneName)
197         {
198             execute(std::string(sceneName));
199         }
200
201         void SceneMemberResource::execute(
202                 std::string && sceneName, executeCallback executeCB)
203         {
204             bool hasScene = false;
205             auto mInfo = getMappingInfo();
206
207             for (unsigned int it = 0; it < mInfo.size(); ++it)
208             {
209                 if (mInfo[it].sceneName == sceneName)
210                 {
211                     hasScene = true;
212
213                     RCSResourceAttributes setAtt;
214                     setAtt[mInfo[it].key] = mInfo[it].value;
215                     m_RemoteMemberObj->setRemoteAttributes(setAtt, executeCB);
216                 }
217             }
218             if (!hasScene && executeCB != nullptr)
219             {
220                 executeCB(RCSResourceAttributes(), SCENE_RESPONSE_SUCCESS);
221             }
222         }
223
224         void SceneMemberResource::execute(
225                 const std::string & sceneName, executeCallback executeCB)
226         {
227             execute(std::string(sceneName), std::move(executeCB));
228         }
229
230         RCSSetResponse SceneMemberResource::SceneMemberRequestHandler::
231         onSetRequest(const RCSRequest & /*request*/, RCSResourceAttributes & attributes)
232         {
233             auto ptr = m_Owner.lock();
234             if (!ptr)
235             {
236                 return RCSSetResponse::create(
237                         RCSResourceAttributes(attributes), SCENE_CLIENT_BADREQUEST).
238                         setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
239             }
240
241             if (attributes.contains(SCENE_KEY_SCENEMAPPINGS))
242             {
243                 auto sceneMappings
244                     = attributes.at(SCENE_KEY_SCENEMAPPINGS).get<std::vector<RCSResourceAttributes>>();
245                 for (unsigned int it = 0; it < sceneMappings.size(); ++it)
246                 {
247                     ptr->addMappingInfo(SceneMemberResource::MappingInfo(
248                             sceneMappings[it].at(SCENE_KEY_SCENE).get<std::string>(),
249                             sceneMappings[it].at(SCENE_KEY_MEMBERPROPERTY).get<std::string>(),
250                             sceneMappings[it].at(SCENE_KEY_MEMBERVALUE)));
251                 }
252             }
253
254             return RCSSetResponse::create(RCSResourceAttributes(attributes)).
255                     setAcceptanceMethod(RCSSetResponse::AcceptanceMethod::IGNORE);
256         }
257     }
258 }