Switch to unified view

a/libupnpp/control/avtransport.cxx b/libupnpp/control/avtransport.cxx
...
...
33
#include "libupnpp/upnpavutils.hxx"     // for upnpdurationtos, etc
33
#include "libupnpp/upnpavutils.hxx"     // for upnpdurationtos, etc
34
#include "libupnpp/upnpp_p.hxx"         // for stringuppercmp, etc
34
#include "libupnpp/upnpp_p.hxx"         // for stringuppercmp, etc
35
35
36
using namespace std;
36
using namespace std;
37
using namespace std::placeholders;
37
using namespace std::placeholders;
38
using namespace UPnPP;
38
39
39
namespace UPnPClient {
40
namespace UPnPClient {
40
41
41
const string AVTransport::SType("urn:schemas-upnp-org:service:AVTransport:1");
42
const string AVTransport::SType("urn:schemas-upnp-org:service:AVTransport:1");
42
43
...
...
123
            LOGERR("AVTransport::evtCallback: bad LastChange value: "
124
            LOGERR("AVTransport::evtCallback: bad LastChange value: "
124
                   << it->second << endl);
125
                   << it->second << endl);
125
            return;
126
            return;
126
        }
127
        }
127
        for (auto it1 = props1.begin(); it1 != props1.end(); it1++) {
128
        for (auto it1 = props1.begin(); it1 != props1.end(); it1++) {
128
            if (!m_reporter) {
129
            if (!getReporter()) {
129
                LOGDEB1("AVTransport::evtCallback: " << it1->first << " -> " 
130
                LOGDEB1("AVTransport::evtCallback: " << it1->first << " -> " 
130
                       << it1->second << endl);
131
                       << it1->second << endl);
131
                continue;
132
                continue;
132
            }
133
            }
133
134
134
            if (!it1->first.compare("TransportState")) {
135
            if (!it1->first.compare("TransportState")) {
135
                m_reporter->changed(it1->first.c_str(), 
136
                getReporter()->changed(it1->first.c_str(), 
136
                                    stringToTpState(it1->second));
137
                                    stringToTpState(it1->second));
137
138
138
            } else if (!it1->first.compare("TransportStatus")) {
139
            } else if (!it1->first.compare("TransportStatus")) {
139
                m_reporter->changed(it1->first.c_str(), 
140
                getReporter()->changed(it1->first.c_str(), 
140
                                    stringToTpStatus(it1->second));
141
                                    stringToTpStatus(it1->second));
141
142
142
            } else if (!it1->first.compare("CurrentPlayMode")) {
143
            } else if (!it1->first.compare("CurrentPlayMode")) {
143
                m_reporter->changed(it1->first.c_str(), 
144
                getReporter()->changed(it1->first.c_str(), 
144
                                    stringToPlayMode(it1->second));
145
                                    stringToPlayMode(it1->second));
145
146
146
            } else if (!it1->first.compare("CurrentTransportActions")) {
147
            } else if (!it1->first.compare("CurrentTransportActions")) {
147
                int iacts;
148
                int iacts;
148
                if (!CTAStringToBits(it1->second, iacts))
149
                if (!CTAStringToBits(it1->second, iacts))
149
                    m_reporter->changed(it1->first.c_str(), iacts);
150
                    getReporter()->changed(it1->first.c_str(), iacts);
150
151
151
            } else if (!it1->first.compare("CurrentTrackURI") ||
152
            } else if (!it1->first.compare("CurrentTrackURI") ||
152
                       !it1->first.compare("AVTransportURI") ||
153
                       !it1->first.compare("AVTransportURI") ||
153
                       !it1->first.compare("NextAVTransportURI")) {
154
                       !it1->first.compare("NextAVTransportURI")) {
154
                m_reporter->changed(it1->first.c_str(), 
155
                getReporter()->changed(it1->first.c_str(), 
155
                                    it1->second.c_str());
156
                                    it1->second.c_str());
156
157
157
            } else if (!it1->first.compare("TransportPlaySpeed") ||
158
            } else if (!it1->first.compare("TransportPlaySpeed") ||
158
                       !it1->first.compare("CurrentTrack") ||
159
                       !it1->first.compare("CurrentTrack") ||
159
                       !it1->first.compare("NumberOfTracks") ||
160
                       !it1->first.compare("NumberOfTracks") ||
160
                       !it1->first.compare("RelativeCounterPosition") ||
161
                       !it1->first.compare("RelativeCounterPosition") ||
161
                       !it1->first.compare("AbsoluteCounterPosition") ||
162
                       !it1->first.compare("AbsoluteCounterPosition") ||
162
                       !it1->first.compare("InstanceID")) {
163
                       !it1->first.compare("InstanceID")) {
163
                m_reporter->changed(it1->first.c_str(),
164
                getReporter()->changed(it1->first.c_str(),
164
                                    atoi(it1->second.c_str()));
165
                                    atoi(it1->second.c_str()));
165
166
166
            } else if (!it1->first.compare("CurrentMediaDuration") ||
167
            } else if (!it1->first.compare("CurrentMediaDuration") ||
167
                       !it1->first.compare("CurrentTrackDuration") ||
168
                       !it1->first.compare("CurrentTrackDuration") ||
168
                       !it1->first.compare("RelativeTimePosition") ||
169
                       !it1->first.compare("RelativeTimePosition") ||
169
                       !it1->first.compare("AbsoluteTimePosition")) {
170
                       !it1->first.compare("AbsoluteTimePosition")) {
170
                m_reporter->changed(it1->first.c_str(),
171
                getReporter()->changed(it1->first.c_str(),
171
                                    upnpdurationtos(it1->second));
172
                                    upnpdurationtos(it1->second));
172
173
173
            } else if (!it1->first.compare("AVTransportURIMetaData") ||
174
            } else if (!it1->first.compare("AVTransportURIMetaData") ||
174
                       !it1->first.compare("NextAVTransportURIMetaData") ||
175
                       !it1->first.compare("NextAVTransportURIMetaData") ||
175
                       !it1->first.compare("CurrentTrackMetaData")) {
176
                       !it1->first.compare("CurrentTrackMetaData")) {
...
...
179
                           it1->second << "]" << endl);
180
                           it1->second << "]" << endl);
180
                } else {
181
                } else {
181
                    LOGDEB1("AVTransport event: good metadata: [" <<
182
                    LOGDEB1("AVTransport event: good metadata: [" <<
182
                            it1->second << "]" << endl);
183
                            it1->second << "]" << endl);
183
                    if (meta.m_items.size() > 0) {
184
                    if (meta.m_items.size() > 0) {
184
                        m_reporter->changed(it1->first.c_str(), 
185
                        getReporter()->changed(it1->first.c_str(), 
185
                                            meta.m_items[0]);
186
                                            meta.m_items[0]);
186
                    }
187
                    }
187
                }
188
                }
