Switch to unified view

a/libupnpp/control/ohplaylist.cxx b/libupnpp/control/ohplaylist.cxx
...
...
12
 *       You should have received a copy of the GNU General Public License
12
 *       You should have received a copy of the GNU General Public License
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 <arpa/inet.h>
17
18
18
#include <string>
19
#include <string>
19
#include <vector>
20
#include <vector>
20
21
21
using namespace std;
22
using namespace std;
22
23
23
#include <upnp/upnp.h>
24
#include <upnp/upnp.h>
24
25
26
#include "libupnpp/base64.hxx"
25
#include "libupnpp/soaphelp.hxx"
27
#include "libupnpp/soaphelp.hxx"
26
#include "libupnpp/upnpp_p.hxx"
28
#include "libupnpp/upnpp_p.hxx"
27
#include "libupnpp/log.hxx"
29
#include "libupnpp/log.hxx"
28
#include "libupnpp/expatmm.hxx"
30
#include "libupnpp/expatmm.hxx"
29
#include "libupnpp/control/ohplaylist.hxx"
31
#include "libupnpp/control/ohplaylist.hxx"
...
...
38
{
40
{
39
    const string::size_type sz(SType.size()-2);
41
    const string::size_type sz(SType.size()-2);
40
    return !SType.compare(0, sz, st, 0, sz);
42
    return !SType.compare(0, sz, st, 0, sz);
41
}
43
}
42
44
45
46
int OHPlaylist::play()
47
{
48
    return runTrivialAction("Play");
49
}
50
int OHPlaylist::pause()
51
{
52
    return runTrivialAction("Pause");
53
}
54
int OHPlaylist::stop()
55
{
56
    return runTrivialAction("Stop");
57
}
58
int OHPlaylist::next()
59
{
60
    return runTrivialAction("Next");
61
}
62
int OHPlaylist::previous()
63
{
64
    return runTrivialAction("Previous");
65
}
66
int OHPlaylist::setRepeat(bool onoff)
67
{
68
    return runSimpleAction("SetRepeat", "Value", onoff);
69
}
70
int OHPlaylist::repeat(bool *on)
71
{
72
    return runSimpleGet("Repeat", "Value", on);
73
}
74
int OHPlaylist::setShuffle(bool onoff)
75
{
76
    return runSimpleAction("SetShuffle", "Value", onoff);
77
}
78
int OHPlaylist::shuffle(bool *on)
79
{
80
    return runSimpleGet("Shuffle", "Value", on);
81
}
82
int OHPlaylist::seekSecondAbsolute(int value)
83
{
84
    return runSimpleAction("SeekSecondAbsolute", "Value", value);
85
}
86
int OHPlaylist::seekSecondRelative(int value)
87
{
88
    return runSimpleAction("SeekSecondRelative", "Value", value);
89
}
90
int OHPlaylist::seekId(int value)
91
{
92
    return runSimpleAction("SeekId", "Value", value);
93
}
94
int OHPlaylist::seekIndex(int value)
95
{
96
    return runSimpleAction("SeekIndex", "Value", value);
97
}
98
99
int OHPlaylist::transportState(TPState* tpp)
100
{
101
    std::string value;
102
    int ret;
103
104
    if ((ret = runSimpleGet("TransportState", "Value", &value)))
105
        return ret;
106
    if (!value.compare("Buffering")) {
107
        *tpp = TPS_Buffering;
108
        return 0;
109
    } else if (!value.compare("Paused")) {
110
        *tpp = TPS_Paused;
111
        return 0;
112
    } else if (!value.compare("Playing")) {
113
        *tpp = TPS_Playing;
114
        return 0;
115
    } else if (!value.compare("Stopped")) {
116
        *tpp = TPS_Stopped;
117
        return 0;
118
    }
119
    *tpp = TPS_Unknown;
120
    return UPNP_E_BAD_RESPONSE;
121
}
122
123
int OHPlaylist::id(int *value)
124
{
125
    return runSimpleGet("Id", "Value", value);
126
}
127
128
int OHPlaylist::read(int id, std::string* urip, UPnPDirObject *dirent)
129
{
130
    SoapEncodeInput args(m_serviceType, "Read");
131
    args("Id", SoapHelp::i2s(id));
132
    SoapDecodeOutput data;
133
    int ret = runAction(args, data);
134
    if (ret != UPNP_E_SUCCESS) {
135
        return ret;
136
    }
137
    if (!data.get("Uri", urip)) {
138
        LOGERR("OHPlaylist::Read: missing Uri in response" << endl);
139
        return UPNP_E_BAD_RESPONSE;
140
    }
141
    string didl;
142
    if (!data.get("Metadata", &didl)) {
143
        LOGERR("OHPlaylist::Read: missing Uri in response" << endl);
144
        return UPNP_E_BAD_RESPONSE;
145
    }
146
    didl = SoapHelp::xmlUnquote(didl);
147
148
    UPnPDirContent dir;
149
    if (!dir.parse(didl)) {
150
        LOGERR("OHPlaylist::Read: didl parse failed: " << didl << endl);
151
        return UPNP_E_BAD_RESPONSE;
152
    }
153
    if (dir.m_items.size() != 1) {
154
        LOGERR("OHPlaylist::Read: " << dir.m_items.size() << " in response!" <<
155
               endl);
156
        return UPNP_E_BAD_RESPONSE;
157
    }
158
    *dirent = dir.m_items[0];
159
    return 0;
160
}
161
162
// Tracklist format
163
// <TrackList>
164
//   <Entry>
165
//     <Id>10</Id>
166
//     <Uri>http://blabla</Uri>
167
//     <Metadata>(xmlencoded didl)</Metadata>
168
//   </Entry>
169
// </TrackList>
170
171
172
class OHTrackListParser : public expatmm::inputRefXMLParser {
173
public:
174
    OHTrackListParser(const string& input, 
175
                      vector<OHPlaylist::TrackListEntry>* vp)
176
        : expatmm::inputRefXMLParser(input), m_v(vp)
177
        {}
178
179
protected:
180
    virtual void StartElement(const XML_Char *name, const XML_Char **) {
181
        m_path.push_back(name);
182
    }
183
    virtual void EndElement(const XML_Char *name) {
184
        if (!strcmp(name, "Entry")) {
185
            UPnPDirContent dir;
186
            if (!dir.parse(SoapHelp::xmlUnquote(m_tdidl))) {
187
                LOGERR("OHPlaylist::ReadList: didl parse failed: " 
188
                       << m_tdidl << endl);
189
                return;
190
            }
191
            if (dir.m_items.size() != 1) {
192
                LOGERR("OHPlaylist::ReadList: " << dir.m_items.size() 
193
                       << " in response!" << endl);
194
                return;
195
            }
196
            m_tt.dirent = dir.m_items[0];
197
            m_v->push_back(m_tt);
198
            m_tt.clear();
199
            m_tdidl.clear();
200
        }
201
        m_path.pop_back();
202
    }
203
    virtual void CharacterData(const XML_Char *s, int len) {
204
        if (s == 0 || *s == 0)
205
            return;
206
        string str(s, len);
207
        if (!m_path.back().compare("Id"))
208
            m_tt.id = atoi(str.c_str());
209
        else if (!m_path.back().compare("Uri"))
210
            m_tt.url = str;
211
        else if (!m_path.back().compare("Metadata"))
212
            m_tdidl += str;
213
    }
214
215
private:
216
    vector<OHPlaylist::TrackListEntry>* m_v;
217
    std::vector<std::string> m_path;
218
    OHPlaylist::TrackListEntry m_tt;
219
    string m_tdidl;
220
};
221
222
int OHPlaylist::readList(const std::vector<int>& ids, 
223
                         vector<TrackListEntry>* entsp)
