Switch to unified view

a/upmpd/ohplaylist.cxx b/upmpd/ohplaylist.cxx
...
...
105
{
105
{
106
    char cbuf[30];
106
    char cbuf[30];
107
    sprintf(cbuf, "%d", val);
107
    sprintf(cbuf, "%d", val);
108
    return string(cbuf);
108
    return string(cbuf);
109
}
109
}
110
110
static string mpdstatusToTransportState(MpdStatus::State st)
111
static string mpdstatusToTransportState(MpdStatus::State st)
111
{
112
{
112
    string tstate;
113
    string tstate;
113
    switch(st) {
114
    switch(st) {
114
    case MpdStatus::MPDS_PLAY: 
115
    case MpdStatus::MPDS_PLAY: 
...
...
123
    return tstate;
124
    return tstate;
124
}
125
}
125
126
126
// The data format for id lists is an array of msb 32b its ints
127
// The data format for id lists is an array of msb 32b its ints
127
// encoded in base64...
128
// encoded in base64...
128
static string makeIdArray(const vector<unsigned int>& in)
129
static string translateIdArray(const vector<unsigned int>& in)
129
{
130
{
130
    string out1;
131
    string out1;
131
    for (vector<unsigned int>::const_iterator it = in.begin(); 
132
    for (vector<unsigned int>::const_iterator it = in.begin(); 
132
         it != in.end(); it++) {
133
         it != in.end(); it++) {
133
        out1 += (unsigned char) (((*it) & 0xff000000) >> 24);
134
        out1 += (unsigned char) (((*it) & 0xff000000) >> 24);
...
...
136
        out1 += (unsigned char) (  (*it) & 0x000000ff);
137
        out1 += (unsigned char) (  (*it) & 0x000000ff);
137
    }
138
    }
138
    return base64_encode(out1);
139
    return base64_encode(out1);
139
}
140
}
140
141
142
string OHPlaylist::makeIdArray()
143
{
144
    string out;
145
    vector<unsigned int> vids;
146
    bool ok = m_dev->m_mpdcli->getQueueIds(vids);
147
    if (ok) {
148
        out = translateIdArray(vids);
149
    }
150
    return out;
151
}
141
152
142
bool OHPlaylist::makestate(unordered_map<string, string> &st)
153
bool OHPlaylist::makestate(unordered_map<string, string> &st)
143
{
154
{
144
    st.clear();
155
    st.clear();
145
156
...
...
148
    st["TracksMax"] = makesint(tracksmax);
159
    st["TracksMax"] = makesint(tracksmax);
149
    st["ProtocolInfo"] = upmpdProtocolInfo;
160
    st["ProtocolInfo"] = upmpdProtocolInfo;
150
    
161
    
151
    st["Id"] = makesint(mpds.songid);
162
    st["Id"] = makesint(mpds.songid);
152
163
153
    st["IdArray"] = "";
164
    st["IdArray"] = makeIdArray();
154
165
155
    st["Repeat"] = makesint(mpds.rept);
166
    st["Repeat"] = makesint(mpds.rept);
156
    st["Shuffle"] = makesint(mpds.random);
167
    st["Shuffle"] = makesint(mpds.random);
157
    st["TransportState"] =  mpdstatusToTransportState(mpds.state);
168
    st["TransportState"] =  mpdstatusToTransportState(mpds.state);
158
169
...
...
182
    }
193
    }
183
194
184
    return true;
195
    return true;
185
}
196
}
186
197
198
void OHPlaylist::maybeWakeUp(bool ok)
199
{
200
    if (ok && m_dev)
201
        m_dev->loopWakeup();
202
}
203
187
int OHPlaylist::play(const SoapArgs& sc, SoapData& data)
204
int OHPlaylist::play(const SoapArgs& sc, SoapData& data)
188
{
205
{
189
    LOGDEB("OHPlaylist::play" << endl);
206
    LOGDEB("OHPlaylist::play" << endl);
190
    bool ok = m_dev->m_mpdcli->play();
207
    bool ok = m_dev->m_mpdcli->play();
191
    m_dev->loopWakeup();
208
    maybeWakeUp(ok);
192
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
209
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
193
}
210
}
194
211
195
int OHPlaylist::pause(const SoapArgs& sc, SoapData& data)
212
int OHPlaylist::pause(const SoapArgs& sc, SoapData& data)
196
{
213
{
197
    LOGDEB("OHPlaylist::pause" << endl);
214
    LOGDEB("OHPlaylist::pause" << endl);
198
    bool ok = m_dev->m_mpdcli->pause(true);
215
    bool ok = m_dev->m_mpdcli->pause(true);
199
#warning check that using play to disable pause as oh does does not restart from bot
216
#warning check that using play to disable pause as oh does does not restart from bot
217
    maybeWakeUp(ok);
200
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
218
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
201
}
219
}
202
220
203
int OHPlaylist::stop(const SoapArgs& sc, SoapData& data)
221
int OHPlaylist::stop(const SoapArgs& sc, SoapData& data)
204
{
222
{
205
    LOGDEB("OHPlaylist::stop" << endl);
223
    LOGDEB("OHPlaylist::stop" << endl);
206
    bool ok = m_dev->m_mpdcli->stop();
224
    bool ok = m_dev->m_mpdcli->stop();
225
    maybeWakeUp(ok);
207
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
226
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
208
}
227
}
209
228
210
int OHPlaylist::next(const SoapArgs& sc, SoapData& data)
229
int OHPlaylist::next(const SoapArgs& sc, SoapData& data)
211
{
230
{
212
    LOGDEB("OHPlaylist::next" << endl);
231
    LOGDEB("OHPlaylist::next" << endl);
213
    bool ok = m_dev->m_mpdcli->next();
232
    bool ok = m_dev->m_mpdcli->next();
233
    maybeWakeUp(ok);
214
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
234
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
215
}
235
}
216
236
217
int OHPlaylist::previous(const SoapArgs& sc, SoapData& data)
237
int OHPlaylist::previous(const SoapArgs& sc, SoapData& data)
218
{
238
{
219
    LOGDEB("OHPlaylist::previous" << endl);
239
    LOGDEB("OHPlaylist::previous" << endl);
220
    bool ok = m_dev->m_mpdcli->previous();
240
    bool ok = m_dev->m_mpdcli->previous();
241
    maybeWakeUp(ok);
221
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
242
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
222
}
243
}
223
244
224
int OHPlaylist::setRepeat(const SoapArgs& sc, SoapData& data)
245
int OHPlaylist::setRepeat(const SoapArgs& sc, SoapData& data)
225
{
246
{
226
    LOGDEB("OHPlaylist::setRepeat" << endl);
247
    LOGDEB("OHPlaylist::setRepeat" << endl);
227
    bool onoff;
248
    bool onoff;
228
    bool ok = sc.getBool("Value", &onoff);
249
    bool ok = sc.getBool("Value", &onoff);
229
    if (ok) {
250
    if (ok) {
230
        ok = m_dev->m_mpdcli->repeat(onoff);
251
        ok = m_dev->m_mpdcli->repeat(onoff);
252
        maybeWakeUp(ok);
231
    }
253
    }
232
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
254
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
233
}
255
}
234
256
235
int OHPlaylist::repeat(const SoapArgs& sc, SoapData& data)
257
int OHPlaylist::repeat(const SoapArgs& sc, SoapData& data)
...
...
247
    bool ok = sc.getBool("Value", &onoff);