188
            } else if (!it1->first.compare("PlaybackStorageMedium") ||
189
            } else if (!it1->first.compare("PlaybackStorageMedium") ||
189
                       !it1->first.compare("PossiblePlaybackStorageMedia") ||
190
                       !it1->first.compare("PossiblePlaybackStorageMedia") ||
190
                       !it1->first.compare("RecordStorageMedium") ||
191
                       !it1->first.compare("RecordStorageMedium") ||
191
                       !it1->first.compare("PossibleRecordStorageMedia") ||
192
                       !it1->first.compare("PossibleRecordStorageMedia") ||
192
                       !it1->first.compare("RecordMediumWriteStatus") ||
193
                       !it1->first.compare("RecordMediumWriteStatus") ||
193
                       !it1->first.compare("CurrentRecordQualityMode") ||
194
                       !it1->first.compare("CurrentRecordQualityMode") ||
194
                       !it1->first.compare("PossibleRecordQualityModes")){
195
                       !it1->first.compare("PossibleRecordQualityModes")){
195
                m_reporter->changed(it1->first.c_str(),it1->second.c_str());
196
                getReporter()->changed(it1->first.c_str(),it1->second.c_str());
196
197
197
            } else {
198
            } else {
198
                LOGDEB1("AVTransport event: unknown variable: name [" <<
199
                LOGDEB1("AVTransport event: unknown variable: name [" <<
199
                        it1->first << "] value [" << it1->second << endl);
200
                        it1->first << "] value [" << it1->second << endl);
200
                m_reporter->changed(it1->first.c_str(),it1->second.c_str());
201
                getReporter()->changed(it1->first.c_str(),it1->second.c_str());
201
            }
