00001 #include <unistd.h>
00002
00003 #include <QFile>
00004
00005 #include "tvremoteutil.h"
00006 #include "cardutil.h"
00007 #include "inputinfo.h"
00008 #include "programinfo.h"
00009 #include "mythcorecontext.h"
00010 #include "remoteencoder.h"
00011 #include "tv_rec.h"
00012
00013 uint RemoteGetFlags(uint cardid)
00014 {
00015 if (gCoreContext->IsBackend())
00016 {
00017 const TVRec *rec = TVRec::GetTVRec(cardid);
00018 if (rec)
00019 return rec->GetFlags();
00020 }
00021
00022 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00023 strlist << "GET_FLAGS";
00024 if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
00025 return 0;
00026
00027 return strlist[0].toInt();
00028 }
00029
00030 uint RemoteGetState(uint cardid)
00031 {
00032 if (gCoreContext->IsBackend())
00033 {
00034 const TVRec *rec = TVRec::GetTVRec(cardid);
00035 if (rec)
00036 return rec->GetState();
00037 }
00038
00039 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00040 strlist << "GET_STATE";
00041 if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
00042 return kState_ChangingState;
00043
00044 return strlist[0].toInt();
00045 }
00046
00047
00048 bool RemoteRecordPending(uint cardid, const ProgramInfo *pginfo,
00049 int secsleft, bool hasLater)
00050 {
00051 if (gCoreContext->IsBackend())
00052 {
00053 TVRec *rec = TVRec::GetTVRec(cardid);
00054 if (rec)
00055 {
00056 rec->RecordPending(pginfo, secsleft, hasLater);
00057 return true;
00058 }
00059 }
00060
00061 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00062 strlist << "RECORD_PENDING";
00063 strlist << QString::number(secsleft);
00064 strlist << QString::number(hasLater);
00065 pginfo->ToStringList(strlist);
00066
00067 if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
00068 return false;
00069
00070 return strlist[0].toUpper() == "OK";
00071 }
00072
00073 bool RemoteStopLiveTV(uint cardid)
00074 {
00075 if (gCoreContext->IsBackend())
00076 {
00077 TVRec *rec = TVRec::GetTVRec(cardid);
00078 if (rec)
00079 {
00080 rec->StopLiveTV();
00081 return true;
00082 }
00083 }
00084
00085 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00086 strlist << "STOP_LIVETV";
00087
00088 if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
00089 return false;
00090
00091 return strlist[0].toUpper() == "OK";
00092 }
00093
00094 bool RemoteStopRecording(uint cardid)
00095 {
00096 if (gCoreContext->IsBackend())
00097 {
00098 TVRec *rec = TVRec::GetTVRec(cardid);
00099 if (rec)
00100 {
00101 rec->StopRecording();
00102 return true;
00103 }
00104 }
00105
00106 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00107 strlist << "STOP_RECORDING";
00108
00109 if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
00110 return false;
00111
00112 return strlist[0].toUpper() == "OK";
00113 }
00114
00115 void RemoteStopRecording(const ProgramInfo *pginfo)
00116 {
00117 QStringList strlist(QString("STOP_RECORDING"));
00118 pginfo->ToStringList(strlist);
00119
00120 gCoreContext->SendReceiveStringList(strlist);
00121 }
00122
00123 void RemoteCancelNextRecording(uint cardid, bool cancel)
00124 {
00125 QStringList strlist(QString("QUERY_RECORDER %1").arg(cardid));
00126 strlist << "CANCEL_NEXT_RECORDING";
00127 strlist << QString::number((cancel) ? 1 : 0);
00128
00129 gCoreContext->SendReceiveStringList(strlist);
00130 }
00131
00132 RemoteEncoder *RemoteRequestNextFreeRecorder(int curr)
00133 {
00134 QStringList strlist( "GET_NEXT_FREE_RECORDER" );
00135 strlist << QString("%1").arg(curr);
00136
00137 if (!gCoreContext->SendReceiveStringList(strlist, true))
00138 return NULL;
00139
00140 int num = strlist[0].toInt();
00141 QString hostname = strlist[1];
00142 int port = strlist[2].toInt();
00143
00144 return new RemoteEncoder(num, hostname, port);
00145 }
00146
00150 vector<uint> RemoteRequestFreeRecorderList(const vector<uint> &excluded_cardids)
00151 {
00152 #if 0
00153 vector<uint> list;
00154
00155 QStringList strlist("GET_FREE_RECORDER_LIST");
00156
00157 if (!gCoreContext->SendReceiveStringList(strlist, true))
00158 return list;
00159
00160 QStringList::const_iterator it = strlist.begin();
00161 for (; it != strlist.end(); ++it)
00162 list.push_back((*it).toUInt());
00163
00164 return list;
00165 #endif
00166 vector<uint> result;
00167 vector<uint> cards = CardUtil::GetCardList();
00168 for (uint i = 0; i < cards.size(); i++)
00169 {
00170 vector<InputInfo> inputs =
00171 RemoteRequestFreeInputList(cards[i], excluded_cardids);
00172 for (uint j = 0; j < inputs.size(); j++)
00173 {
00174 if (find(result.begin(),
00175 result.end(),
00176 inputs[j].cardid) == result.end())
00177 result.push_back(inputs[j].cardid);
00178 }
00179 }
00180 QString msg("RemoteRequestFreeRecorderList returned {");
00181 for (uint k = 0; k < result.size(); k++)
00182 msg += QString(" %1").arg(result[k]);
00183 msg += "}";
00184 LOG(VB_CHANNEL, LOG_INFO, msg);
00185 return result;
00186 }
00187
00188 RemoteEncoder *RemoteRequestFreeRecorderFromList
00189 (const QStringList &qualifiedRecorders, const vector<uint> &excluded_cardids)
00190 {
00191 #if 0
00192 QStringList strlist( "GET_FREE_RECORDER_LIST" );
00193
00194 if (!gCoreContext->SendReceiveStringList(strlist, true))
00195 return NULL;
00196
00197 for (QStringList::const_iterator recIter = qualifiedRecorders.begin();
00198 recIter != qualifiedRecorders.end(); ++recIter)
00199 {
00200 if (!strlist.contains(*recIter))
00201 {
00202
00203
00204 continue;
00205 }
00206
00207 return RemoteGetExistingRecorder((*recIter).toInt());
00208 }
00209
00210 return NULL;
00211 #endif
00212 vector<uint> freeRecorders =
00213 RemoteRequestFreeRecorderList(excluded_cardids);
00214 for (QStringList::const_iterator recIter = qualifiedRecorders.begin();
00215 recIter != qualifiedRecorders.end(); ++recIter)
00216 {
00217 if (find(freeRecorders.begin(),
00218 freeRecorders.end(),
00219 (*recIter).toUInt()) != freeRecorders.end())
00220 return RemoteGetExistingRecorder((*recIter).toInt());
00221 }
00222 return NULL;
00223 }
00224
00225 RemoteEncoder *RemoteRequestRecorder(void)
00226 {
00227 QStringList strlist( "GET_FREE_RECORDER" );
00228
00229 if (!gCoreContext->SendReceiveStringList(strlist, true))
00230 return NULL;
00231
00232 int num = strlist[0].toInt();
00233 QString hostname = strlist[1];
00234 int port = strlist[2].toInt();
00235
00236 return new RemoteEncoder(num, hostname, port);
00237 }
00238
00239 RemoteEncoder *RemoteGetExistingRecorder(const ProgramInfo *pginfo)
00240 {
00241 QStringList strlist( "GET_RECORDER_NUM" );
00242 pginfo->ToStringList(strlist);
00243
00244 if (!gCoreContext->SendReceiveStringList(strlist))
00245 return NULL;
00246
00247 int num = strlist[0].toInt();
00248 QString hostname = strlist[1];
00249 int port = strlist[2].toInt();
00250
00251 return new RemoteEncoder(num, hostname, port);
00252 }
00253
00254 RemoteEncoder *RemoteGetExistingRecorder(int recordernum)
00255 {
00256 QStringList strlist( "GET_RECORDER_FROM_NUM" );
00257 strlist << QString("%1").arg(recordernum);
00258
00259 if (!gCoreContext->SendReceiveStringList(strlist))
00260 return NULL;
00261
00262 QString hostname = strlist[0];
00263 int port = strlist[1].toInt();
00264
00265 return new RemoteEncoder(recordernum, hostname, port);
00266 }
00267
00268 vector<InputInfo> RemoteRequestFreeInputList(
00269 uint cardid, const vector<uint> &excluded_cardids)
00270 {
00271 vector<InputInfo> list;
00272
00273 QStringList strlist(QString("QUERY_RECORDER %1").arg(cardid));
00274 strlist << "GET_FREE_INPUTS";
00275 for (uint i = 0; i < excluded_cardids.size(); i++)
00276 strlist << QString::number(excluded_cardids[i]);
00277
00278 if (!gCoreContext->SendReceiveStringList(strlist))
00279 return list;
00280
00281 QStringList::const_iterator it = strlist.begin();
00282 if ((it == strlist.end()) || (*it == "EMPTY_LIST"))
00283 return list;
00284
00285 while (it != strlist.end())
00286 {
00287 InputInfo info;
00288 if (!info.FromStringList(it, strlist.end()))
00289 break;
00290 list.push_back(info);
00291 }
00292
00293 return list;
00294 }
00295
00296 InputInfo RemoteRequestBusyInputID(uint cardid)
00297 {
00298 InputInfo blank;
00299
00300 QStringList strlist(QString("QUERY_RECORDER %1").arg(cardid));
00301 strlist << "GET_BUSY_INPUT";
00302
00303 if (!gCoreContext->SendReceiveStringList(strlist))
00304 return blank;
00305
00306 QStringList::const_iterator it = strlist.begin();
00307 if ((it == strlist.end()) || (*it == "EMPTY_LIST"))
00308 return blank;
00309
00310 InputInfo info;
00311 if (info.FromStringList(it, strlist.end()))
00312 return info;
00313
00314 return blank;
00315 }
00316
00317 bool RemoteIsBusy(uint cardid, TunedInputInfo &busy_input)
00318 {
00319 #if 0
00320 LOG(VB_GENERAL, LOG_DEBUG, QString("RemoteIsBusy(%1) %2")
00321 .arg(cardid).arg(gCoreContext->IsBackend() ? "be" : "fe"));
00322 #endif
00323
00324 busy_input.Clear();
00325
00326 if (gCoreContext->IsBackend())
00327 {
00328 const TVRec *rec = TVRec::GetTVRec(cardid);
00329 if (rec)
00330 return rec->IsBusy(&busy_input);
00331 }
00332
00333 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00334 strlist << "IS_BUSY";
00335 if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
00336 return true;
00337
00338 QStringList::const_iterator it = strlist.begin();
00339 bool state = (*it).toInt();
00340 ++it;
00341 if (!busy_input.FromStringList(it, strlist.end()))
00342 state = true;
00343
00344 return state;
00345 }
00346
00347 bool RemoteGetRecordingStatus(
00348 vector<TunerStatus> *tunerList, bool list_inactive)
00349 {
00350 bool isRecording = false;
00351 vector<uint> cardlist = CardUtil::GetCardList();
00352
00353 if (tunerList)
00354 tunerList->clear();
00355
00356 for (uint i = 0; i < cardlist.size(); i++)
00357 {
00358 QString status = "";
00359 uint cardid = cardlist[i];
00360 int state = kState_ChangingState;
00361 QString channelName = "";
00362 QString title = "";
00363 QString subtitle = "";
00364 QDateTime dtStart = QDateTime();
00365 QDateTime dtEnd = QDateTime();
00366 QStringList strlist;
00367
00368 QString cmd = QString("QUERY_REMOTEENCODER %1").arg(cardid);
00369
00370 while (state == kState_ChangingState)
00371 {
00372 strlist = QStringList(cmd);
00373 strlist << "GET_STATE";
00374 gCoreContext->SendReceiveStringList(strlist);
00375
00376 if (strlist.empty())
00377 break;
00378
00379 state = strlist[0].toInt();
00380 if (kState_ChangingState == state)
00381 usleep(5000);
00382 }
00383
00384 if (kState_RecordingOnly == state || kState_WatchingRecording == state)
00385 {
00386 isRecording |= true;
00387
00388 if (!tunerList)
00389 break;
00390
00391 strlist = QStringList(QString("QUERY_RECORDER %1").arg(cardid));
00392 strlist << "GET_RECORDING";
00393 gCoreContext->SendReceiveStringList(strlist);
00394
00395 ProgramInfo progInfo(strlist);
00396
00397 title = progInfo.GetTitle();
00398 subtitle = progInfo.GetSubtitle();
00399 channelName = progInfo.GetChannelName();
00400 dtStart = progInfo.GetScheduledStartTime();
00401 dtEnd = progInfo.GetScheduledEndTime();
00402 }
00403 else if (!list_inactive)
00404 continue;
00405
00406 if (tunerList)
00407 {
00408 TunerStatus tuner;
00409 tuner.id = cardid;
00410 tuner.isRecording = ((kState_RecordingOnly == state) ||
00411 (kState_WatchingRecording == state));
00412 tuner.channame = channelName;
00413 tuner.title = (kState_ChangingState == state) ?
00414 QObject::tr("Error querying recorder state") : title;
00415 tuner.subtitle = subtitle;
00416 tuner.startTime = dtStart;
00417 tuner.endTime = dtEnd;
00418 tunerList->push_back(tuner);
00419 }
00420 }
00421
00422 return isRecording;
00423 }
00424
00425