269
    bool ok = sc.getBool("Value", &onoff);
248
    if (ok) {
270
    if (ok) {
249
        // Note that mpd shuffle shuffles the playlist, which is different
271
        // Note that mpd shuffle shuffles the playlist, which is different
250
        // from playing at random
272
        // from playing at random
251
        ok = m_dev->m_mpdcli->random(onoff);
273
        ok = m_dev->m_mpdcli->random(onoff);
274
        maybeWakeUp(ok);
252
    }
275
    }
253
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
276
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
254
}
277
}
255
278
256
int OHPlaylist::shuffle(const SoapArgs& sc, SoapData& data)
279
int OHPlaylist::shuffle(const SoapArgs& sc, SoapData& data)
...
...
266
    LOGDEB("OHPlaylist::seekSecondAbsolute" << endl);
289
    LOGDEB("OHPlaylist::seekSecondAbsolute" << endl);
267
    int seconds;
290
    int seconds;
268
    bool ok = sc.getInt("Value", &seconds);
291
    bool ok = sc.getInt("Value", &seconds);
269
    if (ok) {
292
    if (ok) {
270
        ok = m_dev->m_mpdcli->seek(seconds);
293
        ok = m_dev->m_mpdcli->seek(seconds);
294
        maybeWakeUp(ok);
271
    }
295
    }
272
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
296
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
273
}
297
}
274
298
275
int OHPlaylist::seekSecondRelative(const SoapArgs& sc, SoapData& data)
299
int OHPlaylist::seekSecondRelative(const SoapArgs& sc, SoapData& data)
...
...
285
            seconds += mpds.songelapsedms / 1000;
309
            seconds += mpds.songelapsedms / 1000;