202
            }
202
        }
203
        }
203
    }
204
    }
204
}
205
}
205
206
206
207
207
int AVTransport::setURI(const string& uri, const string& metadata,
208
int AVTransport::setURI(const string& uri, const string& metadata,
208
                        int instanceID, bool next)
209
                        int instanceID, bool next)
209
{
210
{
210
    SoapOutgoing args(m_serviceType, next ? "SetNextAVTransportURI" :
211
    SoapOutgoing args(getServiceType(), next ? "SetNextAVTransportURI" :
211
                         "SetAVTransportURI");
212
                         "SetAVTransportURI");
212
    args("InstanceID", SoapHelp::i2s(instanceID))
213
    args("InstanceID", SoapHelp::i2s(instanceID))
213
        (next ? "NextURI" : "CurrentURI", uri)
214
        (next ? "NextURI" : "CurrentURI", uri)
214
        (next ? "NextURIMetaData" : "CurrentURIMetaData", metadata);
215
        (next ? "NextURIMetaData" : "CurrentURIMetaData", metadata);
215
216
...
...
217
    return runAction(args, data);
218
    return runAction(args, data);
218
}
219
}
219
220
220
int AVTransport::setPlayMode(PlayMode pm, int instanceID)
221
int AVTransport::setPlayMode(PlayMode pm, int instanceID)
221
{
222
{
222
    SoapOutgoing args(m_serviceType, "SetPlayMode");
223
    SoapOutgoing args(getServiceType(), "SetPlayMode");
223
    string playmode;
224
    string playmode;
224
    switch (pm) {
225
    switch (pm) {
225
    case PM_Normal: playmode = "NORMAL"; break;
226
    case PM_Normal: playmode = "NORMAL"; break;
226
    case PM_Shuffle: playmode = "SHUFFLE"; break;
227
    case PM_Shuffle: playmode = "SHUFFLE"; break;
227
    case PM_RepeatOne: playmode = "REPEAT_ONE"; break;
228
    case PM_RepeatOne: playmode = "REPEAT_ONE"; break;
...
...
238
    return runAction(args, data);
239
    return runAction(args, data);
239
}
240
}
240
241
241
int AVTransport::getMediaInfo(MediaInfo& info, int instanceID)
242
int AVTransport::getMediaInfo(MediaInfo& info, int instanceID)
242
{
243
{
243
    SoapOutgoing args(m_serviceType, "GetMediaInfo");
244
    SoapOutgoing args(getServiceType(), "GetMediaInfo");
244
    args("InstanceID", SoapHelp::i2s(instanceID));
245
    args("InstanceID", SoapHelp::i2s(instanceID));
245
    SoapIncoming data;
246
    SoapIncoming data;
246
    int ret = runAction(args, data);
247
    int ret = runAction(args, data);
247
    if (ret != UPNP_E_SUCCESS) {
248
    if (ret != UPNP_E_SUCCESS) {
248
        return ret;
249
        return ret;
249
    }
250
    }
250
    string s;
251
    string s;
251
    data.getInt("NrTracks", &info.nrtracks);
252
    data.get("NrTracks", &info.nrtracks);
252
    data.getString("MediaDuration", &s);
253
    data.get("MediaDuration", &s);
253
    info.mduration = upnpdurationtos(s);
254
    info.mduration = upnpdurationtos(s);
254
    data.getString("CurrentURI", &info.cururi);
255
    data.get("CurrentURI", &info.cururi);
255
    data.getString("CurrentURIMetaData", &s);
256
    data.get("CurrentURIMetaData", &s);
256
    UPnPDirContent meta;
257
    UPnPDirContent meta;
257
    meta.parse(s);
258
    meta.parse(s);
258
    if (meta.m_items.size() > 0)
259
    if (meta.m_items.size() > 0)
259
        info.curmeta = meta.m_items[0];
260
        info.curmeta = meta.m_items[0];
260
    meta.clear();
261
    meta.clear();
261
    data.getString("NextURI", &info.nexturi);
262
    data.get("NextURI", &info.nexturi);
262
    data.getString("NextURIMetaData", &s);
263
    data.get("NextURIMetaData", &s);
263
    if (meta.m_items.size() > 0)
264
    if (meta.m_items.size() > 0)
264
        info.nextmeta = meta.m_items[0];
265
        info.nextmeta = meta.m_items[0];
265
    data.getString("PlayMedium", &info.pbstoragemed);
266
    data.get("PlayMedium", &info.pbstoragemed);
266
    data.getString("RecordMedium", &info.pbstoragemed);
267
    data.get("RecordMedium", &info.pbstoragemed);
267
    data.getString("WriteStatus", &info.ws);
268
    data.get("WriteStatus", &info.ws);
268
    return 0;
269
    return 0;
269
}
270
}
270
271
271
int AVTransport::getTransportInfo(TransportInfo& info, int instanceID)
272
int AVTransport::getTransportInfo(TransportInfo& info, int instanceID)
272
{
273
{
273
    SoapOutgoing args(m_serviceType, "GetTransportInfo");
274
    SoapOutgoing args(getServiceType(), "GetTransportInfo");
274
    args("InstanceID", SoapHelp::i2s(instanceID));
275
    args("InstanceID", SoapHelp::i2s(instanceID));
275
    SoapIncoming data;
276
    SoapIncoming data;
276
    int ret = runAction(args, data);
277
    int ret = runAction(args, data);
277
    if (ret != UPNP_E_SUCCESS) {
278
    if (ret != UPNP_E_SUCCESS) {
278
        return ret;
279
        return ret;
279
    }
280
    }
280
    string s;
281
    string s;
281
    data.getString("CurrentTransportState", &s);
282
    data.get("CurrentTransportState", &s);
282
    info.tpstate = stringToTpState(s);
283
    info.tpstate = stringToTpState(s);
283
    data.getString("CurrentTransportStatus", &s);
284
    data.get("CurrentTransportStatus", &s);
284
    info.tpstatus = stringToTpStatus(s);
285
    info.tpstatus = stringToTpStatus(s);
285
    data.getInt("CurrentSpeed", &info.curspeed);
286
    data.get("CurrentSpeed", &info.curspeed);
286
    return 0;
287
    return 0;
287
}
288
}
288
289
289
int AVTransport::getPositionInfo(PositionInfo& info, int instanceID)
290
int AVTransport::getPositionInfo(PositionInfo& info, int instanceID)
290
{
291
{
291
    SoapOutgoing args(m_serviceType, "GetPositionInfo");
292
    SoapOutgoing args(getServiceType(), "GetPositionInfo");
292
    args("InstanceID", SoapHelp::i2s(instanceID));
293
    args("InstanceID", SoapHelp::i2s(instanceID));
293
    SoapIncoming data;
294
    SoapIncoming data;
294
    int ret = runAction(args, data);
295
    int ret = runAction(args, data);
295
    if (ret != UPNP_E_SUCCESS) {
296
    if (ret != UPNP_E_SUCCESS) {
296
        return ret;
297
        return ret;
297
    }
298
    }
298
    string s;
299
    string s;
299
    data.getInt("Track", &info.track);
300
    data.get("Track", &info.track);
300
    data.getString("TrackDuration", &s);
301
    data.get("TrackDuration", &s);
301
    info.trackduration = upnpdurationtos(s);
302
    info.trackduration = upnpdurationtos(s);
302
    data.getString("TrackMetaData", &s);
303
    data.get("TrackMetaData", &s);
303
    UPnPDirContent meta;
304
    UPnPDirContent meta;
304
    meta.parse(s);
305
    meta.parse(s);
305
    if (meta.m_items.size() > 0) {
306
    if (meta.m_items.size() > 0) {
306
        info.trackmeta = meta.m_items[0];
307
        info.trackmeta = meta.m_items[0];
307
        LOGDEB1("AVTransport::getPositionInfo: size " << 
308
        LOGDEB1("AVTransport::getPositionInfo: size " << 
308
               meta.m_items.size() << " current title: " 
309
               meta.m_items.size() << " current title: " 
309
               << meta.m_items[0].m_title << endl);
310
               << meta.m_items[0].m_title << endl);
310
    }
311
    }
311
    data.getString("TrackURI", &info.trackuri);
312
    data.get("TrackURI", &info.trackuri);
312
    data.getString("RelTime", &s);
313
    data.get("RelTime", &s);
313
    info.reltime = upnpdurationtos(s);
314
    info.reltime = upnpdurationtos(s);
314
    data.getString("AbsTime", &s);
315
    data.get("AbsTime", &s);
315
    info.abstime = upnpdurationtos(s);
316
    info.abstime = upnpdurationtos(s);
316
    data.getInt("RelCount", &info.relcount);
317
    data.get("RelCount", &info.relcount);
317
    data.getInt("AbsCount", &info.abscount);
318
    data.get("AbsCount", &info.abscount);
318
    return 0;
319
    return 0;
319
}
320
}
320
321
321
int AVTransport::getDeviceCapabilities(DeviceCapabilities& info, int iID)
322
int AVTransport::getDeviceCapabilities(DeviceCapabilities& info, int iID)
322
{
323
{
323
    SoapOutgoing args(m_serviceType, "GetDeviceCapabilities");
324
    SoapOutgoing args(getServiceType(), "GetDeviceCapabilities");
324
    args("InstanceID", SoapHelp::i2s(iID));
325
    args("InstanceID", SoapHelp::i2s(iID));
325
    SoapIncoming data;
326
    SoapIncoming data;
326
    int ret = runAction(args, data);
327
    int ret = runAction(args, data);
327
    if (ret != UPNP_E_SUCCESS) {
328
    if (ret != UPNP_E_SUCCESS) {
328
        return ret;
329
        return ret;
329
    }
330
    }
330
    data.getString("PlayMedia", &info.playmedia);
331
    data.get("PlayMedia", &info.playmedia);
331
    data.getString("RecMedia", &info.recmedia);
332
    data.get("RecMedia", &info.recmedia);
332
    data.getString("RecQualityModes", &info.recqualitymodes);
333
    data.get("RecQualityModes", &info.recqualitymodes);
333
    return 0;
334
    return 0;
334
}
335
}
335
336
336
int AVTransport::getTransportSettings(TransportSettings& info, int instanceID)
337
int AVTransport::getTransportSettings(TransportSettings& info, int instanceID)
337
{
338
{
338
    SoapOutgoing args(m_serviceType, "GetTransportSettings");
339
    SoapOutgoing args(getServiceType(), "GetTransportSettings");
339
    args("InstanceID", SoapHelp::i2s(instanceID));
340
    args("InstanceID", SoapHelp::i2s(instanceID));
340
    SoapIncoming data;
341
    SoapIncoming data;
341
    int ret = runAction(args, data);
342
    int ret = runAction(args, data);
342
    if (ret != UPNP_E_SUCCESS) {
343
    if (ret != UPNP_E_SUCCESS) {
343
        return ret;
344
        return ret;
344
    }
345
    }
345
    string s;
346
    string s;
346
    data.getString("PlayMedia", &s);
347
    data.get("PlayMedia", &s);
347
    info.playmode = stringToPlayMode(s);
348
    info.playmode = stringToPlayMode(s);
348
    data.getString("RecQualityMode", &info.recqualitymode);
349
    data.get("RecQualityMode", &info.recqualitymode);
349
    return 0;
350
    return 0;
350
}
351
}
351
352
352
int AVTransport::getCurrentTransportActions(int& iacts, int iID)
353
int AVTransport::getCurrentTransportActions(int& iacts, int iID)
353
{
354
{
354
    SoapOutgoing args(m_serviceType, "GetCurrentTransportActions");
355
    SoapOutgoing args(getServiceType(), "GetCurrentTransportActions");
355
    args("InstanceID", SoapHelp::i2s(iID));
356
    args("InstanceID", SoapHelp::i2s(iID));
356
    SoapIncoming data;
357
    SoapIncoming data;
357
    int ret = runAction(args, data);
358
    int ret = runAction(args, data);
358
    if (ret != UPNP_E_SUCCESS) {
359
    if (ret != UPNP_E_SUCCESS) {
359
        return ret;
360
        return ret;
360
    }
361
    }
361
    string actions;
362
    string actions;
362
    if (!data.getString("Actions", &actions)) {
363
    if (!data.get("Actions", &actions)) {
363
        LOGERR("AVTransport:getCurrentTransportActions: no actions in answer"
364
        LOGERR("AVTransport:getCurrentTransportActions: no actions in answer"
364
               << endl);
365
               << endl);
365
        return UPNP_E_BAD_RESPONSE;
366
        return UPNP_E_BAD_RESPONSE;
366
    }
367
    }
367
    return CTAStringToBits(actions, iacts);
368
    return CTAStringToBits(actions, iacts);
...
...
400
    return 0;
401
    return 0;
401
}
402
}
402
403
403
int AVTransport::stop(int instanceID)
404
int AVTransport::stop(int instanceID)
404
{
405
{
405
    SoapOutgoing args(m_serviceType, "Stop");
406
    SoapOutgoing args(getServiceType(), "Stop");
406
    args("InstanceID", SoapHelp::i2s(instanceID));
407
    args("InstanceID", SoapHelp::i2s(instanceID));
407
    SoapIncoming data;
408
    SoapIncoming data;
408
    return runAction(args, data);
409
    return runAction(args, data);
409
}
410
}
410
411
411
int AVTransport::pause(int instanceID)
412
int AVTransport::pause(int instanceID)
412
{
413
{
413
    SoapOutgoing args(m_serviceType, "Pause");
414
    SoapOutgoing args(getServiceType(), "Pause");
414
    args("InstanceID", SoapHelp::i2s(instanceID));
415
    args("InstanceID", SoapHelp::i2s(instanceID));
415
    SoapIncoming data;
416
    SoapIncoming data;
416
    return runAction(args, data);
417
    return runAction(args, data);
417
}
418
}
418
419
419
int AVTransport::play(int speed, int instanceID)
420
int AVTransport::play(int speed, int instanceID)
420
{
421
{
421
    SoapOutgoing args(m_serviceType, "Play");
422
    SoapOutgoing args(getServiceType(), "Play");
422
    args("InstanceID", SoapHelp::i2s(instanceID))
423
    args("InstanceID", SoapHelp::i2s(instanceID))
423
        ("Speed", SoapHelp::i2s(speed));
424
        ("Speed", SoapHelp::i2s(speed));
424
    SoapIncoming data;
425
    SoapIncoming data;
425
    return runAction(args, data);
426
    return runAction(args, data);
426
}
427
}
...
...
440
    case SEEK_FRAME: sm = "FRAME"; break;
441
    case SEEK_FRAME: sm = "FRAME"; break;
441
    default:
442
    default:
442
        return UPNP_E_INVALID_PARAM;
443
        return UPNP_E_INVALID_PARAM;
443
    }
444
    }
