Switch to unified view

a/libupnpp/control/service.cxx b/libupnpp/control/service.cxx
...
...
13
 *       along with this program; if not, write to the
13
 *       along with this program; if not, write to the
14
 *       Free Software Foundation, Inc.,
14
 *       Free Software Foundation, Inc.,
15
 *       59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15
 *       59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16
 */
16
 */
17
#include <string>
17
#include <string>
18
#include <unordered_map>
19
#include <functional>
18
using namespace std;
20
using namespace std;
21
using namespace std::placeholders;
22
23
#include <upnp/upnp.h>
19
24
20
#include "libupnpp/log.hxx"
25
#include "libupnpp/log.hxx"
26
#include "libupnpp/ptmutex.hxx"
21
#include "libupnpp/upnpplib.hxx"
27
#include "libupnpp/upnpplib.hxx"
22
#include "libupnpp/control/service.hxx"
28
#include "libupnpp/control/service.hxx"
23
#include "libupnpp/control/cdirectory.hxx"
29
#include "libupnpp/control/cdirectory.hxx"
30
#include "libupnpp/control/avlastchg.hxx"
24
31
25
namespace UPnPClient {
32
namespace UPnPClient {
26
33
27
Service *service_factory(const string& servicetype,
34
Service *service_factory(const string& servicetype,
28
                         const UPnPDeviceDesc& device,
35
                         const UPnPDeviceDesc& device,
...
...
76
    if (ret != UPNP_E_SUCCESS) {
83
    if (ret != UPNP_E_SUCCESS) {
77
        LOGINF("Service::runAction: UpnpSendAction failed: " <<
84
        LOGINF("Service::runAction: UpnpSendAction failed: " <<
78
               UpnpGetErrorMessage(ret) << endl);
85
               UpnpGetErrorMessage(ret) << endl);
79
        return ret;
86
        return ret;
80
    }
87
    }
81
    LOGDEB("Result xml: [" << ixmlPrintDocument(response) << "]" << endl);
88
    LOGDEB("Service::runAction: Result xml: [" << ixmlPrintDocument(response) << "]" << endl);
82
89
83
    if (!decodeSoapBody(args.name.c_str(), response, &data)) {
90
    if (!decodeSoapBody(args.name.c_str(), response, &data)) {
84
        LOGERR("Service::runAction: Could not decode response: " <<
91
        LOGERR("Service::runAction: Could not decode response: " <<
85
               ixmlPrintDocument(response) << endl);
92
               ixmlPrintDocument(response) << endl);
86
        return UPNP_E_BAD_RESPONSE;
93
        return UPNP_E_BAD_RESPONSE;
87
    }
94
    }
88
    return UPNP_E_SUCCESS;
95
    return UPNP_E_SUCCESS;
89
}
96
}
90
97
98
99
static PTMutexInit cblock;
100
int Service::srvCB(Upnp_EventType et, void* vevp, void*)
101
{
102
    PTMutexLocker lock(cblock);
103
104
    //LOGDEB("Service:srvCB: " << LibUPnP::evTypeAsString(et) << endl);
105
106
    switch (et) {
107
    case UPNP_EVENT_RENEWAL_COMPLETE:
108
    case UPNP_EVENT_SUBSCRIBE_COMPLETE:
109
    case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
110
    case UPNP_EVENT_AUTORENEWAL_FAILED:
111
    {
112
        const char *ff = (const char *)vevp;
113
        LOGDEB("Service:srvCB: subs event: " << ff << endl);
114
        break;
115
    }
116
117
    case UPNP_EVENT_RECEIVED:
118
    {
119
        struct Upnp_Event *evp = (struct Upnp_Event *)vevp;
120
        LOGDEB1("Service:srvCB: var change event: Sid: " <<
121
               evp->Sid << " EventKey " << evp->EventKey << 
122
               " changed: " << ixmlPrintDocument(evp->ChangedVariables)<< endl);
123
124
        
125
        unordered_map<string, string> props;
126
        if (!decodePropertySet(evp->ChangedVariables, props)) {
127
            LOGERR("Service::srvCB: could not decode EVENT propertyset" <<endl);
128
            return UPNP_E_BAD_RESPONSE;
129
        }
130
        //for (auto& entry: props) {
131
        //LOGDEB(entry.first << " -> " << entry.second << endl;);
132
        //}
133
        std::unordered_map<std::string, evtCBFunc>::iterator it = 
134
            o_calls.find(evp->Sid);
135
136
        if (it!= o_calls.end()) {
137
            (it->second)(props);
138
        } else {
139
            LOGINF("Service::srvCB: no callback found for " << evp->Sid << 
140
                   endl);
141
        }
142
        break;
143
    }
144
145
    default:
146
        // Ignore other events for now
147
        LOGDEB("Service:srvCB: unprocessed evt type: [" << 
148
               LibUPnP::evTypeAsString(et) << "]"  << endl);
149
        break;
150
    }
151
152
    return UPNP_E_SUCCESS;
91
}
153
}
154
155
bool Service::initEvents()
156
{
157
    LOGDEB("Service::initEvents" << endl);
158
159
    PTMutexLocker lock(cblock);
160
    static bool eventinit(false);
161
    if (eventinit)
162
        return true;
163
    eventinit = true;
164
165
    LibUPnP *lib = LibUPnP::getLibUPnP();
166
    if (lib == 0) {
167
        LOGERR("Service::initEvents: Can't get lib" << endl);
168
        return false;
169
    }
170
    lib->registerHandler(UPNP_EVENT_RENEWAL_COMPLETE, srvCB, 0);
171
    lib->registerHandler(UPNP_EVENT_SUBSCRIBE_COMPLETE, srvCB, 0);
172
    lib->registerHandler(UPNP_EVENT_UNSUBSCRIBE_COMPLETE, srvCB, 0);
173
    lib->registerHandler(UPNP_EVENT_AUTORENEWAL_FAILED, srvCB, 0);
174
    lib->registerHandler(UPNP_EVENT_RECEIVED, srvCB, 0);
175
    return true;
176
}
177
178
//void Service::evtCallback(
179
//    const std::unordered_map<std::string, std::string>*)
180
//{
181
//    LOGDEB("Service::evtCallback!! service: " << m_serviceType << endl);
182
//}
183
184
bool Service::subscribe()
185
{
186
    //LOGDEB("Service::subscribe" << endl);
187
    LibUPnP* lib = LibUPnP::getLibUPnP();
188
    if (lib == 0) {
189
        LOGINF("Service::runAction: no lib" << endl);
190
        return UPNP_E_OUTOF_MEMORY;
191
    }
192
    int timeout = 1800;
193
    int ret = UpnpSubscribe(lib->getclh(), m_eventURL.c_str(),
194
                            &timeout, m_SID);
195
    if (ret != UPNP_E_SUCCESS) {
196
        LOGERR("Service:subscribe: failed: " << 
197
               UpnpGetErrorMessage(ret) << endl);
198
        return false;
199
    } 
200
    LOGDEB("Service::subscribe: sid: " << m_SID << endl);
201
    return true;
202
}
203
204
void Service::registerCallback(evtCBFunc c)
205
{
206
    PTMutexLocker lock(cblock);
207
    o_calls[m_SID] = c;
208
}
209
210
std::unordered_map<std::string, evtCBFunc> Service::o_calls;
211
212
}