224
{
225
    string idsparam;
226
    for (auto it = ids.begin(); it != ids.end(); it++) {
227
        idsparam += SoapHelp::i2s(*it) + " ";
228
    }
229
    entsp->clear();
230
231
    SoapEncodeInput args(m_serviceType, "ReadList");
232
    args("IdList", idsparam);
233
    SoapDecodeOutput data;
234
    int ret = runAction(args, data);
235
    if (ret != UPNP_E_SUCCESS) {
236
        return ret;
237
    }
238
    string xml;
239
    if (!data.get("TrackList", &xml)) {
240
        LOGERR("OHPlaylist::readlist: missing TrackList in response" << endl);
241
        return UPNP_E_BAD_RESPONSE;
242
    }
243
    OHTrackListParser mparser(xml, entsp);
244
    if (!mparser.Parse())
245
        return UPNP_E_BAD_RESPONSE;
246
    return 0;
247
}
248
249
int OHPlaylist::insert(int afterid, const string& uri, const string& didl, 
250
                       int *nid)
251
{
252
    SoapEncodeInput args(m_serviceType, "Insert");
253
    args("AfterId", SoapHelp::i2s(afterid))
254
        ("Uri", uri)
255
        ("Metadata", didl);
256
    SoapDecodeOutput data;
257
    int ret = runAction(args, data);
258
    if (ret != UPNP_E_SUCCESS) {
259
        return ret;
260
    }
261
    if (!data.get("NewId", nid)) {
262
        LOGERR("OHPlaylist::insert: missing Newid in response" << endl);
263
        return UPNP_E_BAD_RESPONSE;
264
    }
265
    return 0;
266
}
267
268
269
int OHPlaylist::deleteId(int value)
270
{
271
    return runSimpleAction("DeleteId", "Value", value);
272
}
273
int OHPlaylist::deleteAll()
274
{
275
    return runTrivialAction("DeleteAll");
276
}
277
int OHPlaylist::tracksMax(int *valuep)
278
{
279
    return runSimpleGet("TracksMax", "Value", valuep);
280
}
281
282
int OHPlaylist::idArray(vector<int> *ids, int *tokp)
283
{
284
    SoapEncodeInput args(m_serviceType, "IdArray");
285
    SoapDecodeOutput data;
286
    int ret = runAction(args, data);
287
    if (ret != UPNP_E_SUCCESS) {
288
        return ret;
289
    }
290
    if (!data.get("Token", tokp)) {
291
        LOGERR("OHPlaylist::insert: missing Token in response" << endl);
292
        return UPNP_E_BAD_RESPONSE;
293
    }
294
    string arraydata;
295
    if (!data.get("Array", &arraydata)) {
296
        LOGERR("OHPlaylist::insert: missing Array in response" << endl);
297
        return UPNP_E_BAD_RESPONSE;
298
    }
299
300
    arraydata = base64_decode(arraydata);
301
    const char *cp = arraydata.c_str();
302
    while (cp - arraydata.c_str() < int(arraydata.size())) {
303
        unsigned int *ip = (unsigned int *)cp;
304
        ids->push_back(ntohl(*ip));
305
        cp += 4;
306
    }
307
    return 0;
308
}
309
310
int OHPlaylist::idArrayChanged(int token, bool *changed)
311
{
312
    SoapEncodeInput args(m_serviceType, "IdArrayChanged");
313
    args("Token", SoapHelp::i2s(token));
314
    SoapDecodeOutput data;
315
    int ret = runAction(args, data);
316
    if (ret != UPNP_E_SUCCESS) {
317
        return ret;
318
    }
319
    if (!data.get("Value", changed)) {
320
        LOGERR("OHPlaylist::idArrayChanged: missing Value in response" << endl);
321
        return UPNP_E_BAD_RESPONSE;
322
    }
323
    return 0;
324
}
325
326
int OHPlaylist::protocolInfo(std::string *proto)
327
{
328
    SoapEncodeInput args(m_serviceType, "ProtocolInfo");
329
    SoapDecodeOutput data;
330
    int ret = runAction(args, data);
331
    if (ret != UPNP_E_SUCCESS) {
332
        return ret;
333
    }
334
    if (!data.get("Value", proto)) {
335
        LOGERR("OHPlaylist::protocolInfo: missing Value in response" << endl);
336
        return UPNP_E_BAD_RESPONSE;
337
    }
338
    return 0;
339
}
340
43
} // End namespace UPnPClient
341
} // End namespace UPnPClient
44
342