286
            ok = m_dev->m_mpdcli->seek(seconds);
310
            ok = m_dev->m_mpdcli->seek(seconds);
287
        } else {
311
        } else {
288
            ok = false;
312
            ok = false;
289
        }
313
        }
314
        maybeWakeUp(ok);
290
    }
315
    }
291
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
316
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
292
}
317
}
293
318
294
int OHPlaylist::transportState(const SoapArgs& sc, SoapData& data)
319
int OHPlaylist::transportState(const SoapArgs& sc, SoapData& data)
...
...
316
    LOGDEB("OHPlaylist::seekId" << endl);
341
    LOGDEB("OHPlaylist::seekId" << endl);
317
    int id;
342
    int id;
318
    bool ok = sc.getInt("Value", &id);
343
    bool ok = sc.getInt("Value", &id);
319
    if (ok) {
344
    if (ok) {
320
        ok = m_dev->m_mpdcli->playId(id);
345
        ok = m_dev->m_mpdcli->playId(id);
346
        maybeWakeUp(ok);
321
    }
347
    }
322
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
348
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
323
}
349
}
324
350
325
// Skip to track with specified index 
351
// Skip to track with specified index 
...
...
328
    LOGDEB("OHPlaylist::seekIndex" << endl);
354
    LOGDEB("OHPlaylist::seekIndex" << endl);
329
    int pos;
355
    int pos;
330
    bool ok = sc.getInt("Value", &pos);
356
    bool ok = sc.getInt("Value", &pos);
331
    if (ok) {
357
    if (ok) {
332
        ok = m_dev->m_mpdcli->play(pos);
358
        ok = m_dev->m_mpdcli->play(pos);
359
        maybeWakeUp(ok);
333
    }
360
    }
334
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
361
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
335
}
362
}
336
363
337
// Return current Id
364
// Return current Id
...
...
348
int OHPlaylist::ohread(const SoapArgs& sc, SoapData& data)
375
int OHPlaylist::ohread(const SoapArgs& sc, SoapData& data)
349
{
376
{
350
    LOGDEB("OHPlaylist::ohread" << endl);
377
    LOGDEB("OHPlaylist::ohread" << endl);
351
    int id;
378
    int id;
352
    bool ok = sc.getInt("Value", &id);
379
    bool ok = sc.getInt("Value", &id);
353
    unordered_map<string, string> props;
380
    UpSong song;
354
    if (ok) {
381
    if (ok) {
355
        ok = m_dev->m_mpdcli->statSong(props, id, true);
382
        ok = m_dev->m_mpdcli->statSong(song, id, true);
356
    }
383
    }
357
    if (ok) {
384
    if (ok) {
358
        data.addarg("Uri", props["uri"]);
385
        data.addarg("Uri", song.uri);
359
        string metadata; // = didlmake(mpds);
386
        string metadata = didlmake(song);
360
        data.addarg("Metadata", metadata);
387
        data.addarg("Metadata", metadata);
361
    }
388
    }
362
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
389
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
363
}
390
}
364
391
...
...
375
//
402
//
376
// Any ids not in the playlist are ignored. 
403
// Any ids not in the playlist are ignored. 
377
int OHPlaylist::readlist(const SoapArgs& sc, SoapData& data)
404
int OHPlaylist::readlist(const SoapArgs& sc, SoapData& data)
378
{
405
{
379
    LOGDEB("OHPlaylist::readlist" << endl);
406
    LOGDEB("OHPlaylist::readlist" << endl);
380
    bool ok = false;
407
    string sids;
408
    bool ok = sc.getString("IdList", &sids);
409
    vector<string> ids;
410
    string out("<TrackList>");
411
    if (ok) {
412
        stringToTokens(sids, ids);
413
        for (vector<string>::iterator it = ids.begin(); it != ids.end(); it++) {
414
            int id = atoi(it->c_str());
415
            UpSong song;
416
            if (!m_dev->m_mpdcli->statSong(song, id, true))
417
                continue;
418
            out += "<Entry><Id>";
419
            out += it->c_str();
420
            out += "</Id><Metadata>";
421
            out += didlmake(song);
422
            out += "</Metadata></Entry>";
423
        }
424
        out += "</Tracklist>";
425
        data.addarg("TrackList", out);
426
    }
381
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
427
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
382
}
428
}
383
429
384
// Adds the given uri and metadata as a new track to the playlist. 
430
// Adds the given uri and metadata as a new track to the playlist. 
385
// Set the AfterId argument to 0 to insert a track at the start of the
431
// Set the AfterId argument to 0 to insert a track at the start of the
...
...
393
    LOGDEB("OHPlaylist::insert" << endl);
