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