Switch to unified view

a/libupnpp/control/cdirectory.cxx b/libupnpp/control/cdirectory.cxx
...
...
72
    }
72
    }
73
    bool operator() (const string& val) const {
73
    bool operator() (const string& val) const {
74
        return simpleMatch(val);
74
        return simpleMatch(val);
75
    }
75
    }
76
76
77
    bool ok() const {return m_ok;}
77
    bool ok() const {
78
        return m_ok;
79
    }
78
private:
80
private:
79
    bool m_ok;
81
    bool m_ok;
80
    regex_t m_expr;
82
    regex_t m_expr;
81
};
83
};
82
#else
84
#else
83
class SimpleRegexp {
85
class SimpleRegexp {
84
public:
86
public:
85
  SimpleRegexp(const string& exp, int flags)
87
    SimpleRegexp(const string& exp, int flags)
86
      : m_expr(exp, basic_regex<char>::flag_type(flags)), m_ok(true) {}
88
        : m_expr(exp, basic_regex<char>::flag_type(flags)), m_ok(true) {}
87
  
89
88
  bool simpleMatch(const string& val) const {
90
    bool simpleMatch(const string& val) const {
89
      if (!ok())
91
        if (!ok())
90
          return false;
92
            return false;
91
      return regex_match(val, m_expr);
93
        return regex_match(val, m_expr);
92
  }
94
    }
93
  bool operator() (const string& val) const {
95
    bool operator() (const string& val) const {
94
      return simpleMatch(val);
96
        return simpleMatch(val);
95
  }
97
    }
96
98
97
  bool ok() const { return m_ok; }
99
    bool ok() const {
100
        return m_ok;
101
    }
98
private:
102
private:
99
  basic_regex<char> m_expr;
103
    basic_regex<char> m_expr;
100
  bool m_ok;
104
    bool m_ok;
101
};
105
};
102
#define REG_ICASE std::regex_constants::icase
106
#define REG_ICASE std::regex_constants::icase
103
#define REG_NOSUB std::regex_constants::nosubs
107
#define REG_NOSUB std::regex_constants::nosubs
104
108
105
#endif
109
#endif
...
...
119
123
120
ContentDirectory::ContentDirectory(const UPnPDeviceDesc& device,
124
ContentDirectory::ContentDirectory(const UPnPDeviceDesc& device,
121
                                   const UPnPServiceDesc& service)
125
                                   const UPnPServiceDesc& service)
122
    : Service(device, service), m_rdreqcnt(200), m_serviceKind(CDSKIND_UNKNOWN)
126
    : Service(device, service), m_rdreqcnt(200), m_serviceKind(CDSKIND_UNKNOWN)
123
{
127
{
124
    LOGERR("ContentDirectory::ContentDirectory: manufacturer: " << 
128
    LOGERR("ContentDirectory::ContentDirectory: manufacturer: " <<
125
           getManufacturer() << " model " << getModelName() << endl);
129
           getManufacturer() << " model " << getModelName() << endl);
126
130
127
    if (bubble_rx(getModelName())) {
131
    if (bubble_rx(getModelName())) {
128
        m_serviceKind = CDSKIND_BUBBLE;
132
        m_serviceKind = CDSKIND_BUBBLE;
129
        LOGDEB1("ContentDirectory::ContentDirectory: BUBBLE" << endl);
133
        LOGDEB1("ContentDirectory::ContentDirectory: BUBBLE" << endl);
...
...
140
        m_serviceKind = CDSKIND_MINIM;
144
        m_serviceKind = CDSKIND_MINIM;
141
        LOGDEB1("ContentDirectory::ContentDirectory: MINIM" << endl);
145
        LOGDEB1("ContentDirectory::ContentDirectory: MINIM" << endl);
142
    } else if (twonky_rx(getModelName())) {
146
    } else if (twonky_rx(getModelName())) {
143
        m_serviceKind = CDSKIND_TWONKY;
147
        m_serviceKind = CDSKIND_TWONKY;
144
        LOGDEB1("ContentDirectory::ContentDirectory: TWONKY" << endl);
148
        LOGDEB1("ContentDirectory::ContentDirectory: TWONKY" << endl);
145
    } 
149
    }
146
    registerCallback();
150
    registerCallback();
147
}
151
}
148
ContentDirectory::~ContentDirectory()
152
ContentDirectory::~ContentDirectory()
149
{
153
{
150
    unregisterCallback();
154
    unregisterCallback();
...
...
157
    const string::size_type sz(SType.size()-2);
161
    const string::size_type sz(SType.size()-2);
158
    return !SType.compare(0, sz, st, 0, sz);
162
    return !SType.compare(0, sz, st, 0, sz);
159
}
163
}
160
164
161
static bool DSAccum(vector<CDSH>* out,
165
static bool DSAccum(vector<CDSH>* out,
162
                    const UPnPDeviceDesc& device, 
166
                    const UPnPDeviceDesc& device,
163
                    const UPnPServiceDesc& service)
167
                    const UPnPServiceDesc& service)
164
{
168
{
165
    if (ContentDirectory::isCDService(service.serviceType)) {
169
    if (ContentDirectory::isCDService(service.serviceType)) {
166
        out->push_back(CDSH(new ContentDirectory(device, service)));
170
        out->push_back(CDSH(new ContentDirectory(device, service)));
167
    }
171
    }
...
...
174
    UPnPDeviceDirectory::Visitor visitor = bind(DSAccum, &vds, _1, _2);
178
    UPnPDeviceDirectory::Visitor visitor = bind(DSAccum, &vds, _1, _2);
175
    UPnPDeviceDirectory::getTheDir()->traverse(visitor);
179
    UPnPDeviceDirectory::getTheDir()->traverse(visitor);
176
    return !vds.empty();
180
    return !vds.empty();
177
}
181
}
178
182
179
// Get server by friendly name. 
183
// Get server by friendly name.
180
bool ContentDirectory::getServerByName(const string& fname, CDSH& server)
184
bool ContentDirectory::getServerByName(const string& fname, CDSH& server)
181
{
185
{
182
    UPnPDeviceDesc ddesc;
186
    UPnPDeviceDesc ddesc;
183
    bool found = UPnPDeviceDirectory::getTheDir()->getDevByFName(fname, ddesc);
187
    bool found = UPnPDeviceDirectory::getTheDir()->getDevByFName(fname, ddesc);
184
    if (!found)
188
    if (!found)
185
        return false;
189
        return false;
186
190
187
    found = false;
191
    found = false;
188
    for (std::vector<UPnPServiceDesc>::const_iterator it = 
192
    for (std::vector<UPnPServiceDesc>::const_iterator it =
189
             ddesc.services.begin(); it != ddesc.services.end(); it++) {
193
                ddesc.services.begin(); it != ddesc.services.end(); it++) {
190
        if (isCDService(it->serviceType)) {
194
        if (isCDService(it->serviceType)) {
191
            server = CDSH(new ContentDirectory(ddesc, *it));
195
            server = CDSH(new ContentDirectory(ddesc, *it));
192
            found = true;
196
            found = true;
193
            break;
197
            break;
194
        }
198
        }
...
...
200
static int asyncReaddirCB(Upnp_EventType et, void *vev, void *cookie)
204
static int asyncReaddirCB(Upnp_EventType et, void *vev, void *cookie)
201
{
205
{
202
    LOGDEB("asyncReaddirCB: " << LibUPnP::evTypeAsString(et) << endl);
206
    LOGDEB("asyncReaddirCB: " << LibUPnP::evTypeAsString(et) << endl);
203
    struct Upnp_Action_Complete *act = (struct Upnp_Action_Complete*)vev;
207
    struct Upnp_Action_Complete *act = (struct Upnp_Action_Complete*)vev;
204
208
205
    LOGDEB("asyncReaddirCB: errcode " << act->ErrCode << 
209
    LOGDEB("asyncReaddirCB: errcode " << act->ErrCode <<
206
           " cturl " <<  UpnpString_get_String(act->CtrlUrl) << 
210
           " cturl " <<  UpnpString_get_String(act->CtrlUrl) <<
207
           " actionrequest " << endl << 
211
           " actionrequest " << endl <<
208
           ixmlwPrintDoc(act->ActionRequest) << endl <<
212
           ixmlwPrintDoc(act->ActionRequest) << endl <<
209
           " actionresult " << ixmlwPrintDoc(act->ActionResult) << endl);
213
           " actionresult " << ixmlwPrintDoc(act->ActionResult) << endl);
210
    return 0;
214
    return 0;
211
}
215
}
212
    int ret = 
216
int ret =
213
        UpnpSendActionAsync(hdl, getActionURL().c_str(), getServiceType().c_str(),
217
    UpnpSendActionAsync(hdl, getActionURL().c_str(), getServiceType().c_str(),
214
        0 /*devUDN*/, request, asyncReaddirCB, 0);
218
                        0 /*devUDN*/, request, asyncReaddirCB, 0);
215
    sleep(10);
219
sleep(10);
216
    return -1;
220
return -1;
217
#endif
221
#endif
218
222
219
void ContentDirectory::evtCallback(const STD_UNORDERED_MAP<string, string>&)
223
void ContentDirectory::evtCallback(const STD_UNORDERED_MAP<string, string>&)
220
{
224
{
221
}
225
}
222
226
223
void ContentDirectory::registerCallback()
227
void ContentDirectory::registerCallback()
224
{
228
{
225
    LOGDEB("ContentDirectory::registerCallback"<< endl);
229
    LOGDEB("ContentDirectory::registerCallback"<< endl);
226
    Service::registerCallback(bind(&ContentDirectory::evtCallback, 
230
    Service::registerCallback(bind(&ContentDirectory::evtCallback,
227
                                   this, _1));
231
                                   this, _1));
228
}
232
}
229
233
230
int ContentDirectory::readDirSlice(const string& objectId, int offset,
234
int ContentDirectory::readDirSlice(const string& objectId, int offset,
231
                                          int count, UPnPDirContent& dirbuf,
235
                                   int count, UPnPDirContent& dirbuf,
232
                                          int *didread, int *total)
236
                                   int *didread, int *total)
233
{
237
{
234
    LOGDEB("CDService::readDirSlice: objId [" << objectId << "] offset " << 
238
    LOGDEB("CDService::readDirSlice: objId [" << objectId << "] offset " <<
235
           offset << " count " << count << endl);
239
           offset << " count " << count << endl);
236
240
237
    // Create request
241
    // Create request
238
    // Some devices require an empty SortCriteria, else bad params
242
    // Some devices require an empty SortCriteria, else bad params
239
    SoapOutgoing args(getServiceType(), "Browse");
243
    SoapOutgoing args(getServiceType(), "Browse");
240
    args("ObjectID", objectId)
244
    args("ObjectID", objectId)
241
        ("BrowseFlag", "BrowseDirectChildren")
245
    ("BrowseFlag", "BrowseDirectChildren")
242
        ("Filter", "*")
246
    ("Filter", "*")
243
        ("SortCriteria", "")
247
    ("SortCriteria", "")
244
        ("StartingIndex", SoapHelp::i2s(offset))
248
    ("StartingIndex", SoapHelp::i2s(offset))
245
        ("RequestedCount", SoapHelp::i2s(count));
249
    ("RequestedCount", SoapHelp::i2s(count));
246
250
247
    SoapIncoming data;
251
    SoapIncoming data;
248
    int ret = runAction(args, data);
252
    int ret = runAction(args, data);
249
    if (ret != UPNP_E_SUCCESS) {
253
    if (ret != UPNP_E_SUCCESS) {
250
        return ret;
254
        return ret;
251
    }
255
    }
252
256
253
    string tbuf;
257
    string tbuf;
254
    if (!data.get("NumberReturned", didread) ||
258
    if (!data.get("NumberReturned", didread) ||
255
        !data.get("TotalMatches", total) ||
259
            !data.get("TotalMatches", total) ||
256
        !data.get("Result", &tbuf)) {
260
            !data.get("Result", &tbuf)) {
257
        LOGERR("CDService::readDir: missing elts in response" << endl);
261
        LOGERR("CDService::readDir: missing elts in response" << endl);
258
        return UPNP_E_BAD_RESPONSE;
262
        return UPNP_E_BAD_RESPONSE;
259
    }
263
    }
260
264
261
    if (*didread <= 0) {
265
    if (*didread <= 0) {
...
...
263
        return UPNP_E_BAD_RESPONSE;
267
        return UPNP_E_BAD_RESPONSE;
264
    }
268
    }
265
269
266
#if 0
270
#if 0
267
    cerr << "CDService::readDirSlice: count " << count <<
271
    cerr << "CDService::readDirSlice: count " << count <<
268
        " offset " << offset <<
272
         " offset " << offset <<
269
        " total " << *total << endl;
273
         " total " << *total << endl;
270
    cerr << " result " << tbuf << endl;
274
    cerr << " result " << tbuf << endl;
271
#endif
275
#endif
272
276
273
    dirbuf.parse(tbuf);
277
    dirbuf.parse(tbuf);
274
278
275
    return UPNP_E_SUCCESS;
279
    return UPNP_E_SUCCESS;
276
}
280
}
277
281
278
int ContentDirectory::readDir(const string& objectId,
282
int ContentDirectory::readDir(const string& objectId,
279
                                     UPnPDirContent& dirbuf)
283
                              UPnPDirContent& dirbuf)
280
{
284
{
281
    LOGDEB("CDService::readDir: url [" << getActionURL() << "] type [" <<
285
    LOGDEB("CDService::readDir: url [" << getActionURL() << "] type [" <<
282
           getServiceType() << "] udn [" << getDeviceId() << "] objId [" <<
286
           getServiceType() << "] udn [" << getDeviceId() << "] objId [" <<
283
           objectId << endl);
287
           objectId << endl);
284
288
...
...
301
int ContentDirectory::searchSlice(const string& objectId,
305
int ContentDirectory::searchSlice(const string& objectId,
302
                                  const string& ss,
306
                                  const string& ss,
303
                                  int offset, int count, UPnPDirContent& dirbuf,
307
                                  int offset, int count, UPnPDirContent& dirbuf,
304
                                  int *didread, int *total)
308
                                  int *didread, int *total)
305
{
309
{
306
    LOGDEB("CDService::searchSlice: objId [" << objectId << "] offset " << 
310
    LOGDEB("CDService::searchSlice: objId [" << objectId << "] offset " <<
307
           offset << " count " << count << endl);
311
           offset << " count " << count << endl);
308
312
309
    // Create request
313
    // Create request
310
    SoapOutgoing args(getServiceType(), "Search");
314
    SoapOutgoing args(getServiceType(), "Search");
311
    args("ContainerID", objectId)
315
    args("ContainerID", objectId)
312
        ("SearchCriteria", ss)
316
    ("SearchCriteria", ss)
313
        ("Filter", "*")
317
    ("Filter", "*")
314
        ("SortCriteria", "")
318
    ("SortCriteria", "")
315
        ("StartingIndex", SoapHelp::i2s(offset))
319
    ("StartingIndex", SoapHelp::i2s(offset))
316
        ("RequestedCount", SoapHelp::i2s(count)); 
320
    ("RequestedCount", SoapHelp::i2s(count));
317
321
318
    SoapIncoming data;
322
    SoapIncoming data;
319
    int ret = runAction(args, data);
323
    int ret = runAction(args, data);
320
324
321
    if (ret != UPNP_E_SUCCESS) {
325
    if (ret != UPNP_E_SUCCESS) {
...
...
324
        return ret;
328
        return ret;
325
    }
329
    }
326
330
327
    string tbuf;
331
    string tbuf;
328
    if (!data.get("NumberReturned", didread) ||
332
    if (!data.get("NumberReturned", didread) ||
329
        !data.get("TotalMatches", total) ||
333
            !data.get("TotalMatches", total) ||
330
        !data.get("Result", &tbuf)) {
334
            !data.get("Result", &tbuf)) {
331
        LOGERR("CDService::search: missing elts in response" << endl);
335
        LOGERR("CDService::search: missing elts in response" << endl);
332
        return UPNP_E_BAD_RESPONSE;
336
        return UPNP_E_BAD_RESPONSE;
333
    }
337
    }
334
    if (*didread <=  0) {
338
    if (*didread <=  0) {
335
        LOGINF("CDService::search: got -1 or 0 entries" << endl);
339
        LOGINF("CDService::search: got -1 or 0 entries" << endl);
...
...
343
347
344
int ContentDirectory::search(const string& objectId,
348
int ContentDirectory::search(const string& objectId,
345
                             const string& ss,
349
                             const string& ss,
346
                             UPnPDirContent& dirbuf)
350
                             UPnPDirContent& dirbuf)
347
{
351
{
348
    LOGDEB("CDService::search: url [" << getActionURL() << "] type [" << 
352
    LOGDEB("CDService::search: url [" << getActionURL() << "] type [" <<
349
           getServiceType() << "] udn [" << getDeviceId() << "] objid [" << 
353
           getServiceType() << "] udn [" << getDeviceId() << "] objid [" <<
350
           objectId <<  "] search [" << ss << "]" << endl);
354
           objectId <<  "] search [" << ss << "]" << endl);
351
355
352
    int offset = 0;
356
    int offset = 0;
353
    int total = 1000;// Updated on first read.
357
    int total = 1000;// Updated on first read.
354
358
...
...
371
375
372
    SoapOutgoing args(getServiceType(), "GetSearchCapabilities");
376
    SoapOutgoing args(getServiceType(), "GetSearchCapabilities");
373
    SoapIncoming data;
377
    SoapIncoming data;
374
    int ret = runAction(args, data);
378
    int ret = runAction(args, data);
375
    if (ret != UPNP_E_SUCCESS) {
379
    if (ret != UPNP_E_SUCCESS) {
376
        LOGINF("CDService::getSearchCapa: UpnpSendAction failed: " << 
380
        LOGINF("CDService::getSearchCapa: UpnpSendAction failed: " <<
377
               UpnpGetErrorMessage(ret) << endl);
381
               UpnpGetErrorMessage(ret) << endl);
378
        return ret;
382
        return ret;
379
    }
383
    }
380
    string tbuf;
384
    string tbuf;
381
    if (!data.get("SearchCaps", &tbuf)) {
385
    if (!data.get("SearchCaps", &tbuf)) {
...
...
395
399
396
    return UPNP_E_SUCCESS;
400
    return UPNP_E_SUCCESS;
397
}
401
}
398
402
399
int ContentDirectory::getMetadata(const string& objectId,
403
int ContentDirectory::getMetadata(const string& objectId,
400
                                         UPnPDirContent& dirbuf)
404
                                  UPnPDirContent& dirbuf)
401
{
405
{
402
    LOGDEB("CDService::getMetadata: url [" << getActionURL() << "] type [" <<
406
    LOGDEB("CDService::getMetadata: url [" << getActionURL() << "] type [" <<
403
           getServiceType() << "] udn [" << getDeviceId() << "] objId [" <<
407
           getServiceType() << "] udn [" << getDeviceId() << "] objId [" <<
404
           objectId << "]" << endl);
408
           objectId << "]" << endl);
405
409
406
    SoapOutgoing args(getServiceType(), "Browse");
410
    SoapOutgoing args(getServiceType(), "Browse");
407
    SoapIncoming data;
411
    SoapIncoming data;
408
    args("ObjectID", objectId)
412
    args("ObjectID", objectId)
409
        ("BrowseFlag", "BrowseMetadata")
413
    ("BrowseFlag", "BrowseMetadata")
410
        ("Filter", "*")
414
    ("Filter", "*")
411
        ("SortCriteria", "")
415
    ("SortCriteria", "")
412
        ("StartingIndex", "0")
416
    ("StartingIndex", "0")
413
        ("RequestedCount", "1");
417
    ("RequestedCount", "1");
414
    int ret = runAction(args, data);
418
    int ret = runAction(args, data);
415
    if (ret != UPNP_E_SUCCESS) {
419
    if (ret != UPNP_E_SUCCESS) {
416
        LOGINF("CDService::getmetadata: UpnpSendAction failed: " << 
420
        LOGINF("CDService::getmetadata: UpnpSendAction failed: " <<
417
               UpnpGetErrorMessage(ret) << endl);
421
               UpnpGetErrorMessage(ret) << endl);
418
        return ret;
422
        return ret;
419
    }
423
    }
420
    string tbuf;
424
    string tbuf;
421
    if (!data.get("Result", &tbuf)) {
425
    if (!data.get("Result", &tbuf)) {