Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / resourceBroker / src / DevicePresence.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 "DevicePresence.h"
22 #include "RCSException.h"
23
24 namespace OIC
25 {
26     namespace Service
27     {
28         DevicePresence::DevicePresence()
29         {
30             state = DEVICE_STATE::REQUESTED;
31
32             presenceTimerHandle = 0;
33             isRunningTimeOut = false;
34
35             pSubscribeRequestCB = std::bind(&DevicePresence::subscribeCB, this,
36                         std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
37             pTimeoutCB = std::bind(&DevicePresence::timeOutCB, this, std::placeholders::_1);
38         }
39
40         DevicePresence::~DevicePresence()
41         {
42             if(presenceSubscriber.isSubscribing())
43             {
44                 OC_LOG_V(DEBUG,BROKER_TAG,"unsubscribed presence.");
45                 presenceSubscriber.unsubscribe();
46             }
47             resourcePresenceList.clear();
48             OC_LOG_V(DEBUG,BROKER_TAG,"destroy Timer.");
49         }
50
51         void DevicePresence::initializeDevicePresence(PrimitiveResourcePtr pResource)
52         {
53             OC_LOG_V(DEBUG, BROKER_TAG, "initializeDevicePresence()");
54             address = pResource->getHost();
55
56             OC_LOG_V(DEBUG, BROKER_TAG, "%s",address.c_str());
57
58             try
59             {
60                 OC_LOG_V(DEBUG, BROKER_TAG, "subscribe Presence");
61                 presenceSubscriber
62                 = PresenceSubscriber(address, BROKER_TRANSPORT, pSubscribeRequestCB);
63             } catch(PlatformException &e)
64             {
65                 OC_LOG_V(DEBUG, BROKER_TAG,
66                         "exception in subscribe Presence %s", e.getReason().c_str());
67                 throw;
68             }
69             presenceTimerHandle
70             = presenceTimer.post(BROKER_DEVICE_PRESENCE_TIMEROUT, pTimeoutCB);
71         }
72         DEVICE_STATE DevicePresence::getDeviceState() const
73         {
74             return state;
75         }
76         const std::string DevicePresence::getAddress() const
77         {
78             OC_LOG_V(DEBUG, BROKER_TAG, "getAddress()");
79             return address;
80         }
81
82         void DevicePresence::addPresenceResource(ResourcePresence * rPresence)
83         {
84             OC_LOG_V(DEBUG, BROKER_TAG, "addPresenceResource()");
85             resourcePresenceList.push_back(rPresence);
86         }
87
88         void DevicePresence::removePresenceResource(ResourcePresence * rPresence)
89         {
90             OC_LOG_V(DEBUG, BROKER_TAG, "removePresenceResource()");
91             resourcePresenceList.remove(rPresence);
92         }
93
94         void DevicePresence::changeAllPresenceMode(BROKER_MODE mode)
95         {
96             OC_LOG_V(DEBUG, BROKER_TAG, "changeAllPresenceMode()");
97             if(!resourcePresenceList.empty())
98             {
99                 for(auto it : resourcePresenceList)
100                 {
101                     it->changePresenceMode(mode);
102                 }
103             }
104         }
105
106         bool DevicePresence::isEmptyResourcePresence() const
107         {
108             OC_LOG_V(DEBUG, BROKER_TAG, "isEmptyResourcePresence()");
109             return resourcePresenceList.empty();
110         }
111
112         void DevicePresence::subscribeCB(OCStackResult ret,
113                 const unsigned int seq, const std::string & hostAddress)
114         {
115             OC_LOG_V(DEBUG, BROKER_TAG, "subscribeCB()");
116             OC_LOG_V(DEBUG, BROKER_TAG, "Received presence CB from: %s",hostAddress.c_str());
117             OC_LOG_V(DEBUG, BROKER_TAG, "In subscribeCB: %d",ret);
118
119             if(isRunningTimeOut)
120             {
121                 std::unique_lock<std::mutex> lock(timeoutMutex);
122                 condition.wait(lock);
123             }
124             presenceTimer.cancel(presenceTimerHandle);
125
126             switch(ret)
127             {
128                 case OC_STACK_OK:
129                 case OC_STACK_RESOURCE_CREATED:
130                 case OC_STACK_CONTINUE:
131                 {
132                     OC_LOG_V(DEBUG, BROKER_TAG, "SEQ# %d",seq);
133                     state = DEVICE_STATE::ALIVE;
134                     OC_LOG_V(DEBUG, BROKER_TAG, "device state : %d",
135                             (int)(state.load(boost::memory_order_consume)));
136                     changeAllPresenceMode(BROKER_MODE::DEVICE_PRESENCE_MODE);
137                     presenceTimerHandle
138                     = presenceTimer.post(BROKER_DEVICE_PRESENCE_TIMEROUT, pTimeoutCB);
139                     break;
140                 }
141                 case OC_STACK_INVALID_REQUEST_HANDLE:
142                 case OC_STACK_RESOURCE_DELETED:
143                 case OC_STACK_TIMEOUT:
144                 case OC_STACK_COMM_ERROR:
145                 case OC_STACK_PRESENCE_STOPPED:
146                 case OC_STACK_PRESENCE_TIMEOUT:
147                 case OC_STACK_PRESENCE_DO_NOT_HANDLE:
148                 {
149                     state = DEVICE_STATE::LOST_SIGNAL;
150                     changeAllPresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
151                     break;
152                 }
153                 default:
154                 {
155                     OC_LOG_V(DEBUG, BROKER_TAG, "Presence Lost Signal because unknown type");
156                     state = DEVICE_STATE::LOST_SIGNAL;
157                     changeAllPresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
158                     break;
159                 }
160             }
161         }
162
163         void DevicePresence::timeOutCB(TimerID /*id*/)
164         {
165             OC_LOG_V(DEBUG,BROKER_TAG,"timeOutCB()");
166             std::unique_lock<std::mutex> lock(timeoutMutex);
167             isRunningTimeOut = true;
168
169             OC_LOG_V(DEBUG, BROKER_TAG,
170                     "Timeout execution. will be discard after receiving cb message");
171             state = DEVICE_STATE::LOST_SIGNAL;
172             changeAllPresenceMode(BROKER_MODE::NON_PRESENCE_MODE);
173
174             isRunningTimeOut = false;
175             condition.notify_all();
176         }
177     } // namespace Service
178 } // namespace OIC