444
445
445
    SoapOutgoing args(m_serviceType, "Seek");
446
    SoapOutgoing args(getServiceType(), "Seek");
446
    args("InstanceID", SoapHelp::i2s(instanceID))
447
    args("InstanceID", SoapHelp::i2s(instanceID))
447
        ("Unit", sm)
448
        ("Unit", sm)
448
        ("Target", value);
449
        ("Target", value);
449
    SoapIncoming data;
450
    SoapIncoming data;
450
    return runAction(args, data);
451
    return runAction(args, data);
451
}
452
}
452
453
453
int AVTransport::next(int instanceID)
454
int AVTransport::next(int instanceID)
454
{
455
{
455
    SoapOutgoing args(m_serviceType, "Next");
456
    SoapOutgoing args(getServiceType(), "Next");
456
    args("InstanceID", SoapHelp::i2s(instanceID));
457
    args("InstanceID", SoapHelp::i2s(instanceID));
457
    SoapIncoming data;
458
    SoapIncoming data;
458
    return runAction(args, data);
459
    return runAction(args, data);
459
}
460
}
460
461
461
int AVTransport::previous(int instanceID)
462
int AVTransport::previous(int instanceID)
462
{
463
{
463
    SoapOutgoing args(m_serviceType, "Previous");
464
    SoapOutgoing args(getServiceType(), "Previous");
464
    args("InstanceID", SoapHelp::i2s(instanceID));
465
    args("InstanceID", SoapHelp::i2s(instanceID));
465
    SoapIncoming data;
466
    SoapIncoming data;
466
    return runAction(args, data);
467
    return runAction(args, data);
467
}
468
}
468
469