Rename resource-encapsulation exception classes.
[platform/upstream/iotivity.git] / service / notification-manager / NotificationManager / src / ResourceHosting.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 "ResourceHosting.h"
22
23 #include "PresenceSubscriber.h"
24 #include "OCPlatform.h"
25 #include "RCSDiscoveryManager.h"
26
27 namespace OIC
28 {
29 namespace Service
30 {
31
32 namespace
33 {
34     std::string HOSTING_TAG = "/hosting";
35     size_t HOSTING_TAG_SIZE = (size_t)HOSTING_TAG.size();
36     std::string MULTICAST_PRESENCE_ADDRESS = std::string("coap://") + OC_MULTICAST_PREFIX;
37     std::string HOSTING_RESOURSE_TYPE = "resource.hosting";
38 }
39
40 ResourceHosting * ResourceHosting::s_instance(nullptr);
41 std::mutex ResourceHosting::s_mutexForCreation;
42
43 ResourceHosting::ResourceHosting()
44 : hostingObjectList(),
45   discoveryManager(nullptr),
46   presenceHandle(),
47   pPresenceCB(nullptr), pDiscoveryCB(nullptr)
48 {
49 }
50
51 ResourceHosting * ResourceHosting::getInstance()
52 {
53     if (!s_instance)
54     {
55         s_mutexForCreation.lock();
56         if (!s_instance)
57         {
58             s_instance = new ResourceHosting();
59             s_instance->initializeResourceHosting();
60         }
61         s_mutexForCreation.unlock();
62     }
63     return s_instance;
64 }
65
66 void ResourceHosting::startHosting()
67 {
68     try
69     {
70         requestMulticastPresence();
71         requestMulticastDiscovery();
72     }catch(const RCSPlatformException &e)
73     {
74         OIC_HOSTING_LOG(DEBUG,
75                 "[ResourceHosting::startHosting]PlatformException:%s", e.what());
76         throw;
77     }catch(const RCSInvalidParameterException &e)
78     {
79         OIC_HOSTING_LOG(DEBUG,
80                 "[ResourceHosting::startHosting]InvalidParameterException:%s", e.what());
81         throw;
82     }catch(const std::exception &e)
83     {
84         OIC_HOSTING_LOG(DEBUG,
85                 "[ResourceHosting::startHosting]std::exception:%s", e.what());
86         throw;
87     }
88 }
89
90 void ResourceHosting::stopHosting()
91 {
92     // clear list hostingObjectList
93     if(presenceHandle.isSubscribing())
94     {
95         presenceHandle.unsubscribe();
96     }
97
98     hostingObjectList.clear();
99 }
100
101 void ResourceHosting::initializeResourceHosting()
102 {
103     pPresenceCB = std::bind(&ResourceHosting::presenceHandler, this,
104             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
105     pDiscoveryCB = std::bind(&ResourceHosting::discoverHandler, this,
106             std::placeholders::_1);
107
108     discoveryManager = RCSDiscoveryManager::getInstance();
109 }
110
111 void ResourceHosting::requestMulticastPresence()
112 {
113     try
114     {
115         presenceHandle = PresenceSubscriber(MULTICAST_PRESENCE_ADDRESS,
116                 OCConnectivityType::CT_DEFAULT, pPresenceCB);
117     }catch(...)
118     {
119         throw;
120     }
121 }
122
123 void ResourceHosting::presenceHandler(OCStackResult ret, const unsigned int /*seq*/,
124         const std::string & address)
125 {
126     switch(ret)
127     {
128     case OC_STACK_OK:
129     case OC_STACK_CONTINUE:
130     case OC_STACK_RESOURCE_CREATED:
131     {
132         // TODO start discovery
133         requestDiscovery(address);
134         break;
135     }
136
137     case OC_STACK_RESOURCE_DELETED:
138     case OC_STACK_COMM_ERROR:
139     case OC_STACK_TIMEOUT:
140     case OC_STACK_PRESENCE_STOPPED:
141     case OC_STACK_PRESENCE_TIMEOUT:
142     case OC_STACK_PRESENCE_DO_NOT_HANDLE:
143     case OC_STACK_ERROR:
144         // TODO presence error
145         break;
146
147     case OC_STACK_INVALID_URI:
148     case OC_STACK_INVALID_QUERY:
149     case OC_STACK_INVALID_IP:
150     case OC_STACK_INVALID_PORT:
151     case OC_STACK_INVALID_CALLBACK:
152     case OC_STACK_INVALID_METHOD:
153     case OC_STACK_INVALID_PARAM:
154     case OC_STACK_INVALID_OBSERVE_PARAM:
155     case OC_STACK_NO_MEMORY:
156     case OC_STACK_ADAPTER_NOT_ENABLED:
157     case OC_STACK_NOTIMPL:
158     case OC_STACK_NO_RESOURCE:
159     case OC_STACK_RESOURCE_ERROR:
160     case OC_STACK_SLOW_RESOURCE:
161     case OC_STACK_DUPLICATE_REQUEST:
162     case OC_STACK_NO_OBSERVERS:
163     case OC_STACK_OBSERVER_NOT_FOUND:
164     case OC_STACK_INVALID_OPTION:
165     case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
166     case OC_STACK_MALFORMED_RESPONSE:
167     case OC_STACK_PERSISTENT_BUFFER_REQUIRED:
168     case OC_STACK_INVALID_REQUEST_HANDLE:
169     case OC_STACK_INVALID_DEVICE_INFO:
170     case OC_STACK_INVALID_JSON:
171         break;
172     default:
173         // TODO unknown presence result
174         break;
175     }
176 }
177
178 void ResourceHosting::requestMulticastDiscovery()
179 {
180     requestDiscovery();
181 }
182 void ResourceHosting::requestDiscovery(std::string address)
183 {
184     std::string host = address;
185     RCSAddress rcsAddress = RCSAddress::unicast(host);
186     discoveryTask = discoveryManager->discoverResourceByType(
187         rcsAddress, OC_RSRVD_WELL_KNOWN_URI, HOSTING_RESOURSE_TYPE, pDiscoveryCB);
188 }
189
190 void ResourceHosting::discoverHandler(RemoteObjectPtr remoteResource)
191 {
192     std::string discoverdUri = remoteResource->getUri();
193     if(discoverdUri.compare(
194             discoverdUri.size()-HOSTING_TAG_SIZE, HOSTING_TAG_SIZE, HOSTING_TAG) != 0)
195     {
196         return;
197     }
198
199     HostingObjectPtr foundHostingObject = findRemoteResource(remoteResource);
200     if(foundHostingObject == nullptr)
201     {
202         try
203         {
204             foundHostingObject = std::make_shared<HostingObject>();
205             foundHostingObject->initializeHostingObject(remoteResource,
206                     std::bind(&ResourceHosting::destroyedHostingObject, this,
207                             HostingObjectWeakPtr(foundHostingObject)));
208             hostingObjectList.push_back(foundHostingObject);
209         }catch(const RCSInvalidParameterException &e)
210         {
211             OIC_HOSTING_LOG(DEBUG,
212                     "[ResourceHosting::discoverHandler]InvalidParameterException:%s", e.what());
213         }
214     }
215 }
216
217 ResourceHosting::HostingObjectPtr ResourceHosting::findRemoteResource(
218         RemoteObjectPtr remoteResource)
219 {
220     HostingObjectPtr retObject = nullptr;
221
222     for(auto it : hostingObjectList)
223     {
224         RemoteObjectPtr inListPtr = it->getRemoteResource();
225         if(inListPtr != nullptr && isSameRemoteResource(inListPtr, remoteResource))
226         {
227             retObject = it;
228         }
229     }
230
231     return retObject;
232 }
233
234 bool ResourceHosting::isSameRemoteResource(
235         RemoteObjectPtr remoteResource_1, RemoteObjectPtr remoteResource_2)
236 {
237     bool ret = false;
238     if(remoteResource_1->getAddress() == remoteResource_2->getAddress() &&
239        remoteResource_1->getUri() == remoteResource_2->getUri())
240     {
241         ret = true;
242     }
243     return ret;
244 }
245
246 void ResourceHosting::destroyedHostingObject(HostingObjectWeakPtr destroyedWeakPtr)
247 {
248     auto destroyedPtr = destroyedWeakPtr.lock();
249     if (destroyedPtr) return;
250
251     std::unique_lock<std::mutex> lock(mutexForList);
252     hostingObjectList.remove(destroyedPtr);
253 }
254
255 } /* namespace Service */
256 } /* namespace OIC */