MythTV  0.26-pre
playbacksock.cpp
Go to the documentation of this file.
00001 #include <QStringList>
00002 
00003 using namespace std;
00004 
00005 #include "compat.h"
00006 #include "playbacksock.h"
00007 #include "programinfo.h"
00008 #include "mainserver.h"
00009 
00010 #include "mythcorecontext.h"
00011 #include "mythmiscutil.h"
00012 #include "inputinfo.h"
00013 
00014 #define LOC QString("PlaybackSock: ")
00015 #define LOC_ERR QString("PlaybackSock, Error: ")
00016 
00017 PlaybackSock::PlaybackSock(MainServer *parent, MythSocket *lsock,
00018                            QString lhostname, PlaybackSockEventsMode eventsMode)
00019 {
00020     m_parent = parent;
00021     QString localhostname = gCoreContext->GetHostName();
00022 
00023     refCount = 0;
00024 
00025     sock = lsock;
00026     hostname = lhostname;
00027     m_eventsMode = eventsMode;
00028     ip = "";
00029     backend = false;
00030     mediaserver = false;
00031     expectingreply = false;
00032 
00033     disconnected = false;
00034     blockshutdown = true;
00035 
00036     if (hostname == localhostname)
00037         local = true;
00038     else
00039         local = false;
00040 }
00041 
00042 PlaybackSock::~PlaybackSock()
00043 {
00044     sock->DownRef();
00045 }
00046 
00047 void PlaybackSock::UpRef(void)
00048 {
00049     QMutexLocker locker(&refLock);
00050     refCount++;
00051 }
00052 
00053 bool PlaybackSock::DownRef(void)
00054 {
00055     QMutexLocker locker(&refLock);
00056 
00057     refCount--;
00058     if (refCount < 0)
00059     {
00060         m_parent->DeletePBS(this);
00061         return true;
00062     }
00063     return false;
00064 }
00065 
00066 bool PlaybackSock::wantsEvents(void) const
00067 {
00068     return (m_eventsMode != kPBSEvents_None);
00069 }
00070 
00071 bool PlaybackSock::wantsNonSystemEvents(void) const
00072 {
00073     return ((m_eventsMode == kPBSEvents_Normal) ||
00074             (m_eventsMode == kPBSEvents_NonSystem));
00075 }
00076 
00077 bool PlaybackSock::wantsSystemEvents(void) const
00078 {
00079     return ((m_eventsMode == kPBSEvents_Normal) ||
00080             (m_eventsMode == kPBSEvents_SystemOnly));
00081 }
00082 
00083 bool PlaybackSock::wantsOnlySystemEvents(void) const
00084 {
00085     return (m_eventsMode == kPBSEvents_SystemOnly);
00086 }
00087 
00088 PlaybackSockEventsMode PlaybackSock::eventsMode(void) const
00089 {
00090     return m_eventsMode;
00091 }
00092 
00093 bool PlaybackSock::SendReceiveStringList(
00094     QStringList &strlist, uint min_reply_length)
00095 {
00096     bool ok = false;
00097 
00098     sock->Lock();
00099     sock->UpRef();
00100 
00101     {
00102         QMutexLocker locker(&sockLock);
00103         expectingreply = true;
00104 
00105         sock->writeStringList(strlist);
00106         ok = sock->readStringList(strlist);
00107 
00108         while (ok && strlist[0] == "BACKEND_MESSAGE")
00109         {
00110             // oops, not for us
00111             if (strlist.size() >= 2)
00112             {
00113                 QString message = strlist[1];
00114                 strlist.pop_front();
00115                 strlist.pop_front();
00116                 MythEvent me(message, strlist);
00117                 gCoreContext->dispatch(me);
00118             }
00119 
00120             ok = sock->readStringList(strlist);
00121         }
00122 
00123         expectingreply = false;
00124     }
00125 
00126     sock->Unlock();
00127     sock->DownRef();
00128 
00129     if (!ok)
00130     {
00131         LOG(VB_GENERAL, LOG_ERR,
00132             "PlaybackSock::SendReceiveStringList(): No response.");
00133         return false;
00134     }
00135 
00136     if (min_reply_length && ((uint)strlist.size() < min_reply_length))
00137     {
00138         LOG(VB_GENERAL, LOG_ERR,
00139             "PlaybackSock::SendReceiveStringList(): Response too short");
00140         return false;
00141     }
00142 
00143     return true;
00144 }
00145 
00148 bool PlaybackSock::GoToSleep(void)
00149 {
00150     QStringList strlist(QString("GO_TO_SLEEP"));
00151 
00152     return SendReceiveStringList(strlist, 1) && (strlist[0] == "OK");
00153 }
00154 
00158 void PlaybackSock::GetDiskSpace(QStringList &o_strlist)
00159 {
00160     QStringList strlist(QString("QUERY_FREE_SPACE"));
00161 
00162     SendReceiveStringList(strlist);
00163 
00164     o_strlist += strlist;
00165 
00166 }
00167 
00168 int PlaybackSock::CheckRecordingActive(const ProgramInfo *pginfo)
00169 {
00170     QStringList strlist(QString("CHECK_RECORDING"));
00171     pginfo->ToStringList(strlist);
00172 
00173     if (SendReceiveStringList(strlist, 1))
00174         return strlist[0].toInt();
00175 
00176     return 0;
00177 }
00178 
00179 int PlaybackSock::DeleteFile(const QString &filename, const QString &sgroup)
00180 {
00181     QStringList strlist("DELETE_FILE");
00182     strlist << filename;
00183     strlist << sgroup;
00184 
00185     if (SendReceiveStringList(strlist, 1))
00186         return strlist[0].toInt();
00187 
00188     return 0;
00189 }
00190 
00191 int PlaybackSock::StopRecording(const ProgramInfo *pginfo)
00192 {
00193     QStringList strlist(QString("STOP_RECORDING"));
00194     pginfo->ToStringList(strlist);
00195 
00196     if (SendReceiveStringList(strlist, 1))
00197         return strlist[0].toInt();
00198 
00199     return 0;
00200 }
00201 
00202 int PlaybackSock::DeleteRecording(const ProgramInfo *pginfo,
00203                                   bool forceMetadataDelete)
00204 {
00205     QStringList strlist;
00206 
00207     if (forceMetadataDelete)
00208         strlist = QStringList( QString("FORCE_DELETE_RECORDING"));
00209     else
00210         strlist = QStringList( QString("DELETE_RECORDING"));
00211 
00212     pginfo->ToStringList(strlist);
00213 
00214     if (SendReceiveStringList(strlist, 1))
00215         return strlist[0].toInt();
00216 
00217     return 0;
00218 }
00219 
00220 bool PlaybackSock::FillProgramInfo(ProgramInfo &pginfo,
00221                                    const QString &playbackhost)
00222 {
00223     QStringList strlist(QString("FILL_PROGRAM_INFO"));
00224     strlist << playbackhost;
00225     pginfo.ToStringList(strlist);
00226 
00227     if (SendReceiveStringList(strlist))
00228     {
00229         ProgramInfo tmp(strlist);
00230         if (tmp.HasPathname() || tmp.GetChanID())
00231         {
00232             pginfo.clone(tmp, true);
00233             return true;
00234         }
00235     }
00236 
00237     return false;
00238 }
00239 
00240 QStringList PlaybackSock::GetSGFileList(QString &host, QString &groupname,
00241                                         QString &directory, bool fileNamesOnly)
00242 {
00243     QStringList strlist(QString("QUERY_SG_GETFILELIST"));
00244     strlist << host;
00245     strlist << groupname;
00246     strlist << directory;
00247     strlist << QString::number(fileNamesOnly);
00248 
00249     SendReceiveStringList(strlist);
00250 
00251     return strlist;
00252 }
00253 
00254 QStringList PlaybackSock::GetSGFileQuery(QString &host, QString &groupname,
00255                                          QString &filename)
00256 {
00257     QStringList strlist(QString("QUERY_SG_FILEQUERY"));
00258     strlist << host;
00259     strlist << groupname;
00260     strlist << filename;
00261 
00262     SendReceiveStringList(strlist);
00263 
00264     return strlist;
00265 }
00266 
00267 QString PlaybackSock::GetFileHash(QString filename, QString storageGroup)
00268 {
00269     QStringList strlist(QString("QUERY_FILE_HASH"));
00270     strlist << filename
00271             << storageGroup;
00272 
00273     SendReceiveStringList(strlist);
00274     return strlist[0];
00275 }
00276 
00277 QStringList PlaybackSock::GenPreviewPixmap(const QString &token,
00278                                            const ProgramInfo *pginfo)
00279 {
00280     QStringList strlist(QString("QUERY_GENPIXMAP2"));
00281     strlist += token;
00282     pginfo->ToStringList(strlist);
00283 
00284     SendReceiveStringList(strlist);
00285 
00286     return strlist;
00287 }
00288 
00289 QStringList PlaybackSock::GenPreviewPixmap(const QString &token,
00290                                            const ProgramInfo *pginfo,
00291                                            bool               time_fmt_sec,
00292                                            long long          time,
00293                                            const QString     &outputFile,
00294                                            const QSize       &outputSize)
00295 {
00296     QStringList strlist(QString("QUERY_GENPIXMAP2"));
00297     strlist += token;
00298     pginfo->ToStringList(strlist);
00299     strlist.push_back(time_fmt_sec ? "s" : "f");
00300     strlist.push_back(QString::number(time));
00301     strlist.push_back((outputFile.isEmpty()) ? "<EMPTY>" : outputFile);
00302     strlist.push_back(QString::number(outputSize.width()));
00303     strlist.push_back(QString::number(outputSize.height()));
00304 
00305     SendReceiveStringList(strlist);
00306 
00307     return strlist;
00308 }
00309 
00310 QDateTime PlaybackSock::PixmapLastModified(const ProgramInfo *pginfo)
00311 {
00312     QStringList strlist(QString("QUERY_PIXMAP_LASTMODIFIED"));
00313     pginfo->ToStringList(strlist);
00314 
00315     SendReceiveStringList(strlist);
00316 
00317     QDateTime datetime;
00318     if (!strlist.empty() && strlist[0] != "BAD")
00319     {
00320         uint timet = strlist[0].toUInt();
00321         datetime.setTime_t(timet);
00322     }
00323     return datetime;
00324 }
00325 
00326 bool PlaybackSock::CheckFile(ProgramInfo *pginfo)
00327 {
00328     QStringList strlist("QUERY_CHECKFILE");
00329     strlist << QString::number(0); // don't check slaves
00330     pginfo->ToStringList(strlist);
00331 
00332     if (SendReceiveStringList(strlist, 2))
00333     {
00334         pginfo->SetPathname(strlist[1]);
00335         return strlist[0].toInt();
00336     }
00337 
00338     return false;
00339 }
00340 
00341 bool PlaybackSock::IsBusy(int capturecardnum, InputInfo *busy_input,
00342                           int time_buffer)
00343 {
00344     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00345 
00346     strlist << "IS_BUSY";
00347     strlist << QString::number(time_buffer);
00348 
00349     if (!SendReceiveStringList(strlist, 1))
00350     {
00351         LOG(VB_GENERAL, LOG_ERR, LOC + "IsBusy: " +
00352             QString("QUERY_REMOTEENCODER %1").arg(capturecardnum) +
00353             " gave us no response.");
00354     }
00355 
00356     bool state = false;
00357 
00358     if (!strlist.isEmpty())
00359     {
00360         QStringList::const_iterator it = strlist.begin();
00361         state = (*it).toInt();
00362 
00363         if (busy_input)
00364         {
00365             ++it;
00366             if (!busy_input->FromStringList(it, strlist.end()))
00367             {
00368                 LOG(VB_GENERAL, LOG_ERR, LOC + "IsBusy: "
00369                     "Failed to parse response to " +
00370                     QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00371                 state = false;
00372                 // pretend it's not busy if we can't parse response
00373             }
00374         }
00375     }
00376 
00377     return state;
00378 }
00379 
00384 int PlaybackSock::GetEncoderState(int capturecardnum)
00385 {
00386     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00387     strlist << "GET_STATE";
00388 
00389     if (!SendReceiveStringList(strlist, 1))
00390     {
00391         LOG(VB_GENERAL, LOG_ERR, LOC + "GetEncoderState: " +
00392             QString("QUERY_REMOTEENCODER %1").arg(capturecardnum) +
00393             " gave us no response.");
00394 
00395         return kState_Error;
00396     }
00397 
00398     return strlist[0].toInt();
00399 }
00400 
00401 long long PlaybackSock::GetMaxBitrate(int capturecardnum)
00402 {
00403     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00404     strlist << "GET_MAX_BITRATE";
00405 
00406     if (SendReceiveStringList(strlist, 2))
00407         return strlist[0].toLongLong();
00408 
00409     return 20200000LL; // Peak bit rate for HD-PVR
00410 }
00411 
00416 ProgramInfo *PlaybackSock::GetRecording(uint cardid)
00417 {
00418     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
00419     strlist << "GET_CURRENT_RECORDING";
00420 
00421     if (!SendReceiveStringList(strlist))
00422         return NULL;
00423 
00424     ProgramInfo *pginfo = new ProgramInfo(strlist);
00425     if (!pginfo->HasPathname() && !pginfo->GetChanID())
00426     {
00427         delete pginfo;
00428         pginfo = NULL;
00429     }
00430 
00431     return pginfo;
00432 }
00433 
00434 bool PlaybackSock::EncoderIsRecording(int capturecardnum,
00435                                       const ProgramInfo *pginfo)
00436 {
00437     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00438     strlist << "MATCHES_RECORDING";
00439     pginfo->ToStringList(strlist);
00440 
00441     if (SendReceiveStringList(strlist, 1))
00442         return (bool) strlist[0].toInt();
00443 
00444     return false;
00445 }
00446 
00447 RecStatusType PlaybackSock::StartRecording(int capturecardnum,
00448                                            const ProgramInfo *pginfo)
00449 {
00450     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00451     strlist << "START_RECORDING";
00452     pginfo->ToStringList(strlist);
00453 
00454     if (SendReceiveStringList(strlist, 1))
00455         return RecStatusType(strlist[0].toInt());
00456 
00457     return rsUnknown;
00458 }
00459 
00460 RecStatusType PlaybackSock::GetRecordingStatus(int capturecardnum)
00461 {
00462     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00463     strlist << "GET_RECORDING_STATUS";
00464 
00465     if (!SendReceiveStringList(strlist, 1))
00466     {
00467         LOG(VB_GENERAL, LOG_ERR, LOC + "GetRecordingStatus: " +
00468             QString("QUERY_REMOTEENCODER %1").arg(capturecardnum) +
00469             " did not respond.");
00470 
00471         return rsUnknown;
00472     }
00473 
00474     return RecStatusType(strlist[0].toInt());
00475 }
00476 
00477 void PlaybackSock::RecordPending(int capturecardnum, const ProgramInfo *pginfo,
00478                                  int secsleft, bool hasLater)
00479 {
00480     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00481     strlist << "RECORD_PENDING";
00482     strlist << QString::number(secsleft);
00483     strlist << QString::number(hasLater);
00484     pginfo->ToStringList(strlist);
00485 
00486     SendReceiveStringList(strlist);
00487 }
00488 
00489 int PlaybackSock::SetSignalMonitoringRate(int capturecardnum,
00490                                           int rate, int notifyFrontend)
00491 {
00492     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00493     strlist << "SET_SIGNAL_MONITORING_RATE";
00494     strlist << QString::number(rate);
00495     strlist << QString::number(notifyFrontend);
00496 
00497     if (SendReceiveStringList(strlist, 1))
00498         return strlist[0].toInt();
00499 
00500     return -1;
00501 }
00502 
00503 void PlaybackSock::SetNextLiveTVDir(int capturecardnum, QString dir)
00504 {
00505     QStringList strlist(QString("SET_NEXT_LIVETV_DIR %1 %2")
00506                             .arg(capturecardnum)
00507                             .arg(dir));
00508 
00509     SendReceiveStringList(strlist);
00510 }
00511 
00512 vector<InputInfo> PlaybackSock::GetFreeInputs(int capturecardnum,
00513                                            const vector<uint> &excluded_cardids)
00514 {
00515     QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum));
00516     strlist << "GET_FREE_INPUTS";
00517 
00518     for (uint i = 0; i < excluded_cardids.size(); i++)
00519         strlist << QString::number(excluded_cardids[i]);
00520 
00521     SendReceiveStringList(strlist);
00522 
00523     vector<InputInfo> list;
00524 
00525     QStringList::const_iterator it = strlist.begin();
00526     if ((it == strlist.end()) || (*it == "EMPTY_LIST"))
00527         return list;
00528 
00529     while (it != strlist.end())
00530     {
00531         InputInfo info;
00532         if (!info.FromStringList(it, strlist.end()))
00533             break;
00534         list.push_back(info);
00535     }
00536 
00537     return list;
00538 }
00539 
00540 void PlaybackSock::CancelNextRecording(int capturecardnum, bool cancel)
00541 {
00542     QStringList strlist(QString("QUERY_REMOTEENCODER %1")
00543                         .arg(capturecardnum));
00544 
00545     strlist << "CANCEL_NEXT_RECORDING";
00546     strlist << QString::number(cancel);
00547 
00548     SendReceiveStringList(strlist);
00549 }
00550 
00551 QStringList PlaybackSock::ForwardRequest(const QStringList &slist)
00552 {
00553     QStringList strlist = slist;
00554 
00555     if (SendReceiveStringList(strlist))
00556         return strlist;
00557 
00558     return QStringList();
00559 }
00560 
00561 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends