Switch to unified view

a/upmpd/upmpd.cxx b/upmpd/upmpd.cxx
...
...
118
118
119
static const string serviceIdRender("urn:upnp-org:serviceId:RenderingControl");
119
static const string serviceIdRender("urn:upnp-org:serviceId:RenderingControl");
120
static const string serviceIdTransport("urn:upnp-org:serviceId:AVTransport");
120
static const string serviceIdTransport("urn:upnp-org:serviceId:AVTransport");
121
static const string serviceIdCM("urn:upnp-org:serviceId:ConnectionManager");
121
static const string serviceIdCM("urn:upnp-org:serviceId:ConnectionManager");
122
122
123
// Note: if we ever need this to work without cxx11, there is this:
124
// http://www.tutok.sk/fastgl/callback.html
123
UpMpd::UpMpd(const string& deviceid, 
125
UpMpd::UpMpd(const string& deviceid, 
124
             const unordered_map<string, string>& xmlfiles,
126
             const unordered_map<string, string>& xmlfiles,
125
             MPDCli *mpdcli, Options opts)
127
             MPDCli *mpdcli, Options opts)
126
    : UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_desiredvolume(-1),
128
    : UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_desiredvolume(-1),
127
      m_options(opts)
129
      m_options(opts)
128
{
130
{
129
    addServiceType(serviceIdRender,
131
    addServiceType(serviceIdRender,
130
                   "urn:schemas-upnp-org:service:RenderingControl:1");
132
                   "urn:schemas-upnp-org:service:RenderingControl:1");
131
  {   auto bound = bind(&UpMpd::setMute, this, _1, _2);
133
  addActionMapping("SetMute", bind(&UpMpd::setMute, this, _1, _2));
132
      addActionMapping("SetMute", bound);
134
  addActionMapping("GetMute", bind(&UpMpd::getMute, this, _1, _2));
133
  }
135
  addActionMapping("SetVolume", bind(&UpMpd::setVolume, this, _1, _2, false));
134
  {   auto bound = bind(&UpMpd::getMute, this, _1, _2);
136
  addActionMapping("GetVolume", bind(&UpMpd::getVolume, this, _1, _2, false));
135
      addActionMapping("GetMute", bound);
137
  addActionMapping("ListPresets", bind(&UpMpd::listPresets, this, _1, _2));
136
  }
138
  addActionMapping("SelectPreset", bind(&UpMpd::selectPreset, this, _1, _2));
137
  {   auto bound = bind(&UpMpd::setVolume, this, _1, _2, false);
139
#if 0
138
      addActionMapping("SetVolume", bound);
139
  }
140
//    {   auto bound = bind(&UpMpd::setVolume, this, _1, _2, true);
141
//        addActionMapping("SetVolumeDB", bound);
142
//    }
143
  {   auto bound = bind(&UpMpd::getVolume, this, _1, _2, false);
144
      addActionMapping("GetVolume", bound);
145
  }
146
//    {   auto bound = bind(&UpMpd::getVolume, this, _1, _2, true);
147
//       addActionMapping("GetVolumeDB", bound);
140
    addActionMapping("GetVolumeDB", 
148
//    }
141
                   bind(&UpMpd::getVolume, this, _1, _2, true));
149
  {   auto bound = bind(&UpMpd::listPresets, this, _1, _2);
142
  addActionMapping("SetVolumeDB", 
150
      addActionMapping("ListPresets", bound);
143
                   bind(&UpMpd::setVolume, this, _1, _2, true));
151
  }
152
  {   auto bound = bind(&UpMpd::selectPreset, this, _1, _2);
153
      addActionMapping("SelectPreset", bound);
154
  }
155
//    {   auto bound = bind(&UpMpd::getVolumeDBRange, this, _1, _2);
156
//       addActionMapping("GetVolumeDBRange", bound);
144
    addActionMapping("GetVolumeDBRange", 
157
//    }
145
                   bind(&UpMpd::getVolumeDBRange, this, _1, _2));
146
#endif
158
147
159
    addServiceType(serviceIdTransport,
148
    addServiceType(serviceIdTransport,
160
                   "urn:schemas-upnp-org:service:AVTransport:1");
149
                   "urn:schemas-upnp-org:service:AVTransport:1");
161
162
  {   auto bound = bind(&UpMpd::setAVTransportURI, this, _1, _2, false);
163
     addActionMapping("SetAVTransportURI", bound);
150
    addActionMapping("SetAVTransportURI", 
164
  }
165
    { auto bound = bind(&UpMpd::setAVTransportURI, this, _1, _2, true);
151
                   bind(&UpMpd::setAVTransportURI, this, _1, _2, false));
166
     addActionMapping("SetNextAVTransportURI", bound);
152
    addActionMapping("SetNextAVTransportURI", 
167
  }
153
                   bind(&UpMpd::setAVTransportURI, this, _1, _2, true));
168
  {   auto bound = bind(&UpMpd::getPositionInfo, this, _1, _2);
169
     addActionMapping("GetPositionInfo", bound);
154
    addActionMapping("GetPositionInfo", 
170
  }
155
                   bind(&UpMpd::getPositionInfo, this, _1, _2));
171
  {   auto bound = bind(&UpMpd::getTransportInfo, this, _1, _2);
172
     addActionMapping("GetTransportInfo", bound);
156
    addActionMapping("GetTransportInfo", 
173
  }
157
                   bind(&UpMpd::getTransportInfo, this, _1, _2));
174
  {   auto bound = bind(&UpMpd::getMediaInfo, this, _1, _2);
175
     addActionMapping("GetMediaInfo", bound);
158
    addActionMapping("GetMediaInfo", 
176
  }
159
                   bind(&UpMpd::getMediaInfo, this, _1, _2));
177
  {   auto bound = bind(&UpMpd::getDeviceCapabilities, this, _1, _2);
178
     addActionMapping("GetDeviceCapabilities", bound);
160
    addActionMapping("GetDeviceCapabilities", 
179
  }
161
                   bind(&UpMpd::getDeviceCapabilities, this, _1, _2));
180
  {   auto bound = bind(&UpMpd::setPlayMode, this, _1, _2);
162
  addActionMapping("SetPlayMode", bind(&UpMpd::setPlayMode, this, _1, _2));
181
      addActionMapping("SetPlayMode", bound);
182
  }
183
  {   auto bound = bind(&UpMpd::getTransportSettings, this, _1, _2);
184
     addActionMapping("GetTransportSettings", bound);
163
    addActionMapping("GetTransportSettings", 
185
  }
164
                   bind(&UpMpd::getTransportSettings, this, _1, _2));
186
  {   auto bound = bind(&UpMpd::getCurrentTransportActions, this, _1, _2);
187
     addActionMapping("GetCurrentTransportActions", bound);
165
    addActionMapping("GetCurrentTransportActions", 
188
  }
166
                   bind(&UpMpd::getCurrentTransportActions, this, _1, _2));
189
  {   auto bound = bind(&UpMpd::playcontrol, this, _1, _2, 0);
167
  addActionMapping("Stop", bind(&UpMpd::playcontrol, this, _1, _2, 0));
190
      addActionMapping("Stop", bound);
191
  }
192
  {  auto bound = bind(&UpMpd::playcontrol, this, _1, _2, 1);
168
    addActionMapping("Play", bind(&UpMpd::playcontrol, this, _1, _2, 1));
193
      addActionMapping("Play", bound);
169
  addActionMapping("Pause", bind(&UpMpd::playcontrol, this, _1, _2, 2));
194
  }
170
  addActionMapping("Seek", bind(&UpMpd::seek, this, _1, _2));
195
  {   auto bound = bind(&UpMpd::playcontrol, this, _1, _2, 2);
196
      addActionMapping("Pause", bound);
197
  }
198
  {   auto bound = bind(&UpMpd::seek, this, _1, _2);
199
      addActionMapping("Seek", bound);
200
  }
201
  {  auto bound = bind(&UpMpd::seqcontrol, this, _1, _2, 0);
171
    addActionMapping("Next", bind(&UpMpd::seqcontrol, this, _1, _2, 0));
202
      addActionMapping("Next", bound);
203
  }
204
  {  auto bound = bind(&UpMpd::seqcontrol, this, _1, _2, 1);
172
    addActionMapping("Previous", bind(&UpMpd::seqcontrol, this, _1, _2, 1));
205
      addActionMapping("Previous", bound);
206
  }
207
173
208
    addServiceType(serviceIdCM,
174
    addServiceType(serviceIdCM,
209
                   "urn:schemas-upnp-org:service:ConnectionManager:1");
175
                   "urn:schemas-upnp-org:service:ConnectionManager:1");
210
  {   auto bound = bind(&UpMpd::getCurrentConnectionIDs, this, _1, _2);
211
     addActionMapping("GetCurrentConnectionIDs", bound);
176
    addActionMapping("GetCurrentConnectionIDs", 
212
  }
213
    { auto bound = bind(&UpMpd::getCurrentConnectionInfo, this, _1, _2);
177
                   bind(&UpMpd::getCurrentConnectionIDs, this, _1, _2));
214
     addActionMapping("GetCurrentConnectionInfo", bound);
178
    addActionMapping("GetCurrentConnectionInfo", 
215
  }
179
                   bind(&UpMpd::getCurrentConnectionInfo, this, _1, _2));
216
  {   auto bound = bind(&UpMpd::getProtocolInfo, this, _1, _2);
217
     addActionMapping("GetProtocolInfo", bound);
180
    addActionMapping("GetProtocolInfo", 
218
  }
181
                   bind(&UpMpd::getProtocolInfo, this, _1, _2));
219
}
182
}
220
183
221
// This is called by the polling loop at regular intervals, or when
184
// This is called by the polling loop at regular intervals, or when
222
// triggered, to retrieve changed state variables for each of the
185
// triggered, to retrieve changed state variables for each of the
223
// services (the list of services was defined in the base class by the
186
// services (the list of services was defined in the base class by the
...
...
1027
    if (it == sc.args.end() || it->second.empty()) {
990
    if (it == sc.args.end() || it->second.empty()) {
1028
        return UPNP_E_INVALID_PARAM;
991
        return UPNP_E_INVALID_PARAM;
1029
    }
992
    }
1030
    string target(it->second);
993
    string target(it->second);
1031
994
1032
  // LOGDEB("UpMpd::seek: unit " << unit << " target " << target);
1033
1034
    const MpdStatus &mpds = m_mpdcli->getStatus();
995
    const MpdStatus &mpds = m_mpdcli->getStatus();
996
997
  //LOGDEB("UpMpd::seek: unit " << unit << " target " << target << 
998
  //     " current posisition " << mpds.songelapsedms / 1000 << 
999
  //     " seconds" << endl);
1000
1035
    int abs_seconds;
1001
    int abs_seconds;
1002
  // Note that ABS_TIME and REL_TIME don't mean what you'd think
1003
  // they mean.  REL_TIME means relative to the current track,
1004
  // ABS_TIME to the whole media (ie for a multitrack tape). So
1005
  // we only support REL_TIME, as absolute position in the current song
1036
    if (!unit.compare("ABS_TIME")) {
1006
     if (!unit.compare("REL_TIME")) {
1037
        abs_seconds = upnpdurationtos(target);
1007
        abs_seconds = upnpdurationtos(target);
1038
  } else  if (!unit.compare("REL_TIME")) {
1039
      abs_seconds = mpds.songelapsedms / 1000;
1040
      abs_seconds += upnpdurationtos(target);
1041
//    } else  if (!unit.compare("TRACK_NR")) {
1042
    } else {
1008
    } else {
1043
        return UPNP_E_INVALID_PARAM;
1009
        return UPNP_E_INVALID_PARAM;
1044
    }
1010
    }
1011
  LOGDEB("UpMpd::seek: seeking to " << abs_seconds << " seconds (" <<
1012
         upnpduration(abs_seconds * 1000) << ")" << endl);
1045
1013
1046
    loopWakeup();
1014
    loopWakeup();
1047
    return m_mpdcli->seek(abs_seconds) ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
1015
    return m_mpdcli->seek(abs_seconds) ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
1048
}
1016
}
1049
1017