439
    LOGDEB("OHPlaylist::insert" << endl);
394
    int afterid;
440
    int afterid;
395
    string uri, metadata;
441
    string uri, metadata;
396
    bool ok = sc.getInt("AfterId", &afterid);
442
    bool ok = sc.getInt("AfterId", &afterid);
397
    ok = ok && sc.getString("Uri", &uri);
443
    ok = ok && sc.getString("Uri", &uri);
444
    if (ok)
398
    ok = ok && sc.getString("Metadata", &metadata);
445
        ok = ok && sc.getString("Metadata", &metadata);
399
446
400
    LOGDEB("OHPlaylist::insert: afterid " << afterid << " Uri " <<
447
    LOGDEB("OHPlaylist::insert: afterid " << afterid << " Uri " <<
401
           uri << " Metadata " << metadata << endl);
448
           uri << " Metadata " << metadata << endl);
449
    if (ok)
450
        ok = m_dev->m_mpdcli->insertAfterId(uri, afterid);
451
    maybeWakeUp(ok);
402
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
452
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
403
}
453
}
404
454
405
int OHPlaylist::deleteId(const SoapArgs& sc, SoapData& data)
455
int OHPlaylist::deleteId(const SoapArgs& sc, SoapData& data)
406
{
456
{
407
    LOGDEB("OHPlaylist::deleteId" << endl);
457
    LOGDEB("OHPlaylist::deleteId" << endl);
408
    int id;
458
    int id;
409
    bool ok = sc.getInt("Value", &id);
459
    bool ok = sc.getInt("Value", &id);
410
    if (ok) {
460
    if (ok) {
411
        ok = m_dev->m_mpdcli->deleteId(id);
461
        ok = m_dev->m_mpdcli->deleteId(id);
462
        maybeWakeUp(ok);
412
    }
463
    }
413
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
464
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
414
}
465
}
415
466
416
int OHPlaylist::deleteAll(const SoapArgs& sc, SoapData& data)
467
int OHPlaylist::deleteAll(const SoapArgs& sc, SoapData& data)
417
{
468
{
418
    LOGDEB("OHPlaylist::deleteAll" << endl);
469
    LOGDEB("OHPlaylist::deleteAll" << endl);
419
    bool ok = m_dev->m_mpdcli->clearQueue();
470
    bool ok = m_dev->m_mpdcli->clearQueue();
471
    maybeWakeUp(ok);
420
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
472
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
421
}
473
}
422
474
423
int OHPlaylist::tracksMax(const SoapArgs& sc, SoapData& data)
475
int OHPlaylist::tracksMax(const SoapArgs& sc, SoapData& data)
424
{
476
{
...
...
430
// Returns current list of id as array of big endian 32bits integers,
482
// Returns current list of id as array of big endian 32bits integers,
431
// base-64-encoded. 
483
// base-64-encoded. 
432
int OHPlaylist::idArray(const SoapArgs& sc, SoapData& data)
484
int OHPlaylist::idArray(const SoapArgs& sc, SoapData& data)
433
{
485
{
434
    LOGDEB("OHPlaylist::idArray" << endl);
486
    LOGDEB("OHPlaylist::idArray" << endl);
435
    bool ok = false;
436
437
    data.addarg("Token", "0");
487
    data.addarg("Token", "0");
438
    data.addarg("Array", "");
488
    data.addarg("Array", makeIdArray());
439
489
    return UPNP_E_SUCCESS;
440
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
441
}
490
}
442
491
443
// Check if id array changed since last call (which returned a gen token)
492
// Check if id array changed since last call (which returned a gen token)
444
int OHPlaylist::idArrayChanged(const SoapArgs& sc, SoapData& data)
493
int OHPlaylist::idArrayChanged(const SoapArgs& sc, SoapData& data)
445
{
494
{
446
    LOGDEB("OHPlaylist::idArrayChanged" << endl);
495
    LOGDEB("OHPlaylist::idArrayChanged" << endl);
447
    bool ok = false;
496
    bool ok = false;
448
497
449
    data.addarg("Token", "0");
498
    data.addarg("Token", "0");
450
    // Bool indicating if array changed
499
    // Bool indicating if array changed
451
    data.addarg("Value", "");
500
    data.addarg("Value", "0");
452
501
453
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
502
    return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
454
}
503
}
455
504
456
int OHPlaylist::protocolInfo(const SoapArgs& sc, SoapData& data)
505
int OHPlaylist::protocolInfo(const SoapArgs& sc, SoapData& data)