diff --git a/src/nhttpd/tuxboxapi/coolstream/Makefile.am b/src/nhttpd/tuxboxapi/coolstream/Makefile.am new file mode 100644 index 000000000..4c4c5681d --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = -fno-rtti -fno-exceptions + +INCLUDES = \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src/zapit/include \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/nhttpd \ + -I$(top_srcdir)/src/nhttpd/yhttpd_core \ + -I$(top_srcdir)/src/nhttpd/yhttpd_mods \ + -I$(top_srcdir)/lib/connection \ + -I$(top_srcdir)/lib/libeventserver \ + -I$(top_srcdir)/lib/libconfigfile \ + -I$(top_srcdir)/lib/xmltree \ + @FREETYPE_CFLAGS@ + +noinst_LIBRARIES = libnhttpd_tuxboxapi.a + +libnhttpd_tuxboxapi_a_SOURCES = \ + neutrinoapi.cpp neutrinoyparser.cpp controlapi.cpp + diff --git a/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp b/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp new file mode 100644 index 000000000..58b5ceac9 --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp @@ -0,0 +1,1913 @@ +//============================================================================= +// NHTTPD +// Neutrino ControlAPI +//============================================================================= +#include +// C +#include +#include +// C++ +#include +#include +#include +// system +#include +#include +// tuxbox +#include +#include +#include +#include +#include +// yhttpd +#include "yhttpd.h" +#include "ytypes_globals.h" +#include "ylogging.h" +#include "helper.h" +// nhttpd +#include "neutrinoapi.h" +#include "controlapi.h" + +bool sectionsd_getEPGidShort(event_id_t epgID, CShortEPGData * epgdata); +bool sectionsd_getEPGid(const event_id_t epgID, const time_t startzeit, CEPGData * epgdata); +void sectionsd_getEventsServiceKey(t_channel_id serviceUniqueKey, CChannelEventList &eList, char search = 0, std::string search_text = ""); +void sectionsd_getCurrentNextServiceKey(t_channel_id uniqueServiceKey, CSectionsdClient::responseGetCurrentNextInfoChannelID& current_next ); +bool sectionsd_getLinkageDescriptorsUniqueKey(const event_id_t uniqueKey, CSectionsdClient::LinkageDescriptorList& descriptors); +bool sectionsd_getComponentTagsUniqueKey(const event_id_t uniqueKey, CSectionsdClient::ComponentTagList& tags); +extern tallchans allchans; +extern CBouquetManager *g_bouquetManager; +extern t_channel_id live_channel_id; +#define EVENTDEV "/dev/input/input0" + +//----------------------------------------------------------------------------- +enum { // not defined in input.h but used like that, at least in 2.4.22 + KEY_RELEASED = 0, + KEY_PRESSED, + KEY_AUTOREPEAT +}; + +//============================================================================= +// Initialization of static variables +//============================================================================= +std::string CControlAPI::PLUGIN_DIRS[PLUGIN_DIR_COUNT]; + +//============================================================================= +// constructor und destructor +//============================================================================= +CControlAPI::CControlAPI(CNeutrinoAPI *_NeutrinoAPI) +{ + NeutrinoAPI = _NeutrinoAPI; +} +//----------------------------------------------------------------------------- +void CControlAPI::init(CyhookHandler *hh) +{ + if(PLUGIN_DIRS[0] == "") + { // given in nhttpd.conf + PLUGIN_DIRS[0]=hh->WebserverConfigList["PublicDocumentRoot"]; + PLUGIN_DIRS[0].append("/scripts"); + PLUGIN_DIRS[1]=hh->WebserverConfigList["PrivatDocumentRoot"]; + PLUGIN_DIRS[1].append("/scripts"); + PLUGIN_DIRS[2]="/var/tuxbox/plugins"; + PLUGIN_DIRS[3]=PLUGINDIR; + PLUGIN_DIRS[4]="/mnt/plugins"; + } +} + +//============================================================================= +// Hooks! +//============================================================================= +//----------------------------------------------------------------------------- +THandleStatus CControlAPI::Hook_PrepareResponse(CyhookHandler *hh) +{ + init(hh); + + if(hh->UrlData["path"] == "/control/" + || hh->UrlData["path"] == "/cgi-bin/" + || hh->UrlData["path"] == "/fb/" + ) + return HANDLED_READY; + else + return HANDLED_NONE; +} +//----------------------------------------------------------------------------- +// HOOK: response_hook Handler +// This is the main dispatcher for this module +//----------------------------------------------------------------------------- +THandleStatus CControlAPI::Hook_SendResponse(CyhookHandler *hh) +{ + hh->status = HANDLED_NONE; + +// log_level_printfX(4,"CControlAPI hook start url:%s\n",hh->UrlData["url"].c_str()); + init(hh); + + if(hh->UrlData["path"] == "/control/" + || hh->UrlData["path"] == "/cgi-bin/") + Execute(hh); + if(hh->UrlData["path"] == "/fb/") // fb-compatibility for timer-calls + compatibility_Timer(hh); +// log_level_printfX(4,"CControlAPI hook ende status:%d\n",(int)hh->status); +// log_level_printfX(5,"CControlAPI hook result:%s\n",hh->yresult.c_str()); + + return hh->status; +} + +//============================================================================= +//------------------------------------------------------------------------- +// timer compatibility +// do add/modify/remove and Return (redirect) Timerlist +//------------------------------------------------------------------------- +void CControlAPI::compatibility_Timer(CyhookHandler *hh) +{ + log_level_printf(4,"CControlAPI Compatibility Timer Start url:%s\n",hh->UrlData["url"].c_str()); + if(NeutrinoAPI->Timerd->isTimerdAvailable() && hh->ParamList.size() > 0) + { + if(hh->ParamList["action"] == "remove") + { + unsigned removeId = atoi(hh->ParamList["id"].c_str()); + NeutrinoAPI->Timerd->removeTimerEvent(removeId); + } + else if(hh->ParamList["action"] == "modify") + doModifyTimer(hh); + else if(hh->ParamList["action"] == "new") + doNewTimer(hh); + } + hh->SendRedirect("/Y_Timer_List.yhtm"); +} + +//============================================================================= +// Main Dispatcher / Call definitions +//============================================================================= +const CControlAPI::TyCgiCall CControlAPI::yCgiCallList[]= +{ + // channel & bouquet & epg & zapping handling + {"getservicesxml", &CControlAPI::GetServicesxmlCGI,""}, + {"getbouquetsxml", &CControlAPI::GetBouquetsxmlCGI,""}, + {"channellist", &CControlAPI::ChannellistCGI, "text/plain"}, + {"getbouquet", &CControlAPI::GetBouquetCGI, "+xml"}, + {"getbouquets", &CControlAPI::GetBouquetsCGI, "text/plain"}, + {"getmode", &CControlAPI::GetModeCGI, "text/plain"}, + {"setmode", &CControlAPI::SetModeCGI, "text/plain"}, + {"epg", &CControlAPI::EpgCGI, ""}, + {"zapto", &CControlAPI::ZaptoCGI, "text/plain"}, + {"getonidsid", &CControlAPI::GetChannel_IDCGI, "text/plain"}, + // boxcontrol - system + {"standby", &CControlAPI::StandbyCGI, "text/plain"}, + {"shutdown", &CControlAPI::ShutdownCGI, "text/plain"}, + {"reboot", &CControlAPI::RebootCGI, "text/plain"}, + {"getdate", &CControlAPI::GetDateCGI, "text/plain"}, + {"gettime", &CControlAPI::GetTimeCGI, "text/plain"}, + {"info", &CControlAPI::InfoCGI, "text/plain"}, + {"version", &CControlAPI::VersionCGI, ""}, + // boxcontrol - devices + {"volume", &CControlAPI::VolumeCGI, "text/plain"}, + {"lcd", &CControlAPI::LCDAction, "text/plain"}, + {"system", &CControlAPI::SystemCGI, "text/plain"}, + {"message", &CControlAPI::MessageCGI, "text/plain"}, + {"rc", &CControlAPI::RCCGI, "text/plain"}, + {"rcem", &CControlAPI::RCEmCGI, "text/plain"}, + // Start skripts, plugins + {"startplugin", &CControlAPI::StartPluginCGI, "text/plain"}, + {"exec", &CControlAPI::ExecCGI, "+xml"}, + {"yweb", &CControlAPI::YWebCGI, "text/plain"}, + // video handling + {"videoformat", &CControlAPI::VideoFormatCGI, "text/plain"}, + {"videooutput", &CControlAPI::VideoOutputCGI, "text/plain"}, + {"vcroutput", &CControlAPI::VCROutputCGI, "text/plain"}, + {"scartmode", &CControlAPI::ScartModeCGI, "text/plain"}, + // timer + {"timer", &CControlAPI::TimerCGI, "text/plain"}, + // bouquet editing + {"setbouquet", &CControlAPI::setBouquetCGI, "text/plain"}, + {"savebouquet", &CControlAPI::saveBouquetCGI, "text/plain"}, + {"movebouquet", &CControlAPI::moveBouquetCGI, "text/plain"}, + {"deletebouquet", &CControlAPI::deleteBouquetCGI, "text/plain"}, + {"addbouquet", &CControlAPI::addBouquetCGI, "text/plain"}, + {"renamebouquet", &CControlAPI::renameBouquetCGI, "text/plain"}, + {"changebouquet", &CControlAPI::changeBouquetCGI, "text/plain"}, + {"updatebouquet", &CControlAPI::updateBouquetCGI, "text/plain"}, + // utils + {"build_live_url", &CControlAPI::build_live_url, ""}, + + +}; +//----------------------------------------------------------------------------- +// Main Dispatcher +//----------------------------------------------------------------------------- +void CControlAPI::Execute(CyhookHandler *hh) +{ + int index = -1; + std::string yresult; + std::string filename = hh->UrlData["filename"]; + + log_level_printf(4,"ControlAPI.Execute filename:(%s)\n",filename.c_str()); + // tolower(filename) + for(unsigned int i = 0; i < filename.length(); i++) + filename[i] = tolower(filename[i]); + + // debugging informations + if(CLogging::getInstance()->getDebug()) + { + dprintf("Execute CGI : %s\n",filename.c_str()); + for(CStringList::iterator it = hh->ParamList.begin() ; + it != hh->ParamList.end() ; it++) + dprintf(" Parameter %s : %s\n",it->first.c_str(), it->second.c_str()); + } + + // get function index + for(unsigned int i = 0;i < (sizeof(yCgiCallList)/sizeof(yCgiCallList[0])); i++) + if (filename == yCgiCallList[i].func_name) + { + index = i; + break; + } + if(index == -1) // function not found + { + hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED); + return; + } + + // send header + else if(std::string(yCgiCallList[index].mime_type) == "") // decide in function + ; + else if(std::string(yCgiCallList[index].mime_type) == "+xml") // Parameter xml? + if (hh->ParamList["xml"] != "") + hh->SetHeader(HTTP_OK, "text/xml; charset=UTF-8"); + else + hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8"); + else + hh->SetHeader(HTTP_OK, yCgiCallList[index].mime_type); + // response + hh->status = HANDLED_READY; + if (hh->Method == M_HEAD) // HEAD or function call + return; + else + { + (this->*yCgiCallList[index].pfunc)(hh); + return; + } +} + +//============================================================================= +// CGI Functions +// CyhookHandler contains input/output abstractions +//============================================================================= +void CControlAPI::TimerCGI(CyhookHandler *hh) +{ + if (NeutrinoAPI->Timerd->isTimerdAvailable()) + { + if (!hh->ParamList.empty() && hh->ParamList["format"].empty()) + { + if (hh->ParamList["action"] == "new") + doNewTimer(hh); + else if (hh->ParamList["action"] == "modify") + doModifyTimer(hh); + else if (hh->ParamList["action"] == "remove") + { + unsigned removeId = atoi(hh->ParamList["id"].c_str()); + NeutrinoAPI->Timerd->removeTimerEvent(removeId); + hh->SendOk(); + } + else if(hh->ParamList["get"] != "") + { + int pre=0,post=0; + NeutrinoAPI->Timerd->getRecordingSafety(pre,post); + if(hh->ParamList["get"] == "pre") + hh->printf("%d\n", pre); + else if(hh->ParamList["get"] == "post") + hh->printf("%d\n", post); + else + hh->SendError(); + } + } + else + SendTimers(hh); + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::SetModeCGI(CyhookHandler *hh) +{ + if (!(hh->ParamList.empty())) + { + if (hh->ParamList["1"] == "status") // display recoding status + { + if (NeutrinoAPI->Zapit->isRecordModeActive()) + hh->WriteLn("on"); + else + hh->WriteLn("off"); + return; + } + + if (hh->ParamList["1"] == "radio") // switch to radio mode + { + int mode = NeutrinoMessages::mode_radio; + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::CHANGEMODE, CEventServer::INITID_HTTPD, (void *)&mode,sizeof(int)); + sleep(1); + NeutrinoAPI->UpdateBouquets(); + } + else if (hh->ParamList["1"] == "tv") // switch to tv mode + { + int mode = NeutrinoMessages::mode_tv; + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::CHANGEMODE, CEventServer::INITID_HTTPD, (void *)&mode,sizeof(int)); + sleep(1); + NeutrinoAPI->UpdateBouquets(); + } + else if (hh->ParamList["record"] == "start") // start record mode + { + if(hh->ParamList["stopplayback"] == "true") + NeutrinoAPI->Zapit->stopPlayBack(); + NeutrinoAPI->Sectionsd->setPauseScanning(true); + NeutrinoAPI->Zapit->setRecordMode(true); + } + else if (hh->ParamList["record"] == "stop") // stop record mode + { + NeutrinoAPI->Zapit->setRecordMode(false); + NeutrinoAPI->Sectionsd->setPauseScanning(false); + if (!NeutrinoAPI->Zapit->isPlayBackActive()) + NeutrinoAPI->Zapit->startPlayBack(); + } + hh->SendOk(); + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::GetModeCGI(CyhookHandler *hh) +{ + int mode = NeutrinoAPI->Zapit->getMode(); + if ( mode == CZapitClient::MODE_TV) + hh->WriteLn("tv"); + else if ( mode == CZapitClient::MODE_RADIO) + return hh->WriteLn("radio"); + else + return hh->WriteLn("unknown"); +} + +//----------------------------------------------------------------------------- +void CControlAPI::ExecCGI(CyhookHandler *hh) +{ + bool res = false; + std::string script, result; + // override standard header + if (hh->ParamList.size() > 1 && hh->ParamList["xml"].empty()) + hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8"); + else if (hh->ParamList.size() > 1 && !hh->ParamList["xml"].empty()) + hh->SetHeader(HTTP_OK, "text/xml; charset=UTF-8"); + else + hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); + if (hh->ParamList.size() > 0) + { + script = hh->ParamList["1"]; + unsigned int len = hh->ParamList.size(); + for(unsigned int y=2;y<=len;y++) + if(!hh->ParamList[itoa(y)].empty()) + { + script += " "; + script += hh->ParamList[itoa(y)]; + } + result = YexecuteScript(hh, script); + } + else + printf("[CControlAPI] no script given\n"); + + res = (result != "error"); + if (res) + hh->Write(result); + else + hh->SetError(HTTP_NOT_FOUND); +} + +//----------------------------------------------------------------------------- +void CControlAPI::SystemCGI(CyhookHandler *hh) +{ + if (!(hh->ParamList.empty())) + { + //FIXME: No system information until now + hh->SendOk(); + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::StandbyCGI(CyhookHandler *hh) +{ + if (!(hh->ParamList.empty())) + { + if (hh->ParamList["1"] == "on") // standby mode on + { + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::STANDBY_ON, CEventServer::INITID_HTTPD); + hh->SendOk(); + } + else if (hh->ParamList["1"] == "off")// standby mode off + { + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::STANDBY_OFF, CEventServer::INITID_HTTPD); + hh->SendOk(); + } + else + hh->SendError(); + } + else +#if HAVE_DBOX2 // FIXME: not implemented + if(NeutrinoAPI->Controld->getVideoPowerDown()) + hh->WriteLn("on"); + else +#endif + hh->WriteLn("off"); +} + +//----------------------------------------------------------------------------- +void CControlAPI::RCCGI(CyhookHandler *hh) +{ + if (!(hh->ParamList.empty())) + { + if (hh->ParamList["1"] == "lock") // lock remote control + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::LOCK_RC, CEventServer::INITID_HTTPD); + else if (hh->ParamList["1"] == "unlock")// unlock remote control + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::UNLOCK_RC, CEventServer::INITID_HTTPD); + else + hh->SendError(); + } + hh->SendOk(); +} + +//----------------------------------------------------------------------------- +// Get actual Date +// security: strftime has buffer-overflow limit. ok! +//----------------------------------------------------------------------------- +void CControlAPI::GetDateCGI(CyhookHandler *hh) +{ + if (hh->ParamList.empty()) + { + //paramlos + char *timestr = new char[50]; + struct timeb tm; + ftime(&tm); + strftime(timestr, 20, "%d.%m.%Y\n", localtime(&tm.time) ); + hh->Write(timestr); + delete[] timestr; + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +// Get actual Time +// security: strftime has buffer-overflow limit. ok! +//----------------------------------------------------------------------------- +void CControlAPI::GetTimeCGI(CyhookHandler *hh) +{ + time_t now = time(NULL); + + if (hh->ParamList.empty()) + { + //paramlos + char *timestr = new char[50]; + struct tm *tm = localtime(&now); + strftime(timestr, 20, "%H:%M:%S\n", tm ); + hh->Write(timestr); + delete[] timestr; + } + else if (hh->ParamList["1"].compare("rawtime") == 0) + hh->printf("%ld\n",now); + else + hh->SendError(); +} +//----------------------------------------------------------------------------- +// send services.xml +void CControlAPI::GetServicesxmlCGI(CyhookHandler *hh) +{ + hh->SendFile("/var/tuxbox/config/zapit/services.xml"); +} + +//----------------------------------------------------------------------------- +// send bouquets.xml +void CControlAPI::GetBouquetsxmlCGI(CyhookHandler *hh) +{ + hh->SendFile("/var/tuxbox/config/zapit/bouquets.xml"); +} + +//----------------------------------------------------------------------------- +// get actual channel_id +void CControlAPI::GetChannel_IDCGI(CyhookHandler *hh) +{ + CZapitClient::CCurrentServiceInfo current_pids = NeutrinoAPI->Zapit->getCurrentServiceInfo(); + hh->printf("%x%04x%04x\n",current_pids.tsid, current_pids.onid, current_pids.sid); +} + +//----------------------------------------------------------------------------- +void CControlAPI::MessageCGI(CyhookHandler *hh) +{ + std::string message; + int event = 0; + + if (!(hh->ParamList["popup"].empty())) + { + message = hh->ParamList["popup"]; + event = NeutrinoMessages::EVT_POPUP; + } + else if (!(hh->ParamList["nmsg"].empty())) + { + message = hh->ParamList["nmsg"]; + event = NeutrinoMessages::EVT_EXTMSG; + } + else + { + hh->SendError(); + return; + } + + if (event != 0) + { + message=decodeString(message); + NeutrinoAPI->EventServer->sendEvent(event, CEventServer::INITID_HTTPD, (void *) message.c_str(), message.length() + 1); + hh->SendOk(); + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::InfoCGI(CyhookHandler *hh) +{ + if (hh->ParamList.empty()) + hh->Write("Neutrino\n"); + else + { + if (hh->ParamList["1"] == "streaminfo") // print streaminfo + SendStreamInfo(hh); + else if (hh->ParamList["1"] == "version") // send version file + hh->SendFile("/.version"); + else if (hh->ParamList["1"] == "httpdversion") // print httpd version typ (only ffor comptibility) + hh->Write("3"); + else if (hh->ParamList["1"] == "nhttpd_version")// print nhttpd version + hh->printf("%s\n", HTTPD_VERSION); + else + hh->SendError(); + } +} +//----------------------------------------------------------------------------- +void CControlAPI::ShutdownCGI(CyhookHandler *hh) +{ + if (hh->ParamList.empty()) + { + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::SHUTDOWN, CEventServer::INITID_HTTPD); + hh->SendOk(); + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::RebootCGI(CyhookHandler *hh) +{ + FILE *f = fopen("/tmp/.reboot", "w"); + fclose(f); + return ShutdownCGI(hh); +} + +//----------------------------------------------------------------------------- +int CControlAPI::rc_send(int ev, unsigned int code, unsigned int value) +{ + struct input_event iev; + iev.type=EV_KEY; + iev.code=code; + iev.value=value; + return write(ev,&iev,sizeof(iev)); +} + +//----------------------------------------------------------------------------- +// security: use const char-Pointers +struct key { + const char *name; + const int code; +}; + +#ifndef KEY_TOPLEFT +#define KEY_TOPLEFT 0x1a2 +#endif + +#ifndef KEY_TOPRIGHT +#define KEY_TOPRIGHT 0x1a3 +#endif + +#ifndef KEY_BOTTOMLEFT +#define KEY_BOTTOMLEFT 0x1a4 +#endif + +#ifndef KEY_BOTTOMRIGHT +#define KEY_BOTTOMRIGHT 0x1a5 +#endif + +static const struct key keynames[] = { + {"KEY_POWER", KEY_POWER}, + {"KEY_MUTE", KEY_MUTE}, + {"KEY_1", KEY_1}, + {"KEY_2", KEY_2}, + {"KEY_3", KEY_3}, + {"KEY_4", KEY_4}, + {"KEY_5", KEY_5}, + {"KEY_6", KEY_6}, + {"KEY_7", KEY_7}, + {"KEY_8", KEY_8}, + {"KEY_9", KEY_9}, + {"KEY_0", KEY_0}, + {"KEY_INFO", KEY_INFO}, + {"KEY_MODE", KEY_MODE}, + {"KEY_SETUP", KEY_MENU}, + {"KEY_EPG", KEY_EPG}, + {"KEY_FAVORITES", KEY_FAVORITES}, + {"KEY_HOME", KEY_EXIT}, + {"KEY_UP", KEY_UP}, + {"KEY_LEFT", KEY_LEFT}, + {"KEY_OK", KEY_OK}, + {"KEY_RIGHT", KEY_RIGHT}, + {"KEY_DOWN", KEY_DOWN}, + {"KEY_VOLUMEUP", KEY_VOLUMEUP}, + {"KEY_VOLUMEDOWN", KEY_VOLUMEDOWN}, + {"KEY_PAGEUP", KEY_PAGEUP}, + {"KEY_PAGEDOWN", KEY_PAGEDOWN}, + {"KEY_TV", KEY_TV}, + {"KEY_TEXT", KEY_TEXT}, + {"KEY_RADIO", KEY_RADIO}, + {"KEY_RED", KEY_RED}, + {"KEY_GREEN", KEY_GREEN}, + {"KEY_YELLOW", KEY_YELLOW}, + {"KEY_BLUE", KEY_BLUE}, + {"KEY_SAT", KEY_SAT}, + {"KEY_HELP", KEY_HELP}, + {"KEY_NEXT", KEY_NEXT}, + {"KEY_PREVIOUS", KEY_PREVIOUS}, + {"KEY_TIME", KEY_TIME}, + {"KEY_AUDIO", KEY_AUDIO}, + {"KEY_REWIND", KEY_REWIND}, + {"KEY_FORWARD", KEY_FORWARD}, + {"KEY_PAUSE", KEY_PAUSE}, + {"KEY_RECORD", KEY_RECORD}, + {"KEY_STOP", KEY_STOP}, + {"KEY_PLAY", KEY_PLAY} +}; + +// The code here is based on rcsim. Thx Carjay! +void CControlAPI::RCEmCGI(CyhookHandler *hh) +{ + if (hh->ParamList.empty()) { + hh->SendError(); + return; + } + std::string keyname = hh->ParamList["1"]; + int sendcode = -1; + for (unsigned int i = 0; sendcode == -1 && i < sizeof(keynames)/sizeof(key); i++) { + if (!strcmp(keyname.c_str(), keynames[i].name)) + sendcode = keynames[i].code; + } + + if (sendcode == -1) { + printf("[nhttpd] Key %s not found\n", keyname.c_str()); + hh->SendError(); + return; + } + unsigned int repeat = 1; + unsigned int delay = 250; + if (hh->ParamList["delay"] != "") + delay = atoi(hh->ParamList["delay"].c_str()); + if (hh->ParamList["duration"] != "") + repeat = atoi(hh->ParamList["duration"].c_str())*1000/delay; + if (hh->ParamList["repeat"] != "") + repeat = atoi(hh->ParamList["repeat"].c_str()); + + int evd = open(EVENTDEV, O_RDWR); + if (evd < 0) { + hh->SendError(); + perror("opening event0 failed"); + return; + } + if (rc_send(evd, sendcode, KEY_PRESSED) < 0){ + perror("writing 'KEY_PRESSED' event failed"); + hh->SendError(); + close(evd); + return; + } + if (rc_send(evd, sendcode, KEY_RELEASED)<0){ + perror("writing 'KEY_RELEASED' event failed"); + close(evd); + hh->SendError(); + return; + } + close(evd); + hh->SendOk(); +} +//----------------------------------------------------------------------------- +void CControlAPI::VideoFormatCGI(CyhookHandler *hh) +{ +// FIXME: not implemented + hh->SendOk(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::VideoOutputCGI(CyhookHandler *hh) +{ +// FIXME: not implemented + hh->SendOk(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::VCROutputCGI(CyhookHandler *hh) +{ +// FIXME: not implemented + hh->SendOk(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::ScartModeCGI(CyhookHandler *hh) +{ +// FIXME: not implemented + hh->SendOk(); +} + +//------------------------------------------------------------------------- +void CControlAPI::VolumeCGI(CyhookHandler *hh) +{ + if (hh->ParamList.empty()) {//without param: show actual volumen + unsigned int volume; + NeutrinoAPI->Zapit->getVolume(&volume, &volume); + hh->printf("%d", volume); + } + else if (hh->ParamList["1"].compare("mute") == 0) + { + NeutrinoAPI->Zapit->muteAudio(true); + hh->SendOk(); + } + else if (hh->ParamList["1"].compare("unmute") == 0) + { + NeutrinoAPI->Zapit->muteAudio(false); + hh->SendOk(); + } +#if 0 //FIXME + + else if (hh->ParamList["1"].compare("status") == 0) { // Mute status + hh->Write("1"); //FIXME coolstream implemented? + } +#endif + else if(hh->ParamList["1"]!="") { //set volume + char vol = atol( hh->ParamList["1"].c_str() ); + NeutrinoAPI->Zapit->setVolume(vol,vol); + hh->SendOk(); + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::ChannellistCGI(CyhookHandler *hh) +{ + SendChannelList(hh); +} + +//----------------------------------------------------------------------------- +void CControlAPI::GetBouquetCGI(CyhookHandler *hh) +{ + if (!(hh->ParamList.empty())) + { + int mode = CZapitClient::MODE_CURRENT; + + if (!(hh->ParamList["mode"].empty())) + { + if (hh->ParamList["mode"].compare("TV") == 0) + mode = CZapitClient::MODE_TV; + if (hh->ParamList["mode"].compare("RADIO") == 0) + mode = CZapitClient::MODE_RADIO; + } + + // Get Bouquet Number. First matching current channel + if (hh->ParamList["1"] == "actual") + { + int actual=0; + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) { + if(g_bouquetManager->existsChannelInBouquet(i, live_channel_id)) { + actual=i+1; + break; + } + } + + hh->printf("%d",actual); + } + else if (!(hh->ParamList["xml"].empty())) + { + hh->WriteLn(""); + hh->WriteLn(""); + hh->printf("\n\t%s\n\n",hh->ParamList["bouquet"].c_str()); + + ZapitChannelList channels; + int BouquetNr = atoi(hh->ParamList["bouquet"].c_str()); + if(BouquetNr > 0) + BouquetNr--; + channels = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->Bouquets[BouquetNr]->radioChannels : g_bouquetManager->Bouquets[BouquetNr]->tvChannels; + int num = 1 + (mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr) : g_bouquetManager->tvChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr)) ; + for(int j = 0; j < (int) channels.size(); j++) { + CZapitChannel * channel = channels[j]; + hh->printf("\n\t%u\n\t" + PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + "\n\t\n\n", + num + j, + channel->channel_id, + channel->getName().c_str()); + } + hh->WriteLn(""); + } + else + { +//FIXME - check for a better way + ZapitChannelList channels; + int BouquetNr = atoi(hh->ParamList["bouquet"].c_str()); + if(BouquetNr > 0) + BouquetNr--; + channels = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->Bouquets[BouquetNr]->radioChannels : g_bouquetManager->Bouquets[BouquetNr]->tvChannels; + int num = 1 + (mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr) : g_bouquetManager->tvChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr)) ; + for(int j = 0; j < (int) channels.size(); j++) { + CZapitChannel * channel = channels[j]; + hh->printf("%u " + PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + " %s\n", + num + j, + channel->channel_id, + channel->getName().c_str()); + } + } + } + else + hh->WriteLn("error"); +} + +//----------------------------------------------------------------------------- +void CControlAPI::GetBouquetsCGI(CyhookHandler *hh) +{ + for (unsigned int i = 0; i < NeutrinoAPI->BouquetList.size();i++) + hh->printf("%u %s\n", (NeutrinoAPI->BouquetList[i].bouquet_nr) + 1, NeutrinoAPI->BouquetList[i].name); +} + +//----------------------------------------------------------------------------- +void CControlAPI::EpgCGI(CyhookHandler *hh) +{ + //hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); + if (hh->ParamList.empty()) + { + hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); + CChannelEvent *event; + NeutrinoAPI->GetChannelEvents(); + + int mode = NeutrinoAPI->Zapit->getMode(); + CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin(); + for (; !(cit.EndOfChannels()); cit++) { + CZapitChannel * channel = *cit; + event = NeutrinoAPI->ChannelListEvents[channel->channel_id]; + if(event) + hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + " %llu %s\n", + channel->channel_id, + event->eventID, + event->description.c_str()); + } + } + else if (hh->ParamList["xml"].empty()) + { + hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); + if (hh->ParamList["1"] == "ext") + { + CChannelEvent *event; + NeutrinoAPI->GetChannelEvents(); + int mode = NeutrinoAPI->Zapit->getMode(); + CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin(); + for (; !(cit.EndOfChannels()); cit++) { + CZapitChannel * channel = *cit; + event = NeutrinoAPI->ChannelListEvents[channel->channel_id]; + if(event) + hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + " %ld %u %llu %s\n", + channel->channel_id, + event->startTime, + event->duration, + event->eventID, + event->description.c_str()); + } + } + else if (hh->ParamList["eventid"] != "") + { + //special epg query + uint64_t epgid; + sscanf( hh->ParamList["eventid"].c_str(), "%llu", &epgid); + CShortEPGData epg; + //if (NeutrinoAPI->Sectionsd->getEPGidShort(epgid,&epg)) + if (sectionsd_getEPGidShort(epgid,&epg)) + { + hh->WriteLn(epg.title); + hh->WriteLn(epg.info1); + hh->WriteLn(epg.info2); + } + } + else if (hh->ParamList["eventid2fsk"] != "") + { + if (hh->ParamList["starttime"] != "") + { + uint64_t epgid; + time_t starttime; + sscanf( hh->ParamList["fskid"].c_str(), "%llu", &epgid); + sscanf( hh->ParamList["starttime"].c_str(), "%lu", &starttime); + CEPGData longepg; + if(sectionsd_getEPGid(epgid, starttime, &longepg)) + { + hh->printf("%u\n", longepg.fsk); + return; + } + } + hh->SendError(); + } + else if (!(hh->ParamList["id"].empty())) + { + t_channel_id channel_id; + sscanf(hh->ParamList["id"].c_str(), + SCANF_CHANNEL_ID_TYPE, + &channel_id); + sectionsd_getEventsServiceKey(channel_id&0xFFFFFFFFFFFFULL, NeutrinoAPI->eList); + CChannelEventList::iterator eventIterator; + for (eventIterator = NeutrinoAPI->eList.begin(); eventIterator != NeutrinoAPI->eList.end(); eventIterator++) + { + CShortEPGData epg; + if (sectionsd_getEPGidShort(eventIterator->eventID,&epg)) + { + hh->printf("%llu %ld %d\n", eventIterator->eventID, eventIterator->startTime, eventIterator->duration); + hh->printf("%s\n",epg.title.c_str()); + hh->printf("%s\n",epg.info1.c_str()); + hh->printf("%s\n\n",epg.info2.c_str()); + } + } + } + else + { + //eventlist for a chan + t_channel_id channel_id; + sscanf(hh->ParamList["1"].c_str(), + SCANF_CHANNEL_ID_TYPE, + &channel_id); + SendEventList(hh, channel_id); + } + } + // xml=true&channelid=|channelname=[&details=true][&max=][&stoptime=] + // details=true : Show EPG Info1 and info2 + // stoptime : show only items until stoptime reached + else if (!(hh->ParamList["xml"].empty())) + { + hh->SetHeader(HTTP_OK, "text/xml; charset=UTF-8"); + t_channel_id channel_id = (t_channel_id)-1; + + if (!(hh->ParamList["channelid"].empty())) + { + sscanf(hh->ParamList["channelid"].c_str(), + SCANF_CHANNEL_ID_TYPE, + &channel_id); + } + else if (!(hh->ParamList["channelname"].empty())) + { + channel_id = NeutrinoAPI->ChannelNameToChannelId( hh->ParamList["channelname"].c_str() ); + } + if(channel_id != (t_channel_id)-1) + { + hh->WriteLn(""); + hh->WriteLn(""); + sectionsd_getEventsServiceKey(channel_id&0xFFFFFFFFFFFFULL, NeutrinoAPI->eList); + hh->printf("" + PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + "\r\n", channel_id); + hh->printf("\r\n", NeutrinoAPI->GetServiceName(channel_id).c_str()); + + // max = maximal output items + int max = -1; + if (!(hh->ParamList["max"].empty())) + max = atoi( hh->ParamList["max"].c_str() ); + + // stoptime = maximal output items until starttime >= stoptime + long stoptime = -1; + if (!(hh->ParamList["stoptime"].empty())) + stoptime = atol( hh->ParamList["stoptime"].c_str() ); + int i=0; + CChannelEventList::iterator eventIterator; + for (eventIterator = NeutrinoAPI->eList.begin(); eventIterator != NeutrinoAPI->eList.end(); eventIterator++, i++) + { + if( (max != -1 && i >= max) || ( stoptime != -1 && eventIterator->startTime >= stoptime)) + break; + hh->WriteLn(""); + hh->printf("\t%llu\r\n", eventIterator->eventID); + hh->printf("\t%llx\r\n", eventIterator->eventID); + hh->printf("\t%ld\r\n", eventIterator->startTime); + char zbuffer[25] = {0}; + struct tm *mtime = localtime(&eventIterator->startTime); + strftime(zbuffer,20,"%H:%M",mtime); + hh->printf("\t%s\r\n", zbuffer); + bzero(zbuffer,25); + strftime(zbuffer,20,"%d.%m.%Y",mtime); + hh->printf("\t%s\r\n", zbuffer); + hh->printf("\t%ld\r\n", eventIterator->startTime+eventIterator->duration); + long _stoptime = eventIterator->startTime+eventIterator->duration; + mtime = localtime(&_stoptime); + strftime(zbuffer,20,"%H:%M",mtime); + hh->printf("\t%s\r\n", zbuffer); + hh->printf("\t%d\r\n", (int)(eventIterator->duration/60)); + hh->printf("\t\r\n", eventIterator->description.c_str()); + + if (!(hh->ParamList["details"].empty())) + { + CShortEPGData epg; + if (sectionsd_getEPGidShort(eventIterator->eventID,&epg)) + { + hh->printf("\t\r\n",epg.info1.c_str()); + hh->printf("\t\r\n",epg.info2.c_str()); + } + } + hh->WriteLn(""); + } + hh->WriteLn(""); + } + } +} + +//----------------------------------------------------------------------------- +void CControlAPI::VersionCGI(CyhookHandler *hh) +{ + hh->SendFile("/.version"); +} + +//----------------------------------------------------------------------------- +void CControlAPI::ZaptoCGI(CyhookHandler *hh) +{ + if (hh->ParamList.empty()) + { + hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + "\n", + NeutrinoAPI->Zapit->getCurrentServiceID()); + return; + } + else + { + if (hh->ParamList["1"] == "getpids") // getpids ! + SendcurrentVAPid(hh); + else if (hh->ParamList["1"] == "getallpids") // getpids ! + SendAllCurrentVAPid(hh); + else if (hh->ParamList["1"] == "stopplayback") + { + NeutrinoAPI->Zapit->stopPlayBack(); + NeutrinoAPI->Sectionsd->setPauseScanning(true); + hh->SendOk(); + } + else if (hh->ParamList["1"] == "startplayback") + { + NeutrinoAPI->Zapit->startPlayBack(); + NeutrinoAPI->Sectionsd->setPauseScanning(false); + dprintf("start playback requested..\n"); + hh->SendOk(); + } + else if (hh->ParamList["1"] == "statusplayback") + hh->Write((char *) (NeutrinoAPI->Zapit->isPlayBackActive() ? "1" : "0")); + else if (hh->ParamList["1"] == "stopsectionsd") + { + NeutrinoAPI->Sectionsd->setPauseScanning(true); + hh->SendOk(); + } + else if (hh->ParamList["1"] == "startsectionsd") + { + NeutrinoAPI->Sectionsd->setPauseScanning(false); + hh->SendOk(); + } + else if (hh->ParamList["1"] == "statussectionsd") + hh->Write((char *) (NeutrinoAPI->Sectionsd->getIsScanningActive() ? "1" : "0")); + else if (hh->ParamList["1"] == "getallsubchannels") + { + t_channel_id current_channel = NeutrinoAPI->Zapit->getCurrentServiceID(); + CSectionsdClient::LinkageDescriptorList desc; + CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo; + sectionsd_getCurrentNextServiceKey(current_channel&0xFFFFFFFFFFFFULL, currentNextInfo); + if (sectionsd_getLinkageDescriptorsUniqueKey(currentNextInfo.current_uniqueKey,desc)) + { + for(unsigned int i=0;i< desc.size();i++) + { + t_channel_id sub_channel_id = + CREATE_CHANNEL_ID_FROM_SERVICE_ORIGINALNETWORK_TRANSPORTSTREAM_ID( + desc[i].serviceId, desc[i].originalNetworkId, desc[i].transportStreamId); + hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + " %s\n", + sub_channel_id, + (desc[i].name).c_str()); + } + } + } + else if (hh->ParamList["name"] != "") + { + t_channel_id channel_id; + channel_id = NeutrinoAPI->ChannelNameToChannelId(hh->ParamList["name"]); + if(channel_id != (t_channel_id)-1) + { + NeutrinoAPI->ZapToChannelId(channel_id); + hh->SendOk(); + } + else + hh->SendError(); + } + else + { + NeutrinoAPI->ZapTo(hh->ParamList["1"].c_str()); + + hh->SendOk(); + } + return; + } + hh->SendError(); + return; +} + +//----------------------------------------------------------------------------- +void CControlAPI::StartPluginCGI(CyhookHandler *hh) +{ + std::string pluginname; + if (!(hh->ParamList.empty())) + { + if (hh->ParamList["name"] != "") + { + pluginname = hh->ParamList["name"]; + pluginname=decodeString(pluginname); + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::EVT_START_PLUGIN, + CEventServer::INITID_HTTPD, + (void *) pluginname.c_str(), + pluginname.length() + 1); + + hh->SendOk(); + } + else + hh->SendError(); + + } + else + hh->SendError(); +} + +//----------------------------------------------------------------------------- +void CControlAPI::LCDAction(CyhookHandler *hh) +{ + hh->SendOk(); +} + +//------------------------------------------------------------------------- +// Send functions (for ExecuteCGI) +//------------------------------------------------------------------------- +void CControlAPI::SendEventList(CyhookHandler *hh, t_channel_id channel_id) +{ + int pos; + sectionsd_getEventsServiceKey(channel_id&0xFFFFFFFFFFFFULL, NeutrinoAPI->eList); + CChannelEventList::iterator eventIterator; + + for (eventIterator = NeutrinoAPI->eList.begin(); eventIterator != NeutrinoAPI->eList.end(); eventIterator++, pos++) + hh->printf("%llu %ld %d %s\n", eventIterator->eventID, eventIterator->startTime, eventIterator->duration, eventIterator->description.c_str()); +} + +//----------------------------------------------------------------------------- +void CControlAPI::SendChannelList(CyhookHandler *hh) +{ + int mode = NeutrinoAPI->Zapit->getMode(); + hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8"); + CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin(); + for (; !(cit.EndOfChannels()); cit++) { + CZapitChannel * channel = *cit; + hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS + " %s\n", + channel->channel_id, + channel->getName().c_str()); + } +} + +//----------------------------------------------------------------------------- +void CControlAPI::SendStreamInfo(CyhookHandler *hh) +{ + + int bitInfo[10]; + NeutrinoAPI->GetStreamInfo(bitInfo); + hh->printf("%d\n%d\n", bitInfo[0], bitInfo[1] ); //Resolution x y + hh->printf("%d\n", bitInfo[4]*50); //Bitrate bit/sec + + switch (bitInfo[2]) //format + { + case 2: hh->Write("4:3\n"); break; + case 3: hh->Write("16:9\n"); break; + case 4: hh->Write("2.21:1\n"); break; + default: hh->Write("unknown\n"); break; + } + switch (bitInfo[3]) //fps + { + case 3: hh->Write("25\n"); break; + case 6: hh->Write("50\n"); break; + default: hh->Write("unknown\n"); + } + hh->WriteLn(NeutrinoAPI->audiotype_names[bitInfo[6]]); +} + +//----------------------------------------------------------------------------- +void CControlAPI::SendcurrentVAPid(CyhookHandler *hh) +{ + CZapitClient::responseGetPIDs pids; + pids.PIDs.vpid=0; + NeutrinoAPI->Zapit->getPIDS(pids); + + hh->printf("%u\n", pids.PIDs.vpid); + if(!pids.APIDs.empty()) + hh->printf("%u\n", pids.APIDs[0].pid); + else + hh->printf("0\n"); +} + +//----------------------------------------------------------------------------- +void CControlAPI::SendAllCurrentVAPid(CyhookHandler *hh) +{ + static bool init_iso=true; + if(init_iso) + { + if(_initialize_iso639_map()) + init_iso=false; + } + bool eit_not_ok=true; + CZapitClient::responseGetPIDs pids; + + CSectionsdClient::ComponentTagList tags; + pids.PIDs.vpid=0; + NeutrinoAPI->Zapit->getPIDS(pids); + + hh->printf("%05u\n", pids.PIDs.vpid); + + t_channel_id current_channel = NeutrinoAPI->Zapit->getCurrentServiceID(); + CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo; + sectionsd_getCurrentNextServiceKey(current_channel&0xFFFFFFFFFFFFULL, currentNextInfo); + if (sectionsd_getComponentTagsUniqueKey(currentNextInfo.current_uniqueKey,tags)) + { + for (unsigned int i=0; i< tags.size(); i++) + { + for (unsigned short j=0; j< pids.APIDs.size(); j++) + { + if ( pids.APIDs[j].component_tag == tags[i].componentTag ) + { + if(!tags[i].component.empty()) + { + if(!(isalnum(tags[i].component[0]))) + tags[i].component=tags[i].component.substr(1,tags[i].component.length()-1); + hh->printf("%05u %s\n",pids.APIDs[j].pid,tags[i].component.c_str()); + } + else + { + if(!(init_iso)) + { + strcpy( pids.APIDs[j].desc, _getISO639Description( pids.APIDs[j].desc ) ); + } + hh->printf("%05u %s %s\n",pids.APIDs[j].pid,pids.APIDs[j].desc,pids.APIDs[j].is_ac3 ? " (AC3)": " "); + } + eit_not_ok=false; + break; + } + } + } + } + if(eit_not_ok) + { + unsigned short i = 0; + for (CZapitClient::APIDList::iterator it = pids.APIDs.begin(); it!=pids.APIDs.end(); it++) + { + if(!(init_iso)) + { + strcpy( pids.APIDs[i].desc, _getISO639Description( pids.APIDs[i].desc ) ); + } + hh->printf("%05u %s %s\n",it->pid,pids.APIDs[i].desc,pids.APIDs[i].is_ac3 ? " (AC3)": " "); + i++; + } + } + + if(pids.APIDs.empty()) + hh->printf("0\n"); // shouldnt happen, but print at least one apid + if(pids.PIDs.vtxtpid) + hh->printf("%05u vtxt\n",pids.PIDs.vtxtpid); + if (pids.PIDs.pmtpid) + hh->printf("%05u pmt\n",pids.PIDs.pmtpid); + +} +//----------------------------------------------------------------------------- +void CControlAPI::SendTimers(CyhookHandler *hh) +{ + CTimerd::TimerList timerlist; // List of bouquets + bool send_id = false; + + if (hh->ParamList["format"] == "id") + send_id = true; + + timerlist.clear(); + NeutrinoAPI->Timerd->getTimerList(timerlist); + + CTimerd::TimerList::iterator timer = timerlist.begin(); + + for(; timer != timerlist.end();timer++) + { + // Add Data + char zAddData[22+1] = { 0 }; + if (send_id) + { + zAddData[0] = '0'; + zAddData[1] = 0; + } + + switch(timer->eventType) { + case CTimerd::TIMER_NEXTPROGRAM: + case CTimerd::TIMER_ZAPTO: + case CTimerd::TIMER_RECORD: + if (!send_id) + { + strncpy(zAddData, NeutrinoAPI->GetServiceName(timer->channel_id).c_str(), 22); + if (zAddData[0] == 0) + strcpy(zAddData, NeutrinoAPI->Zapit->isChannelTVChannel(timer->channel_id) ? "Unbekannter TV-Kanal" : "Unbekannter Radiokanal"); + } + else + sprintf(zAddData, PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, timer->channel_id); + + zAddData[22]=0; + + break; + + case CTimerd::TIMER_STANDBY: + if (!send_id) + sprintf(zAddData,"Standby: %s",(timer->standby_on ? "ON" : "OFF")); + break; + + case CTimerd::TIMER_REMIND : + if (!send_id) + strncpy(zAddData, timer->message, 22); + zAddData[22]=0; + break; + + default: + break; + } + + hh->printf("%d %d %d %d %d %d %d %s\n", + timer->eventID, + (int)timer->eventType, + (int)timer->eventRepeat, + (int)timer->repeatCount, + (int)timer->announceTime, + (int)timer->alarmTime, + (int)timer->stopTime, + zAddData); + } +} + +//----------------------------------------------------------------------------- +// yweb : Extentions +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Dispatcher +//----------------------------------------------------------------------------- +void CControlAPI::YWebCGI(CyhookHandler *hh) +{ + bool status=true; + int para; + if (hh->ParamList["video_stream_pids"] != "") + { + para=0; + sscanf( hh->ParamList["video_stream_pids"].c_str(), "%d", ¶); + YWeb_SendVideoStreamingPids(hh, para); + } + else if (hh->ParamList["1"] == "radio_stream_pid") + YWeb_SendRadioStreamingPid(hh); + + if(!status) + hh->SendError(); +} + +//----------------------------------------------------------------------------- +// Get Streaming Pids 0x$pmt,0x$vpid,0x$apid with apid_no is the Number of Audio-Pid +//----------------------------------------------------------------------------- +void CControlAPI::YWeb_SendVideoStreamingPids(CyhookHandler *hh, int apid_no) +{ + CZapitClient::responseGetPIDs pids; + int apid=0,apid_idx=0; + pids.PIDs.vpid=0; + NeutrinoAPI->Zapit->getPIDS(pids); + + if( apid_no < (int)pids.APIDs.size()) + apid_idx=apid_no; + if(!pids.APIDs.empty()) + apid = pids.APIDs[apid_idx].pid; + if(hh->ParamList["no_commas"] != "") + hh->printf("0x%04x 0x%04x 0x%04x",pids.PIDs.pmtpid,pids.PIDs.vpid,apid); + else + hh->printf("0x%04x,0x%04x,0x%04x",pids.PIDs.pmtpid,pids.PIDs.vpid,apid); +} + +//----------------------------------------------------------------------------- +// Get Streaming Pids 0x$pmt,0x$vpid,0x$apid with apid_no is the Number of Audio-Pid +//----------------------------------------------------------------------------- +void CControlAPI::YWeb_SendRadioStreamingPid(CyhookHandler *hh) +{ + CZapitClient::responseGetPIDs pids; + int apid=0; + NeutrinoAPI->Zapit->getPIDS(pids); + + if(!pids.APIDs.empty()) + apid = pids.APIDs[0].pid; + hh->printf("0x%04x",apid); +} + +//----------------------------------------------------------------------------- +std::string CControlAPI::YexecuteScript(CyhookHandler *, std::string cmd) +{ + std::string script, para, result; + bool found = false; + + // split script and parameters + int pos; + if ((pos = cmd.find_first_of(" ")) > 0) + { + script = cmd.substr(0, pos); + para = cmd.substr(pos+1,cmd.length() - (pos+1)); // snip + } + else + script=cmd; + // get file + std::string fullfilename; + script += ".sh"; //add script extention + char cwd[255]; + getcwd(cwd, 254); + + for (unsigned int i=0;iParamList["update"]="1"; + doNewTimer(hh); +} +//------------------------------------------------------------------------- +void CControlAPI::doNewTimer(CyhookHandler *hh) +{ + time_t announceTimeT = 0, + stopTimeT = 0, + alarmTimeT = 0, + tnull = 0; + unsigned int repCount = 0; + int alHour=0; + + // if alarm given then in parameters im time_t format + if(hh->ParamList["alarm"] != "") + { + alarmTimeT = atoi(hh->ParamList["alarm"].c_str()); + if(hh->ParamList["stop"] != "") + stopTimeT = atoi(hh->ParamList["stop"].c_str()); + if(hh->ParamList["announce"] != "") + announceTimeT = atoi(hh->ParamList["announce"].c_str()); + else + announceTimeT = alarmTimeT; + } + else if(hh->ParamList["alDate"] != "") //given formatted + { + // Alarm Date - Format exact! DD.MM.YYYY + tnull = time(NULL); + struct tm *alarmTime=localtime(&tnull); + alarmTime->tm_sec = 0; + if(sscanf(hh->ParamList["alDate"].c_str(),"%2d.%2d.%4d",&(alarmTime->tm_mday), &(alarmTime->tm_mon), &(alarmTime->tm_year)) == 3) + { + alarmTime->tm_mon -= 1; + alarmTime->tm_year -= 1900; + } + + // Alarm Time - Format exact! HH:MM + if(hh->ParamList["alTime"] != "") + sscanf(hh->ParamList["alTime"].c_str(),"%2d.%2d",&(alarmTime->tm_hour), &(alarmTime->tm_min)); + alHour = alarmTime->tm_hour; + correctTime(alarmTime); + alarmTimeT = mktime(alarmTime); + announceTimeT = alarmTimeT; + struct tm *stopTime = localtime(&alarmTimeT); + stopTime->tm_sec = 0; + // Stop Time - Format exact! HH:MM + if(hh->ParamList["stTime"] != "") + sscanf(hh->ParamList["stTime"].c_str(),"%2d.%2d",&(stopTime->tm_hour), &(stopTime->tm_min)); + + // Stop Date - Format exact! DD.MM.YYYY + if(hh->ParamList["stDate"] != "") + if(sscanf(hh->ParamList["stDate"].c_str(),"%2d.%2d.%4d",&(stopTime->tm_mday), &(stopTime->tm_mon), &(stopTime->tm_year)) == 3) + { + stopTime->tm_mon -= 1; + stopTime->tm_year -= 1900; + } + correctTime(stopTime); + stopTimeT = mktime(stopTime); + if(hh->ParamList["stDate"] == "" && alHour > stopTime->tm_hour) + stopTimeT += 24* 60 * 60; // add 1 Day + } + else // alarm/stop time given in pieces + { + // alarm time + time_t now = time(NULL); + struct tm *alarmTime=localtime(&now); + if(hh->ParamList["ad"] != "") + alarmTime->tm_mday = atoi(hh->ParamList["ad"].c_str()); + if(hh->ParamList["amo"] != "") + alarmTime->tm_mon = atoi(hh->ParamList["amo"].c_str())-1; + if(hh->ParamList["ay"] != "") + alarmTime->tm_year = atoi(hh->ParamList["ay"].c_str())-1900; + if(hh->ParamList["ah"] != "") + alarmTime->tm_hour = atoi(hh->ParamList["ah"].c_str()); + if(hh->ParamList["ami"] != "") + alarmTime->tm_min = atoi(hh->ParamList["ami"].c_str()); + alarmTime->tm_sec = 0; + correctTime(alarmTime); + alarmTimeT = mktime(alarmTime); + announceTimeT = alarmTimeT; + + // stop time + struct tm *stopTime = alarmTime; + if(hh->ParamList["sd"] != "") + stopTime->tm_mday = atoi(hh->ParamList["sd"].c_str()); + if(hh->ParamList["smo"] != "") + stopTime->tm_mon = atoi(hh->ParamList["smo"].c_str())-1; + if(hh->ParamList["sy"] != "") + stopTime->tm_year = atoi(hh->ParamList["sy"].c_str())-1900; + if(hh->ParamList["sh"] != "") + stopTime->tm_hour = atoi(hh->ParamList["sh"].c_str()); + if(hh->ParamList["smi"] != "") + stopTime->tm_min = atoi(hh->ParamList["smi"].c_str()); + stopTime->tm_sec = 0; + correctTime(stopTime); + stopTimeT = mktime(stopTime); + } + + if(announceTimeT != 0) + announceTimeT -= 60; + + CTimerd::CTimerEventTypes type; + if(hh->ParamList["type"] != "") + type = (CTimerd::CTimerEventTypes) atoi(hh->ParamList["type"].c_str()); + else // default is: record + type = CTimerd::TIMER_RECORD; + + // repeat + if(hh->ParamList["repcount"] != "") + { + repCount = atoi(hh->ParamList["repcount"].c_str()); + } + CTimerd::CTimerEventRepeat rep; + if(hh->ParamList["rep"] != "") + rep = (CTimerd::CTimerEventRepeat) atoi(hh->ParamList["rep"].c_str()); + else // default: no repeat + rep = (CTimerd::CTimerEventRepeat)0; + + if(((int)rep) >= ((int)CTimerd::TIMERREPEAT_WEEKDAYS) && hh->ParamList["wd"] != "") + NeutrinoAPI->Timerd->getWeekdaysFromStr(&rep, hh->ParamList["wd"].c_str()); +#if 0 //FIXME + // apids + bool changeApids=false; + unsigned char apids=0; + if(hh->ParamList["apcf"] == "on") + { + changeApids=true; + apids=0; + } + else + { + if(hh->ParamList["apst"] == "on") + { + changeApids=true; + apids |= TIMERD_APIDS_STD; + } + if(hh->ParamList["apal"] == "on") + { + changeApids=true; + apids |= TIMERD_APIDS_ALT; + } + if(hh->ParamList["apac"] == "on") + { + changeApids=true; + apids |= TIMERD_APIDS_AC3; + } + } +#endif + CTimerd::RecordingInfo recinfo; + CTimerd::EventInfo eventinfo; + eventinfo.epgID = 0; + eventinfo.epg_starttime = 0; + eventinfo.apids = TIMERD_APIDS_CONF; + eventinfo.recordingSafety = (hh->ParamList["rs"] == "1"); + + // channel by Id or name + if(hh->ParamList["channel_id"] != "") + sscanf(hh->ParamList["channel_id"].c_str(), + SCANF_CHANNEL_ID_TYPE, + &eventinfo.channel_id); + else + eventinfo.channel_id = NeutrinoAPI->ChannelNameToChannelId(hh->ParamList["channel_name"]); + + std::string _rec_dir = hh->ParamList["rec_dir"]; + void *data=NULL; + if(type == CTimerd::TIMER_RECORD) + announceTimeT-=120; + if(type == CTimerd::TIMER_STANDBY) + { + bool standby_on = (hh->ParamList["sbon"]=="1"); + data=&standby_on; + } + else if(type==CTimerd::TIMER_NEXTPROGRAM || type==CTimerd::TIMER_ZAPTO) + data= &eventinfo; + else if (type==CTimerd::TIMER_RECORD) + { + if(_rec_dir == "") + { + // get Default Recordingdir + CConfigFile *Config = new CConfigFile(','); + Config->loadConfig(NEUTRINO_CONFIGFILE); + _rec_dir = Config->getString("network_nfs_recordingdir", "/mnt/filme"); + delete Config;//Memory leak: Config + } +#if 0 //FIXME? + if(changeApids) + eventinfo.apids = apids; +#endif + recinfo = eventinfo; + strncpy(recinfo.recordingDir, _rec_dir.c_str(), RECORD_DIR_MAXLEN-1); + data = &recinfo; + } + else if(type==CTimerd::TIMER_REMIND) + { + char msg[REMINDER_MESSAGE_MAXLEN]; + memset(msg, 0, sizeof(msg)); + strncpy(msg, hh->ParamList["msg"].c_str(),REMINDER_MESSAGE_MAXLEN-1); + data=msg; + } + else if(type==CTimerd::TIMER_EXEC_PLUGIN) + { + char msg[EXEC_PLUGIN_NAME_MAXLEN]; + memset(msg, 0, sizeof(msg)); + strncpy(msg, hh->ParamList["PluginName"].c_str(),EXEC_PLUGIN_NAME_MAXLEN-1); + data=msg; + } + // update or add timer + if(hh->ParamList["update"]=="1") + { + if(hh->ParamList["id"] != "") + { + unsigned modyId = atoi(hh->ParamList["id"].c_str()); + NeutrinoAPI->Timerd->removeTimerEvent(modyId); + } + else + { + CTimerd::TimerList timerlist; + timerlist.clear(); + NeutrinoAPI->Timerd->getTimerList(timerlist); + CTimerd::TimerList::iterator timer = timerlist.begin(); + + // Look for Recording Safety Timers too + time_t real_alarmTimeT = alarmTimeT; + if(eventinfo.recordingSafety) + { + int pre,post; + NeutrinoAPI->Timerd->getRecordingSafety(pre,post); + real_alarmTimeT -= pre; + } + + for(; timer != timerlist.end();timer++) + if(timer->alarmTime == real_alarmTimeT) + { + NeutrinoAPI->Timerd->removeTimerEvent(timer->eventID); + break; + } + } + } + NeutrinoAPI->Timerd->addTimerEvent(type,data,announceTimeT,alarmTimeT,stopTimeT,rep,repCount); + hh->SendOk(); +} +//------------------------------------------------------------------------- +void CControlAPI::setBouquetCGI(CyhookHandler *hh) +{ + if (hh->ParamList["selected"] != "") { + int selected = atoi(hh->ParamList["selected"].c_str()); + if(hh->ParamList["action"].compare("hide") == 0) + NeutrinoAPI->Zapit->setBouquetHidden(selected - 1,true); + else if(hh->ParamList["action"].compare("show") == 0) + NeutrinoAPI->Zapit->setBouquetHidden(selected - 1,false); + else if(hh->ParamList["action"].compare("lock") == 0) + NeutrinoAPI->Zapit->setBouquetLock(selected - 1,true); + else if(hh->ParamList["action"].compare("unlock") == 0) + NeutrinoAPI->Zapit->setBouquetLock(selected - 1,false); + hh->SendOk(); + } + else + hh->SendError(); +} +//------------------------------------------------------------------------- +void CControlAPI::saveBouquetCGI(CyhookHandler *hh) +{ + NeutrinoAPI->Zapit->saveBouquets(); + NeutrinoAPI->UpdateBouquets(); + hh->SendOk(); +} +//------------------------------------------------------------------------- +void CControlAPI::moveBouquetCGI(CyhookHandler *hh) +{ + if (hh->ParamList["selected"] != "" && ( + hh->ParamList["action"] == "up" || + hh->ParamList["action"] == "down")) + { + int selected = atoi(hh->ParamList["selected"].c_str()); + if (hh->ParamList["action"] == "up") { + NeutrinoAPI->Zapit->moveBouquet(selected - 1, (selected - 1) - 1); + selected--; + } else { + NeutrinoAPI->Zapit->moveBouquet(selected - 1, (selected + 1) - 1); + selected++; + } + hh->SendOk(); + } + else + hh->SendError(); +} +//------------------------------------------------------------------------- +void CControlAPI::deleteBouquetCGI(CyhookHandler *hh) +{ + int selected = -1; + + if (hh->ParamList["selected"] != "") { + selected = atoi(hh->ParamList["selected"].c_str()); + NeutrinoAPI->Zapit->deleteBouquet(selected - 1); + hh->SendOk(); + } + else + hh->SendError(); +} +//------------------------------------------------------------------------- +void CControlAPI::addBouquetCGI(CyhookHandler *hh) +{ + if (!hh->ParamList["name"].empty()) + { + std::string tmp = hh->ParamList["name"]; + if (NeutrinoAPI->Zapit->existsBouquet(tmp.c_str()) == -1) + { + NeutrinoAPI->Zapit->addBouquet(tmp.c_str()); + hh->SendOk(); + } + else + hh->SendError(); + } +} +//------------------------------------------------------------------------- +void CControlAPI::renameBouquetCGI(CyhookHandler *hh) +{ + if (hh->ParamList["selected"] != "") + { + if (hh->ParamList["nameto"] != "") + { + if (NeutrinoAPI->Zapit->existsBouquet((hh->ParamList["nameto"]).c_str()) == -1) + { + NeutrinoAPI->Zapit->renameBouquet(atoi(hh->ParamList["selected"].c_str()) - 1, hh->ParamList["nameto"].c_str()); + hh->SendOk(); + return; + } + } + } + hh->SendError(); +} +//------------------------------------------------------------------------- +void CControlAPI::changeBouquetCGI(CyhookHandler *hh) +{ + if (!(hh->ParamList["selected"].empty())) + { + int selected = atoi(hh->ParamList["selected"].c_str()); + CZapitClient::BouquetChannelList BChannelList; + NeutrinoAPI->Zapit->getBouquetChannels(selected - 1, BChannelList, CZapitClient::MODE_CURRENT, true); + CZapitClient::BouquetChannelList::iterator channels = BChannelList.begin(); + for(; channels != BChannelList.end();channels++) + { + NeutrinoAPI->Zapit->removeChannelFromBouquet(selected - 1, channels->channel_id); + } + + t_channel_id channel_id; + int delta; + const char * bchannels = hh->ParamList["bchannels"].c_str(); + while (sscanf(bchannels, + SCANF_CHANNEL_ID_TYPE + "%n", + &channel_id, + &delta) > 0) + { + NeutrinoAPI->Zapit->addChannelToBouquet(selected - 1, channel_id); + bchannels += (delta + 1); // skip the separating ',', too + } + + NeutrinoAPI->Zapit->renumChannellist(); + NeutrinoAPI->UpdateBouquets(); + if(hh->ParamList["redirect"] != "") + hh->SendRewrite(hh->ParamList["redirect"]); + else + hh->SendOk(); + } + else + hh->SendError(); +} +//------------------------------------------------------------------------- +void CControlAPI::updateBouquetCGI(CyhookHandler *hh) +{ + NeutrinoAPI->UpdateBouquets(); + hh->SendOk(); +} +//------------------------------------------------------------------------- +// audio_no : (optional) audio channel +// host : (optional) ip of dbox +void CControlAPI::build_live_url(CyhookHandler *hh) +{ + std::string xpids,port,yresult; + int mode = NeutrinoAPI->Zapit->getMode(); + + if ( mode == CZapitClient::MODE_TV) + { + CZapitClient::responseGetPIDs pids; + int apid=0,apid_no=0,apid_idx=0; + pids.PIDs.vpid=0; + + if(hh->ParamList["audio_no"] !="") + apid_no = atoi(hh->ParamList["audio_no"].c_str()); + NeutrinoAPI->Zapit->getPIDS(pids); + + if( apid_no < (int)pids.APIDs.size()) + apid_idx=apid_no; + if(!pids.APIDs.empty()) + apid = pids.APIDs[apid_idx].pid; + xpids = string_printf("0x%04x,0x%04x,0x%04x",pids.PIDs.pmtpid,pids.PIDs.vpid,apid); + } + else if ( mode == CZapitClient::MODE_RADIO) + { + CZapitClient::responseGetPIDs pids; + int apid=0; + + NeutrinoAPI->Zapit->getPIDS(pids); + if(!pids.APIDs.empty()) + apid = pids.APIDs[0].pid; + + //xpids = string_printf("0x%04x",apid); + xpids = string_printf("0x%04x,0x%04x",pids.PIDs.pmtpid,apid); + } + else + hh->SendError(); + // build url + std::string url = ""; + if(hh->ParamList["host"] !="") + url = "http://"+hh->ParamList["host"]; + else + url = "http://"+hh->HeaderList["Host"]; + //url += (mode == CZapitClient::MODE_TV) ? ":31339/0," : ":31338/"; + url += ":31339/0,"; + url += xpids; +printf("Live url: %s\n", url.c_str()); + // response url + if(hh->ParamList["vlc_link"] !="") + { + write_to_file("/tmp/vlc.m3u", url); + hh->SendRedirect("/tmp/vlc.m3u"); + } + else + { + hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8"); + hh->Write(url); + } +} diff --git a/src/nhttpd/tuxboxapi/coolstream/controlapi.h b/src/nhttpd/tuxboxapi/coolstream/controlapi.h new file mode 100644 index 000000000..b31cb02e1 --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/controlapi.h @@ -0,0 +1,114 @@ +//============================================================================= +// NHTTPD +// Neutrino ControlAPI +//============================================================================= +#ifndef __nhttpd_neutrinocontrolapi_hpp__ +#define __nhttpd_neutrinocontrolapi_hpp__ +// C++ +#include +// yhttpd +#include "yhook.h" + +// forward declaration +class CNeutrinoAPI; + +//----------------------------------------------------------------------------- +class CControlAPI : public Cyhook +{ +private: + // Dispatcher Array + typedef void (CControlAPI::*TyFunc)(CyhookHandler *hh); + typedef struct + { + const char *func_name; + TyFunc pfunc; + const char *mime_type; + } TyCgiCall; + const static TyCgiCall yCgiCallList[]; + + int rc_send(int ev, unsigned int code, unsigned int value); + + // send functions for ExecuteCGI (controld api) + void SendEventList(CyhookHandler *hh,t_channel_id channel_id); + void SendcurrentVAPid(CyhookHandler *hh); + void SendAllCurrentVAPid(CyhookHandler *hh); + void SendStreamInfo(CyhookHandler *hh); + void SendBouquets(CyhookHandler *hh); + void SendBouquet(CyhookHandler *hh,int BouquetNr); + void SendChannelList(CyhookHandler *hh); + void SendTimers(CyhookHandler *hh); + + // subs + friend class CNeutrinoWebserver; // for timer /fb/ compatibility + void doModifyTimer(CyhookHandler *hh); + void doNewTimer(CyhookHandler *hh); + + //yweb + void YWeb_SendVideoStreamingPids(CyhookHandler *hh, int apid_no); + void YWeb_SendRadioStreamingPid(CyhookHandler *hh); + void compatibility_Timer(CyhookHandler *hh); + std::string YexecuteScript(CyhookHandler *hh, std::string cmd); + + // CGI functions for ExecuteCGI + void TimerCGI(CyhookHandler *hh); + void SetModeCGI(CyhookHandler *hh); + void GetModeCGI(CyhookHandler *hh); + void ExecCGI(CyhookHandler *hh); + void SystemCGI(CyhookHandler *hh); + void StandbyCGI(CyhookHandler *hh); + void EsoundCGI(CyhookHandler *hh); + void RCCGI(CyhookHandler *hh); + void GetDateCGI(CyhookHandler *hh); + void GetTimeCGI(CyhookHandler *hh); + void GetServicesxmlCGI(CyhookHandler *hh); + void GetBouquetsxmlCGI(CyhookHandler *hh); + void GetChannel_IDCGI(CyhookHandler *hh); + void MessageCGI(CyhookHandler *hh); + void InfoCGI(CyhookHandler *hh); + void ShutdownCGI(CyhookHandler *hh); + void VolumeCGI(CyhookHandler *hh); + void ChannellistCGI(CyhookHandler *hh); + void GetBouquetCGI(CyhookHandler *hh); + void GetBouquetsCGI(CyhookHandler *hh); + void EpgCGI(CyhookHandler *hh); + void VersionCGI(CyhookHandler *hh); + void ZaptoCGI(CyhookHandler *hh); + void StartPluginCGI(CyhookHandler *hh); + void LCDAction(CyhookHandler *hh); + void YWebCGI(CyhookHandler *hh); + void RebootCGI(CyhookHandler *hh); + void RCEmCGI(CyhookHandler *hh); + void VideoFormatCGI(CyhookHandler *hh); + void VideoOutputCGI(CyhookHandler *hh); + void VCROutputCGI(CyhookHandler *hh); + void ScartModeCGI(CyhookHandler *hh); + void setBouquetCGI(CyhookHandler *hh); + void saveBouquetCGI(CyhookHandler *hh); + void moveBouquetCGI(CyhookHandler *hh); + void deleteBouquetCGI(CyhookHandler *hh); + void addBouquetCGI(CyhookHandler *hh); + void renameBouquetCGI(CyhookHandler *hh); + void changeBouquetCGI(CyhookHandler *hh); + void updateBouquetCGI(CyhookHandler *hh); + void build_live_url(CyhookHandler *hh); + +protected: + static const unsigned int PLUGIN_DIR_COUNT = 5; + static std::string PLUGIN_DIRS[PLUGIN_DIR_COUNT]; + CNeutrinoAPI *NeutrinoAPI; + + void init(CyhookHandler *hh); + void Execute(CyhookHandler *hh); + +public: + // constructor & deconstructor + CControlAPI(CNeutrinoAPI *_NeutrinoAPI); + + // virtual functions for HookHandler/Hook + virtual std::string getHookName(void) {return std::string("mod_ControlAPI");} + virtual std::string getHookVersion(void) {return std::string("$Revision: 1.1.2.2 $");} + virtual THandleStatus Hook_SendResponse(CyhookHandler *hh); + virtual THandleStatus Hook_PrepareResponse(CyhookHandler *hh); +}; + +#endif /* __nhttpd_neutrinocontrolapi_hpp__ */ diff --git a/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp b/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp new file mode 100644 index 000000000..d0fa0c20f --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.cpp @@ -0,0 +1,386 @@ +//============================================================================= +// NHTTPD +// NeutrionAPI +// +// Aggregates: NeutrinoYParser, NeutrinoControlAPI +// Defines Interfaces to:CControldClient, CSectionsdClient, CZapitClient, +// CTimerdClient,CLCDAPI +// Place for common used Neutrino-functions used by NeutrinoYParser, NeutrinoControlAPI +//============================================================================= + +// C +#include +#include + +// C++ +#include +#include +#include + +// tuxbox +#include + +#include +#include +#include +extern tallchans allchans; +extern CBouquetManager *g_bouquetManager; + +// yhttpd +#include "ylogging.h" + +// nhttpd +#include "neutrinoapi.h" + +void sectionsd_getChannelEvents(CChannelEventList &eList, const bool tv_mode = true, t_channel_id *chidlist = NULL, int clen = 0); + +//============================================================================= +// No Class Helpers +//============================================================================= + +static std::map iso639; +#ifndef initialize_iso639_map +bool _initialize_iso639_map(void) +{ + std::string s, t, u, v; + std::ifstream in("/share/iso-codes/iso-639.tab"); + if (in.is_open()) + { + while (in.peek() == '#') + getline(in, s); + while (in >> s >> t >> u >> std::ws) + { + getline(in, v); + iso639[s] = v; + if (s != t) + iso639[t] = v; + } + in.close(); + return true; + } + else + return false; +} +#endif +//----------------------------------------------------------------------------- +const char * _getISO639Description(const char * const iso) +{ + std::map::const_iterator it = iso639.find(std::string(iso)); + if (it == iso639.end()) + return iso; + else + return it->second.c_str(); +} + +//============================================================================= +// Initialization of static variables +//============================================================================= +std::string CNeutrinoAPI::Dbox_Hersteller[4] = {"none", "Nokia", "Philips", "Sagem"}; +std::string CNeutrinoAPI::videooutput_names[5] = {"CVBS", "RGB with CVBS", "S-Video", "YUV with VBS", "YUV with CVBS"}; +std::string CNeutrinoAPI::videoformat_names[4] = {"automatic", "16:9", "4:3 (LB)", "4:3 (PS)"}; +std::string CNeutrinoAPI::audiotype_names[5] = {"none", "single channel","dual channel","joint stereo","stereo"}; + +//============================================================================= +// Constructor & Destructor +//============================================================================= +CNeutrinoAPI::CNeutrinoAPI() +{ + Sectionsd = new CSectionsdClient(); + Zapit = new CZapitClient(); + Timerd = new CTimerdClient(); + + NeutrinoYParser = new CNeutrinoYParser(this); + ControlAPI = new CControlAPI(this); + + UpdateBouquets(); + + EventServer = new CEventServer; + EventServer->registerEvent2( NeutrinoMessages::SHUTDOWN, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::STANDBY_ON, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::STANDBY_OFF, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::STANDBY_TOGGLE, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::EVT_POPUP, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::EVT_EXTMSG, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::CHANGEMODE, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::EVT_START_PLUGIN, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::LOCK_RC, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); + EventServer->registerEvent2( NeutrinoMessages::UNLOCK_RC, CEventServer::INITID_HTTPD, "/tmp/neutrino.sock"); +} +//------------------------------------------------------------------------- + +CNeutrinoAPI::~CNeutrinoAPI(void) +{ + if (NeutrinoYParser) + delete NeutrinoYParser; + if (ControlAPI) + delete ControlAPI; + if (Sectionsd) + delete Sectionsd; + if (Zapit) + delete Zapit; + if (Timerd) + delete Timerd; + if (EventServer) + delete EventServer; +} + +//------------------------------------------------------------------------- + +void CNeutrinoAPI::UpdateBouquets(void) +{ +#if 0 //FIXME + BouquetList.clear(); + Zapit->getBouquets(BouquetList, true, true); + for (unsigned int i = 1; i <= BouquetList.size(); i++) + UpdateBouquet(i); + + UpdateChannelList(); +#endif +} + +//------------------------------------------------------------------------- +void CNeutrinoAPI::ZapTo(const char * const target) +{ + t_channel_id channel_id; + + sscanf(target, + SCANF_CHANNEL_ID_TYPE, + &channel_id); + + ZapToChannelId(channel_id); +} +//------------------------------------------------------------------------- +void CNeutrinoAPI::ZapToChannelId(t_channel_id channel_id) +{ + if (channel_id == Zapit->getCurrentServiceID()) + { + //printf("Kanal ist aktuell\n"); + return; + } + + if (Zapit->zapTo_serviceID(channel_id) != CZapitClient::ZAP_INVALID_PARAM) + Sectionsd->setServiceChanged(channel_id&0xFFFFFFFFFFFFULL, false); +} +//------------------------------------------------------------------------- + +void CNeutrinoAPI::ZapToSubService(const char * const target) +{ + t_channel_id channel_id; + + sscanf(target, + SCANF_CHANNEL_ID_TYPE, + &channel_id); + + if (Zapit->zapTo_subServiceID(channel_id) != CZapitClient::ZAP_INVALID_PARAM) + Sectionsd->setServiceChanged(channel_id&0xFFFFFFFFFFFFULL, false); +} +//------------------------------------------------------------------------- +t_channel_id CNeutrinoAPI::ChannelNameToChannelId(std::string search_channel_name) +{ +//FIXME depending on mode missing + //int mode = Zapit->getMode(); + t_channel_id channel_id = (t_channel_id)-1; + CStringArray channel_names = ySplitStringVector(search_channel_name, ","); + for (tallchans_iterator it = allchans.begin(); it != allchans.end(); it++) { + std::string channel_name = it->second.getName(); + for(unsigned int j=0;jsecond.channel_id; + break; + } + } + } + return channel_id; +} + +//------------------------------------------------------------------------- +// Get functions +//------------------------------------------------------------------------- + +bool CNeutrinoAPI::GetStreamInfo(int bitInfo[10]) +{ + char *key, *tmpptr, buf[100]; + long value; + int pos = 0; + + memset(bitInfo, 0, sizeof(bitInfo)); + + FILE *fd = fopen("/proc/bus/bitstream", "rt"); + + if (fd == NULL) + { + dprintf("error while opening proc-bitstream\n" ); + return false; + } + + fgets(buf,35,fd);//dummy + while(!feof(fd)) + { + if(fgets(buf,35,fd)!=NULL) + { + buf[strlen(buf)-1]=0; + tmpptr=buf; + key=strsep(&tmpptr,":"); + value=strtoul(tmpptr,NULL,0); + bitInfo[pos]= value; + pos++; + } + } + fclose(fd); + + return true; +} + +//------------------------------------------------------------------------- + +bool CNeutrinoAPI::GetChannelEvents(void) +{ + sectionsd_getChannelEvents(eList); + CChannelEventList::iterator eventIterator; + + ChannelListEvents.clear(); + + if (eList.begin() == eList.end()) + return false; + + for (eventIterator = eList.begin(); eventIterator != eList.end(); eventIterator++) + ChannelListEvents[(*eventIterator).get_channel_id()] = &(*eventIterator); + + return true; +} + +//------------------------------------------------------------------------- + +std::string CNeutrinoAPI::GetServiceName(t_channel_id channel_id) +{ + tallchans_iterator it = allchans.find(channel_id); + if (it != allchans.end()) + it->second.getName(); + return ""; +} + +//------------------------------------------------------------------------- + +CZapitClient::BouquetChannelList *CNeutrinoAPI::GetBouquet(unsigned int, int) +{ + //FIXME + printf("CNeutrinoAPI::GetChannelList still used !\n"); + return NULL; +} + +//------------------------------------------------------------------------- + +CZapitClient::BouquetChannelList *CNeutrinoAPI::GetChannelList(int) +{ +//FIXME + printf("CNeutrinoAPI::GetChannelList still used !\n"); + return NULL; +} + +//------------------------------------------------------------------------- +void CNeutrinoAPI::UpdateBouquet(unsigned int) +{ + //FIXME +} + +//------------------------------------------------------------------------- +void CNeutrinoAPI::UpdateChannelList(void) +{ + //FIXME +} + +//------------------------------------------------------------------------- + +std::string CNeutrinoAPI::timerEventType2Str(CTimerd::CTimerEventTypes type) +{ + std::string result; + switch (type) { + case CTimerd::TIMER_SHUTDOWN: + result = "Shutdown"; + break; + case CTimerd::TIMER_NEXTPROGRAM: + result = "Next program"; + break; + case CTimerd::TIMER_ZAPTO: + result = "Zap to"; + break; + case CTimerd::TIMER_STANDBY: + result = "Standby"; + break; + case CTimerd::TIMER_RECORD: + result = "Record"; + break; + case CTimerd::TIMER_REMIND: + result = "Reminder"; + break; + case CTimerd::TIMER_EXEC_PLUGIN: + result = "Execute plugin"; + break; + case CTimerd::TIMER_SLEEPTIMER: + result = "Sleeptimer"; + break; + default: + result = "Unknown"; + break; + } + return result; +} + +//------------------------------------------------------------------------- + +std::string CNeutrinoAPI::timerEventRepeat2Str(CTimerd::CTimerEventRepeat rep) +{ + std::string result; + switch (rep) { + case CTimerd::TIMERREPEAT_ONCE: + result = "once"; + break; + case CTimerd::TIMERREPEAT_DAILY: + result = "daily"; + break; + case CTimerd::TIMERREPEAT_WEEKLY: + result = "weekly"; + break; + case CTimerd::TIMERREPEAT_BIWEEKLY: + result = "2-weekly"; + break; + case CTimerd::TIMERREPEAT_FOURWEEKLY: + result = "4-weekly"; + break; + case CTimerd::TIMERREPEAT_MONTHLY: + result = "monthly"; + break; + case CTimerd::TIMERREPEAT_BYEVENTDESCRIPTION: + result = "event"; + break; + case CTimerd::TIMERREPEAT_WEEKDAYS: + result = "weekdays"; + break; + default: + if (rep > CTimerd::TIMERREPEAT_WEEKDAYS) + { + if (rep & 0x0200) + result += "Mo "; + if (rep & 0x0400) + result += "Tu "; + if (rep & 0x0800) + result += "We "; + if (rep & 0x1000) + result += "Th "; + if (rep & 0x2000) + result += "Fr "; + if (rep & 0x4000) + result += "Sa "; + if (rep & 0x8000) + result += "Su "; + } + else + result = "Unknown"; + } + return result; +} + diff --git a/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.h b/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.h new file mode 100644 index 000000000..39383a9b4 --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/neutrinoapi.h @@ -0,0 +1,84 @@ +#ifndef __nhttpd_neutrinoapi_h__ +#define __nhttpd_neutrinoapi_h__ + +// c++ +#include +#include + +// tuxbox +#include +#include +#include +#include + +// nhttpd +#include "helper.h" +#include "neutrinoyparser.h" +#include "controlapi.h" + +//------------------------------------------------------------------------- +// No Class Helpers +const char * _getISO639Description(const char * const iso); +bool _initialize_iso639_map(void); + +//------------------------------------------------------------------------- +class CNeutrinoAPI +{ + // Clientlibs + CSectionsdClient *Sectionsd; + CZapitClient *Zapit; + CTimerdClient *Timerd; + CEventServer *EventServer; + + // complete channellists + CZapitClient::BouquetChannelList RadioChannelList,TVChannelList; + // events of actual channel + std::map ChannelListEvents; + // List of available tv bouquets + std::map TVBouquetsList; + // List of available radio bouquets + std::map RadioBouquetsList; + // List of bouquets + CZapitClient::BouquetList BouquetList; + + //bool standby_mode; + + // some constants + static std::string Dbox_Hersteller[4]; + static std::string videooutput_names[5]; + static std::string videoformat_names[4]; + static std::string audiotype_names[5]; + + // get functions to collect data + bool GetChannelEvents(void); + bool GetStreamInfo(int bitinfo[10]); + std::string GetServiceName(t_channel_id channel_id); + CZapitClient::BouquetChannelList *GetBouquet(unsigned int BouquetNr, int Mode); + CZapitClient::BouquetChannelList *GetChannelList(int Mode); + + // support functions + void ZapTo (const char * const target); + void ZapToSubService(const char * const target); + void ZapToChannelId (t_channel_id channel_id); + t_channel_id ChannelNameToChannelId(std::string search_channel_name); + + void UpdateBouquet(unsigned int BouquetNr); + void UpdateChannelList(void); + void UpdateBouquets(void); + + std::string timerEventType2Str(CTimerd::CTimerEventTypes type); + std::string timerEventRepeat2Str(CTimerd::CTimerEventRepeat rep); + +public: + CNeutrinoAPI(); + ~CNeutrinoAPI(void); + + CChannelEventList eList; + CNeutrinoYParser *NeutrinoYParser; + CControlAPI *ControlAPI; + + friend class CNeutrinoYParser; // Backreference + friend class CControlAPI; +}; + +#endif /*__nhttpd_neutrinoapi_h__*/ diff --git a/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp b/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp new file mode 100644 index 000000000..65475bb05 --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.cpp @@ -0,0 +1,1079 @@ +//============================================================================= +// NHTTPD +// Neutrino yParser Extenstion +//============================================================================= +// c++ +#include +#include +#include +#include +#include +// system +#include //ntohs +#include //ntohs +#include //ntohs +// yhttpd +#include "yhttpd.h" +#include "ytypes_globals.h" +#include "mod_yparser.h" +// tuxbox +#include //timer list +// nhttpd +#include "neutrinoyparser.h" +#include "neutrinoapi.h" + +#include +#include +#include + +#include +#include + +extern tallchans allchans; +extern CBouquetManager *g_bouquetManager; +extern t_channel_id live_channel_id; + +bool sectionsd_getNVODTimesServiceKey(const t_channel_id uniqueServiceKey, CSectionsdClient::NVODTimesList& nvod_list); +void sectionsd_getCurrentNextServiceKey(t_channel_id uniqueServiceKey, CSectionsdClient::responseGetCurrentNextInfoChannelID& current_next ); +bool sectionsd_getComponentTagsUniqueKey(const event_id_t uniqueKey, CSectionsdClient::ComponentTagList& tags); +bool sectionsd_getActualEPGServiceKey(const t_channel_id uniqueServiceKey, CEPGData * epgdata); +//============================================================================= +// Constructor & Destructor & Initialization +//============================================================================= +CNeutrinoYParser::CNeutrinoYParser(CNeutrinoAPI *_NeutrinoAPI) +{ + NeutrinoAPI = _NeutrinoAPI; +} +//------------------------------------------------------------------------- +CNeutrinoYParser::~CNeutrinoYParser(void) +{ +} +//============================================================================= +// Hooks! +//============================================================================= +//----------------------------------------------------------------------------- +// HOOK: response_hook Handler +// This is the main dispatcher for this module +//----------------------------------------------------------------------------- +THandleStatus CNeutrinoYParser::Hook_SendResponse(CyhookHandler *hh) +{ + hh->status = HANDLED_NONE; + + log_level_printf(4,"Neutrinoparser Hook Start url:%s\n",hh->UrlData["url"].c_str()); + init(hh); + + CNeutrinoYParser *yP = new CNeutrinoYParser(NeutrinoAPI); // create a Session + if(hh->UrlData["fileext"] == "yhtm") // yParser for yhtm-File + yP->ParseAndSendFile(hh); + else if(hh->UrlData["path"] == "/y/") // /y/ commands + { + yP->Execute(hh); + if(hh->status == HANDLED_NOT_IMPLEMENTED) + hh->status = HANDLED_NONE; // y-calls can be implemented anywhere + } + + delete yP; + + log_level_printf(4,"Neutrinoparser Hook Ende status:%d\n",(int)hh->status); +// log_level_printf(5,"Neutrinoparser Hook Result:%s\n",hh->yresult.c_str()); + + return hh->status; +} +//----------------------------------------------------------------------------- +// HOOK: webserver_readconfig_hook Handler +// This hook ist called from ReadCong (webserver) +//----------------------------------------------------------------------------- +THandleStatus CNeutrinoYParser::Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList) +{ + ConfigList["ExtrasDocumentRoot"]= Config->getString("ExtrasDocRoot", EXTRASDOCUMENTROOT); + ConfigList["ExtrasDocumentURL"] = Config->getString("ExtrasDocURL", EXTRASDOCUMENTURL); +// ConfigList["NewGui"] = Config->getString("NewGui", "true"); + ConfigList["Zapit_XML_Path"] = Config->getString("Zapit_XML_Path", ZAPITXMLPATH); + ConfigList["TUXBOX_LOGOS_URL"]= Config->getString("Tuxbox.LogosURL", TUXBOX_LOGOS_URL); + + if (Config->getInt32("configfile.version") < 3) + { + Config->setString("Tuxbox.LogosURL", Config->getString("ExtrasDocURL", EXTRASDOCUMENTURL) +"/logos"); + Config->setInt32("configfile.version", CONF_VERSION); + Config->saveConfig(HTTPD_CONFIGFILE); + } + + return HANDLED_CONTINUE; +} + +//============================================================================= +// y-func : Dispatching +//============================================================================= +const CNeutrinoYParser::TyFuncCall CNeutrinoYParser::yFuncCallList[]= +{ + {"mount-get-list", &CNeutrinoYParser::func_mount_get_list}, + {"mount-set-values", &CNeutrinoYParser::func_mount_set_values}, + {"get_bouquets_as_dropdown", &CNeutrinoYParser::func_get_bouquets_as_dropdown}, + {"get_bouquets_as_templatelist",&CNeutrinoYParser::func_get_bouquets_as_templatelist}, + {"get_actual_bouquet_number", &CNeutrinoYParser::func_get_actual_bouquet_number}, + {"get_channels_as_dropdown", &CNeutrinoYParser::func_get_channels_as_dropdown}, + {"get_bouquets_with_epg", &CNeutrinoYParser::func_get_bouquets_with_epg}, + {"get_actual_channel_id", &CNeutrinoYParser::func_get_actual_channel_id}, + {"get_mode", &CNeutrinoYParser::func_get_mode}, + {"get_video_pids", &CNeutrinoYParser::func_get_video_pids}, + {"get_audio_pid", &CNeutrinoYParser::func_get_radio_pid}, + {"get_audio_pids_as_dropdown", &CNeutrinoYParser::func_get_audio_pids_as_dropdown}, + {"umount_get_list", &CNeutrinoYParser::func_unmount_get_list}, + {"get_partition_list", &CNeutrinoYParser::func_get_partition_list}, + {"get_boxtype", &CNeutrinoYParser::func_get_boxtype}, + {"get_current_stream_info", &CNeutrinoYParser::func_get_current_stream_info}, + {"get_timer_list", &CNeutrinoYParser::func_get_timer_list}, + {"set_timer_form", &CNeutrinoYParser::func_set_timer_form}, + {"bouquet_editor_main", &CNeutrinoYParser::func_bouquet_editor_main}, + {"set_bouquet_edit_form", &CNeutrinoYParser::func_set_bouquet_edit_form}, + +}; +//------------------------------------------------------------------------- +// y-func : dispatching and executing +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::YWeb_cgi_func(CyhookHandler *hh, std::string ycmd) +{ + std::string func="", para="", yresult="ycgi func not found"; + bool found = false; + ySplitString(ycmd," ",func, para); + + log_level_printf(4,"NeutrinoYParser: func:(%s)\n", func.c_str()); + for(unsigned int i = 0;i < (sizeof(yFuncCallList)/sizeof(yFuncCallList[0])); i++) + if (func == yFuncCallList[i].func_name) + { + yresult = (this->*yFuncCallList[i].pfunc)(hh, para); + found = true; + break; + } + log_level_printf(8,"NeutrinoYParser: func:(%s) para:(%s) Result:(%s)\n", func.c_str(), para.c_str(), yresult.c_str() ); + if(!found) + yresult = CyParser::YWeb_cgi_func(hh, ycmd); + return yresult; +} +//============================================================================= +// y-func : Functions for Neutrino +//============================================================================= +//------------------------------------------------------------------------- +// y-func : mount_get_list +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_mount_get_list(CyhookHandler *, std::string) +{ + CConfigFile *Config = new CConfigFile(','); + std::string ysel, ytype, yip, ylocal_dir, ydir, ynr, yresult; + int yitype; + + Config->loadConfig(NEUTRINO_CONFIGFILE); + for(unsigned int i=0; i <= 7; i++) + { + ynr=itoa(i); + ysel = ((i==0) ? "checked=\"checked\"" : ""); + yitype = Config->getInt32("network_nfs_type_"+ynr,0); + ytype = ( (yitype==0) ? "NFS" :((yitype==1) ? "CIFS" : "FTPFS") ); + yip = Config->getString("network_nfs_ip_"+ynr,""); + ydir = Config->getString("network_nfs_dir_"+ynr,""); + ylocal_dir = Config->getString("network_nfs_local_dir_"+ynr,""); + if(ydir != "") + ydir="("+ydir+")"; + + yresult += string_printf("%d %s - %s %s %s
", + i,ysel.c_str(),i,ytype.c_str(),yip.c_str(),ylocal_dir.c_str(), ydir.c_str()); + } + delete Config; + return yresult; +} + +//------------------------------------------------------------------------- +// y-func : mount_set_values +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_mount_set_values(CyhookHandler *hh, std::string) +{ + CConfigFile *Config = new CConfigFile(','); + std::string ynr, yresult; + + Config->loadConfig(NEUTRINO_CONFIGFILE); + ynr = hh->ParamList["nr"]; + Config->setString("network_nfs_type_"+ynr,hh->ParamList["type"]); + Config->setString("network_nfs_ip_"+ynr,hh->ParamList["ip"]); + Config->setString("network_nfs_dir_"+ynr,hh->ParamList["dir"]); + Config->setString("network_nfs_local_dir_"+ynr,hh->ParamList["localdir"]); + Config->setString("network_nfs_mac_"+ynr,hh->ParamList["mac"]); + Config->setString("network_nfs_mount_options1_"+ynr,hh->ParamList["opt1"]); + Config->setString("network_nfs_mount_options2_"+ynr,hh->ParamList["opt2"]); + Config->setString("network_nfs_automount_"+ynr,hh->ParamList["automount"]); + Config->setString("network_nfs_username_"+ynr,hh->ParamList["username"]); + Config->setString("network_nfs_password_"+ynr,hh->ParamList["password"]); + Config->saveConfig(NEUTRINO_CONFIGFILE); + + delete Config; + return yresult; +} +//------------------------------------------------------------------------- +// y-func : get_bouquets_as_dropdown [] +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_bouquets_as_dropdown(CyhookHandler *, std::string para) +{ + std::string ynr, yresult, sel, nr_str, do_show_hidden; + int nr=1; + + ySplitString(para," ",nr_str, do_show_hidden); + if(nr_str != "") + nr = atoi(nr_str.c_str()); + + int mode = NeutrinoAPI->Zapit->getMode(); + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) { + ZapitChannelList * channels = mode == CZapitClient::MODE_RADIO ? &g_bouquetManager->Bouquets[i]->radioChannels : &g_bouquetManager->Bouquets[i]->tvChannels; + sel=(nr==(i+1)) ? "selected=\"selected\"" : ""; + if(!channels->empty() && (!g_bouquetManager->Bouquets[i]->bHidden || do_show_hidden == "true")) + yresult += string_printf("\n", i + 1, sel.c_str(), + (encodeString(std::string(g_bouquetManager->Bouquets[i]->bFav ? g_Locale->getText(LOCALE_FAVORITES_BOUQUETNAME) :g_bouquetManager->Bouquets[i]->Name.c_str()))).c_str()); + //yresult += string_printf("\n", i + 1, sel.c_str(), (encodeString(std::string(g_bouquetManager->Bouquets[i]->Name.c_str()))).c_str()); + } + return yresult; +} + +//------------------------------------------------------------------------- +// y-func : get_bouquets_as_templatelist [~] +// TODO: select actual Bouquet +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_bouquets_as_templatelist(CyhookHandler *, std::string para) +{ + std::string yresult, ytemplate, do_show_hidden; + + ySplitString(para,"~",ytemplate, do_show_hidden); + //ytemplate += "\n"; //FIXME add newline to printf + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) { + if(!g_bouquetManager->Bouquets[i]->bHidden || do_show_hidden == "true") { + yresult += string_printf(ytemplate.c_str(), i + 1, g_bouquetManager->Bouquets[i]->bFav ? g_Locale->getText(LOCALE_FAVORITES_BOUQUETNAME) : g_bouquetManager->Bouquets[i]->Name.c_str()); + yresult += "\r\n"; + } + } + return yresult; +} +//------------------------------------------------------------------------- +// y-func : get_actual_bouquet_number +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_actual_bouquet_number(CyhookHandler *, std::string) +{ + int actual=0; + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) { + if(g_bouquetManager->existsChannelInBouquet(i, live_channel_id)) { + actual=i+1; + break; + } + } + return std::string(itoa(actual)); +} + +//------------------------------------------------------------------------- +// y-func : get_channel_dropdown [ []] +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_channels_as_dropdown(CyhookHandler *, std::string para) +{ + std::string abouquet, achannel_id, yresult, sel, sid; + + int bnumber = 1; + int mode = NeutrinoAPI->Zapit->getMode(); + + ySplitString(para," ",abouquet, achannel_id); + if(abouquet != "") + bnumber = atoi(abouquet.c_str()); + if(bnumber > 0) { + bnumber--; + ZapitChannelList channels; + channels = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->Bouquets[bnumber]->radioChannels : g_bouquetManager->Bouquets[bnumber]->tvChannels; + for(int j = 0; j < (int) channels.size(); j++) { + CEPGData epg; + CZapitChannel * channel = channels[j]; + char buf[100],id[20]; + sprintf(id,PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS,channel->channel_id); + std::string _sid = std::string(id); + sel = (_sid == achannel_id) ? "selected=\"selected\"" : ""; + sectionsd_getActualEPGServiceKey(channel->channel_id&0xFFFFFFFFFFFFULL, &epg); + sprintf(buf,"\n", channel->channel_id, sel.c_str(), channel->getName().c_str(),epg.title.c_str()); + yresult += buf; + } + } + return yresult; +} +//------------------------------------------------------------------------- +// TODO: clean up code +// use templates? +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_bouquets_with_epg(CyhookHandler *hh, std::string para) +{ + int BouquetNr = 0; + std::string abnumber, tmp,yresult; + ZapitChannelList channels; + int num; + int mode = NeutrinoAPI->Zapit->getMode(); + + ySplitString(para," ",abnumber, tmp); + if(abnumber != "") + BouquetNr = atoi(abnumber.c_str()); + if (BouquetNr > 0) { + BouquetNr--; + channels = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->Bouquets[BouquetNr]->radioChannels : g_bouquetManager->Bouquets[BouquetNr]->tvChannels; + num = 1 + (mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr) : g_bouquetManager->tvChannelsBegin().getNrofFirstChannelofBouquet(BouquetNr)) ; + } else { + CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin(); + for (; !(cit.EndOfChannels()); cit++) + channels.push_back(*cit); + num = 1; + } + NeutrinoAPI->GetChannelEvents(); + + int i = 1; + char classname; + t_channel_id current_channel = live_channel_id; + int prozent; + CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo; + std::string timestr; + bool have_logos = false; + + if(hh->WebserverConfigList["TUXBOX_LOGOS_URL"] != "" ||hh->WebserverConfigList["ExtrasDocumentRoot"] == "web" || (access((hh->WebserverConfigList["ExtrasDocumentRoot"]+"/logos").c_str(),4)==0) ) + have_logos = true; + for(int j = 0; j < (int) channels.size(); j++) + { + CZapitChannel * channel = channels[j]; + CChannelEvent *event; + event = NeutrinoAPI->ChannelListEvents[channel->channel_id]; + + classname = (i++ & 1) ? 'a' : 'b'; + if (channel->channel_id == current_channel) + classname = 'c'; + + std::string bouquetstr = (BouquetNr >= 0) ? ("&bouquet=" + itoa(BouquetNr)) : ""; + yresult += ""; +//FIXME: Logo-Extensions + if(have_logos) + yresult += string_printf("", classname, channel->channel_id, + (hh->WebserverConfigList["ExtrasDocumentURL"]).c_str(), + channel->channel_id & 0xFFFFFFFFFFFFULL); + + /* timer slider */ + if(event && event->duration > 0) + prozent = 100 * (time(NULL) - event->startTime) / event->duration; + else + prozent = 100; + yresult += string_printf("\n" + , classname + , (prozent / 10) * 3 + , (10 - (prozent / 10))*3 + ); + + /* channel name and buttons */ + yresult += string_printf("
\n" + "\t" + "" + "" + "" + "" + "
\n
\n%s %d. %s%s %s\n", + ((channel->channel_id == current_channel) ? "" : " "), + channel->channel_id, + num + j /*channel->nr*/, + channel->getName().c_str(), + (channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE) ? " (NVOD)" : "", + channel->channel_id, + ((NeutrinoAPI->ChannelListEvents[channel->channel_id]) ? "\"Programmvorschau\"" : "")); + + if (channel->channel_id == current_channel) + yresult += string_printf("\n  \"Streaminfo\""); + + yresult += string_printf("
\n\n\n"); + + if (channel->getServiceType() == ST_NVOD_REFERENCE_SERVICE) + { + CSectionsdClient::NVODTimesList nvod_list; + if (sectionsd_getNVODTimesServiceKey(channel->channel_id&0xFFFFFFFFFFFFULL, nvod_list)) + { + CZapitClient::subServiceList subServiceList; + + for (CSectionsdClient::NVODTimesList::iterator ni = nvod_list.begin(); ni != nvod_list.end(); ni++) + { + CZapitClient::commandAddSubServices cmd; + CEPGData epg; + + // Byte Sequence by ntohs + cmd.original_network_id = ntohs(ni->original_network_id); + cmd.service_id = ntohs(ni->service_id); + cmd.transport_stream_id = ntohs(ni->transport_stream_id); + + t_channel_id channel_id = CREATE_CHANNEL_ID_FROM_SERVICE_ORIGINALNETWORK_TRANSPORTSTREAM_ID(cmd.service_id, cmd.original_network_id, cmd.transport_stream_id); + + timestr = timeString(ni->zeit.startzeit); // FIXME: time is wrong (at least on little endian)! + sectionsd_getActualEPGServiceKey(channel_id&0xFFFFFFFFFFFFULL, &epg); // FIXME: der scheissendreck geht nit!!! + yresult += string_printf("\n ", classname); + yresult += string_printf("%s ", classname, timestr.c_str()); + yresult += string_printf("%s%04x:%04x:%04x %s", // FIXME: get name + (channel_id == current_channel) ? "" : " ", + channel_id, + bouquetstr.c_str(), + cmd.transport_stream_id, + cmd.original_network_id, + cmd.service_id, + epg.title.c_str()); + yresult += string_printf("\n"); + + subServiceList.push_back(cmd); + } + + if (!(subServiceList.empty())) + NeutrinoAPI->Zapit->setSubServices(subServiceList); + } + } + + else if ((event = NeutrinoAPI->ChannelListEvents[channel->channel_id])) + { + bool has_current_next = true; + sectionsd_getCurrentNextServiceKey(channel->channel_id&0xFFFFFFFFFFFFULL, currentNextInfo); + timestr = timeString(event->startTime); + + yresult += string_printf("",classname); + yresult += string_printf("%s %s " + "(%ld von %d min, %d%%)" + , timestr.c_str() + , event->description.c_str() + , (time(NULL) - event->startTime)/60 + , event->duration / 60,prozent); + + if ((has_current_next) && (currentNextInfo.flags & CSectionsdClient::epgflags::has_next)) { + timestr = timeString(currentNextInfo.next_zeit.startzeit); + yresult += string_printf("
%s %s", timestr.c_str(), currentNextInfo.next_name.c_str()); + } + + yresult += string_printf("\n"); + } + else + yresult += string_printf("\n"); + } + return yresult; +} + +//------------------------------------------------------------------------- +// y-func : get_actual_channel_id +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_actual_channel_id(CyhookHandler *, std::string) +{ + return string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, live_channel_id /*NeutrinoAPI->Zapit->getCurrentServiceID()*/); +} +//------------------------------------------------------------------------- +// y-func : get_mode (returns tv|radio|unknown) +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_mode(CyhookHandler *, std::string) +{ + std::string yresult; + int mode = NeutrinoAPI->Zapit->getMode(); + + if ( mode == CZapitClient::MODE_TV) + yresult = "tv"; + else if ( mode == CZapitClient::MODE_RADIO) + yresult = "radio"; + else + yresult = "unknown"; + return yresult; +} + +//------------------------------------------------------------------------- +// y-func : get_video_pids (para=audio channel, returns: 0x0000,0x0000,0x0000) +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_video_pids(CyhookHandler *, std::string para) +{ + CZapitClient::responseGetPIDs pids; + int apid=0,apid_no=0,apid_idx=0; + pids.PIDs.vpid=0; + + if(para != "") + apid_no = atoi(para.c_str()); + NeutrinoAPI->Zapit->getPIDS(pids); + + if( apid_no < (int)pids.APIDs.size()) + apid_idx=apid_no; + if(!pids.APIDs.empty()) + apid = pids.APIDs[apid_idx].pid; + return string_printf("0x%04x,0x%04x,0x%04x",pids.PIDs.pmtpid,pids.PIDs.vpid,apid); +} +//------------------------------------------------------------------------- +// y-func : get_radio_pids (returns: 0x0000) +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_radio_pid(CyhookHandler *, std::string) +{ + CZapitClient::responseGetPIDs pids; + int apid=0; + + NeutrinoAPI->Zapit->getPIDS(pids); + if(!pids.APIDs.empty()) + apid = pids.APIDs[0].pid; + + return string_printf("0x%04x",apid); +} + +//------------------------------------------------------------------------- +// y-func : get_audio_pids_as_dropdown (from controlapi) +// prara: [apid] option value = apid-Value. Default apid-Index +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_audio_pids_as_dropdown(CyhookHandler *, std::string para) +{ + std::string yresult; + static bool init_iso=true; + bool idx_as_id=true; + + if(para == "apid") + idx_as_id=false; + if(init_iso) + { + if(_initialize_iso639_map()) + init_iso=false; + } + bool eit_not_ok=true; + CZapitClient::responseGetPIDs pids; + + CSectionsdClient::ComponentTagList tags; + pids.PIDs.vpid=0; + NeutrinoAPI->Zapit->getPIDS(pids); + + t_channel_id current_channel = live_channel_id; //NeutrinoAPI->Zapit->getCurrentServiceID(); + CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo; + sectionsd_getCurrentNextServiceKey(current_channel&0xFFFFFFFFFFFFULL, currentNextInfo); + if (sectionsd_getComponentTagsUniqueKey(currentNextInfo.current_uniqueKey,tags)) + { + for (unsigned int i=0; i< tags.size(); i++) + { + for (unsigned short j=0; j< pids.APIDs.size(); j++) + { + if ( pids.APIDs[j].component_tag == tags[i].componentTag ) + { + if(!tags[i].component.empty()) + { + if(!(isalnum(tags[i].component[0]))) + tags[i].component=tags[i].component.substr(1,tags[i].component.length()-1); + yresult += string_printf("\r\n",idx_as_id ? j : pids.APIDs[j].pid,encodeString(tags[i].component).c_str()); + } + else + { + if(!(init_iso)) + { + strcpy( pids.APIDs[j].desc, _getISO639Description( pids.APIDs[j].desc ) ); + } + yresult += string_printf("\r\n",idx_as_id ? j : pids.APIDs[j].pid,encodeString(std::string(pids.APIDs[j].desc)).c_str(),pids.APIDs[j].is_ac3 ? " (AC3)": " "); + } + eit_not_ok=false; + break; + } + } + } + } + if(eit_not_ok) + { + unsigned short i = 0; + for (CZapitClient::APIDList::iterator it = pids.APIDs.begin(); it!=pids.APIDs.end(); it++) + { + if(!(init_iso)) + { + strcpy( pids.APIDs[i].desc, _getISO639Description( pids.APIDs[i].desc ) ); + } + yresult += string_printf("\r\n",idx_as_id ? i : it->pid,pids.APIDs[i].desc,pids.APIDs[i].is_ac3 ? " (AC3)": " "); + i++; + } + } + + if(pids.APIDs.empty()) + yresult = "00000"; // shouldnt happen, but print at least one apid + return yresult; +} + +//------------------------------------------------------------------------- +// y-func : build umount list +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_unmount_get_list(CyhookHandler *, std::string) +{ + std::string ysel, ymount, ylocal_dir, yfstype, ynr, yresult, mounts; + + std::ifstream in; + in.open("/proc/mounts", std::ifstream::in); + int j=0; + while(in.good() && (j<8)) + { + yfstype=""; + in >> ymount >> ylocal_dir >> yfstype; + in.ignore(std::numeric_limits::max(), '\n'); + yfstype = trim(yfstype); + if( (yfstype == "nfs") << (yfstype == "ftp") || (yfstype == "lufsd") ) + { + mounts=ylocal_dir +" on "+ ymount + " ("+yfstype+")"; + ysel = ((j==0) ? "checked=\"checked\"" : ""); + yresult += string_printf("%d %.120s
", + ylocal_dir.c_str(),ysel.c_str(),j,mounts.c_str()); + j++; + } + } + return yresult; +} + +//------------------------------------------------------------------------- +// y-func : build partition list +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_partition_list(CyhookHandler *, std::string) +{ + std::string ysel, ymtd, yname, dummy, yresult; + char ytmp[200]; + + std::ifstream in; + in.open("/proc/mtd", std::ifstream::in); + int j=0; + while(in.good() && (j<8)) + { + ymtd=""; + in >> ymtd >> dummy >> dummy; //format: mtd# start end "name " + in.getline(ytmp, 200); // Rest of line is the mtd description + yname = ytmp; + if((j>0) && (ymtd != ""))// iggnore first line + { + ysel = ((j==1) ? "checked=\"checked\"" : ""); + yresult += string_printf("%d %s
", + j-1,ysel.c_str(),yname.c_str(),j-1,yname.c_str()); + } + j++; + } + return yresult; +} +//------------------------------------------------------------------------- +// y-func : get boxtypetext (Nokia, Philips, Sagem) +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_boxtype(CyhookHandler *, std::string) +{ + return "Coolstream";//FIXME +} +//------------------------------------------------------------------------- +// y-func : get stream info +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_current_stream_info(CyhookHandler *hh, std::string) +{ + int bitInfo[10]; + CZapitClient::CCurrentServiceInfo serviceinfo; + + serviceinfo = NeutrinoAPI->Zapit->getCurrentServiceInfo(); + hh->ParamList["onid"] = itoh(serviceinfo.onid); + hh->ParamList["sid"] = itoh(serviceinfo.sid); + hh->ParamList["tsid"] = itoh(serviceinfo.tsid); + hh->ParamList["vpid"] = itoh(serviceinfo.vpid); + hh->ParamList["apid"] = itoh(serviceinfo.apid); + hh->ParamList["vtxtpid"] = (serviceinfo.vtxtpid != 0)?itoh(serviceinfo.vtxtpid):"nicht verfügbar"; + hh->ParamList["pmtpid"] = (serviceinfo.pmtpid != 0)?itoh(serviceinfo.pmtpid):"nicht verfügbar"; + hh->ParamList["tsfrequency"] = string_printf("%d.%d MHz", serviceinfo.tsfrequency/1000, serviceinfo.tsfrequency%1000); + hh->ParamList["polarisation"] = serviceinfo.polarisation==1?"h":"v"; + hh->ParamList["ServiceName"] = NeutrinoAPI->GetServiceName(live_channel_id);//NeutrinoAPI->Zapit->getCurrentServiceID()); + NeutrinoAPI->GetStreamInfo(bitInfo); + + hh->ParamList["VideoFormat"] = string_printf("%d x %d", bitInfo[0], bitInfo[1] ); + hh->ParamList["BitRate"] = string_printf("%d\n", bitInfo[4]*50); + + switch ( bitInfo[2] ) //format + { + case 2: hh->ParamList["AspectRatio"] = "4:3"; break; + case 3: hh->ParamList["AspectRatio"] = "16:9"; break; + case 4: hh->ParamList["AspectRatio"] = "2.21:1"; break; + default: hh->ParamList["AspectRatio"]= "unknown"; break; + } + + switch ( bitInfo[3] ) //fps + { + case 3: hh->ParamList["FPS"] = "25"; break; + case 6: hh->ParamList["FPS"] = "50"; break; + default: hh->ParamList["FPS"]= "unknown"; + } + + if (!bitInfo[7]) hh->ParamList["AudioType"]="unknown"; + else { + const char* layernames[4]={"res","III","II","I"}; + const char* sampfreqnames[4]={"44,1k","48k","32k","res"}; + const char* modenames[4]={"stereo","joint_st","dual_ch","single_ch"}; + + long header = bitInfo[7]; + + unsigned char layer = (header>>17)&3; + unsigned char sampfreq =(header>>10)&3; + unsigned char mode = (header>> 6)&3; + unsigned char copy = (header>> 3)&1; + + hh->ParamList["AudioType"] = + string_printf("%s (%s/%s) %s", modenames[mode], sampfreqnames[sampfreq], + layernames[layer], copy?"c":""); + } + return ""; +} +//------------------------------------------------------------------------- +// Template 1:classname, 2:zAlarmTime, 3: zStopTime, 4:zRep, 5:zRepCouunt +// 6:zType, 7:sAddData, 8:timer->eventID, 9:timer->eventID +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_get_timer_list(CyhookHandler *, std::string para) +{ + std::string yresult; + CTimerd::TimerList timerlist; // List of bouquets + + timerlist.clear(); + NeutrinoAPI->Timerd->getTimerList(timerlist); + sort(timerlist.begin(), timerlist.end()); + + CZapitClient::BouquetChannelList channellist_tv; + CZapitClient::BouquetChannelList channellist_radio; + channellist_tv.clear(); + channellist_radio.clear(); + + int i = 1; + char classname= 'a'; + CTimerd::TimerList::iterator timer = timerlist.begin(); + for(; timer != timerlist.end();timer++) + { + classname = (i++&1)?'a':'b'; + + // build alarm/stoptime + char zAlarmTime[25] = {0}; + struct tm *alarmTime = localtime(&(timer->alarmTime)); + strftime(zAlarmTime,20,"%d.%m. %H:%M",alarmTime); + + char zAnnounceTime[25] = {0}; + struct tm *announceTime = localtime(&(timer->announceTime)); + strftime(zAnnounceTime,20,"%d.%m. %H:%M",announceTime); + + char zStopTime[25] = {0}; + if(timer->stopTime > 0) + { + struct tm *stopTime = localtime(&(timer->stopTime)); + strftime(zStopTime,20,"%d.%m. %H:%M",stopTime); + } + // repeat + std::string zRep = NeutrinoAPI->timerEventRepeat2Str(timer->eventRepeat); + std::string zRepCount; + if (timer->eventRepeat == CTimerd::TIMERREPEAT_ONCE) + zRepCount = "-"; + else + zRepCount = (timer->repeatCount == 0) ? "∞" : string_printf("%dx",timer->repeatCount); + // timer type + std::string zType = NeutrinoAPI->timerEventType2Str(timer->eventType); + // Add Data + std::string sAddData=""; + switch(timer->eventType) + { + case CTimerd::TIMER_NEXTPROGRAM : + case CTimerd::TIMER_ZAPTO : + case CTimerd::TIMER_RECORD : + { + sAddData = NeutrinoAPI->GetServiceName(timer->channel_id); + if (sAddData.empty()) + sAddData = NeutrinoAPI->Zapit->isChannelTVChannel(timer->channel_id) ? "Unbekannter TV-Kanal" : "Unbekannter Radiokanal"; + + if( timer->apids != TIMERD_APIDS_CONF) + { + std::string separator = ""; + sAddData += '('; + if( timer->apids & TIMERD_APIDS_STD ) + { + sAddData += "STD"; + separator = "/"; + } + if( timer->apids & TIMERD_APIDS_ALT ) + { + sAddData += separator; + sAddData += "ALT"; + separator = "/"; + } + if( timer->apids & TIMERD_APIDS_AC3 ) + { + sAddData += separator; + sAddData += "AC3"; + separator = "/"; + } + sAddData += ')'; + } + if(timer->epgID!=0) + { + CSectionsdClient sdc; + CEPGData epgdata; + if (sdc.getEPGid(timer->epgID, timer->epg_starttime, &epgdata)) + sAddData+="
" + epgdata.title; + else + sAddData+=std::string("
")+timer->epgTitle; + } + else + sAddData+=std::string("
")+timer->epgTitle; + } + break; + case CTimerd::TIMER_STANDBY : + { + sAddData = "Standby: "; + if(timer->standby_on) + sAddData+= "An"; + else + sAddData+="Aus"; + } + break; + case CTimerd::TIMER_REMIND : + sAddData = std::string(timer->message).substr(0,20); + break; + case CTimerd::TIMER_EXEC_PLUGIN : + sAddData = std::string(timer->pluginName); + break; + + default:{} + } + yresult += string_printf(para.c_str(), classname, zAlarmTime, zStopTime, zRep.c_str(), zRepCount.c_str(), + zType.c_str(), sAddData.c_str(),timer->eventID,timer->eventID); + } + classname = (i++&1)?'a':'b'; + + return yresult; +} +/*------------------------------------------------------------------------------ + CTimerd::TIMER_RECORD = 5 + CTimerd::TIMER_STANDBY = 4 + CTimerd::TIMER_NEXTPROGRAM = 2 + CTimerd::TIMER_ZAPTO = 3 + CTimerd::TIMER_REMIND = 6 + CTimerd::TIMER_EXEC_PLUGIN = 8 + CTimerd::TIMERREPEAT_WEEKDAYS = 256 + CTimerd::TIMERREPEAT_ONCE = 0 + */ +// para ::= [timerid] +std::string CNeutrinoYParser::func_set_timer_form(CyhookHandler *hh, std::string para) +{ + unsigned timerId=0; + std::string cmd, stimerid; + CTimerd::responseGetTimer timer; // Timer + time_t now_t = time(NULL); + ySplitString(para, " ", cmd, stimerid); + if(cmd != "new") + { + // init timerid + if(stimerid != "") + timerId = (unsigned)atoi(stimerid.c_str()); + + NeutrinoAPI->Timerd->getTimer(timer, timerId); + std::string zType = NeutrinoAPI->timerEventType2Str(timer.eventType); + + hh->ParamList["timerId"] = itoa(timerId); + hh->ParamList["zType"] = zType; + } + // Alarm/StopTime + struct tm *alarmTime = (cmd == "new") ? localtime(&now_t) : localtime(&(timer.alarmTime)); + + hh->ParamList["alarm_mday"] = string_printf("%02d", alarmTime->tm_mday); + hh->ParamList["alarm_mon"] = string_printf("%02d", alarmTime->tm_mon +1); + hh->ParamList["alarm_year"] = string_printf("%04d", alarmTime->tm_year + 1900); + hh->ParamList["alarm_hour"] = string_printf("%02d", alarmTime->tm_hour); + hh->ParamList["alarm_min"] = string_printf("%02d", alarmTime->tm_min); + + struct tm *stopTime = (cmd == "new") ? alarmTime : ( (timer.stopTime > 0) ? localtime(&(timer.stopTime)) : NULL ); + if(stopTime != NULL) + { + hh->ParamList["stop_mday"] = string_printf("%02d", stopTime->tm_mday); + hh->ParamList["stop_mon"] = string_printf("%02d", stopTime->tm_mon +1); + hh->ParamList["stop_year"] = string_printf("%04d", stopTime->tm_year + 1900); + hh->ParamList["stop_hour"] = string_printf("%02d", stopTime->tm_hour); + hh->ParamList["stop_min"] = string_printf("%02d", stopTime->tm_min); + + // APid settings for Record + if(timer.apids == TIMERD_APIDS_CONF) + hh->ParamList["TIMERD_APIDS_CONF"] = "y"; + if(timer.apids & TIMERD_APIDS_STD) + hh->ParamList["TIMERD_APIDS_STD"] = "y"; + if(timer.apids & TIMERD_APIDS_ALT) + hh->ParamList["TIMERD_APIDS_ALT"] = "y"; + if(timer.apids & TIMERD_APIDS_AC3) + hh->ParamList["TIMERD_APIDS_AC3"] = "y"; + } + else + hh->ParamList["stop_mday"] = "0"; + // event type + std::string sel; + for(int i=1; i<=8;i++) + { + if(i!=(int)CTimerd::TIMER_NEXTPROGRAM) + { + std::string zType = NeutrinoAPI->timerEventType2Str((CTimerd::CTimerEventTypes) i); + if(cmd != "new") + sel = (i==(int)timer.eventType) ? "selected=\"selected\"" : ""; + else + sel = (i==(int)CTimerd::TIMER_RECORD) ? "selected=\"selected\"" : ""; + hh->ParamList["timertype"] += + string_printf("\n",i,sel.c_str(),zRep.c_str()); + } + } + // Repeat Weekdays + zRep = NeutrinoAPI->timerEventRepeat2Str(CTimerd::TIMERREPEAT_WEEKDAYS); + if(timer.eventRepeat >= CTimerd::TIMERREPEAT_WEEKDAYS && cmd != "new") + sel = "selected=\"selected\""; + else + sel = ""; + hh->ParamList["repeat"] += + string_printf("\n",(int)CTimerd::TIMERREPEAT_WEEKDAYS, sel.c_str(), zRep.c_str()); + + // Weekdays + char weekdays[8]; + NeutrinoAPI->Timerd->setWeekdaysToStr(timer.eventRepeat, weekdays); + hh->ParamList["weekdays"]= weekdays; + + // timer repeats + if (timer.eventRepeat == CTimerd::TIMERREPEAT_ONCE) + hh->ParamList["TIMERREPEAT_ONCE"] = "y"; + hh->ParamList["timer_repeatCount"] = itoa(timer.repeatCount); + + // program row + t_channel_id current_channel = (cmd == "new") ? live_channel_id /*NeutrinoAPI->Zapit->getCurrentServiceID()*/ : timer.channel_id; + CBouquetManager::ChannelIterator cit = g_bouquetManager->tvChannelsBegin(); + for (; !(cit.EndOfChannels()); cit++) { + sel = ((*cit)->channel_id == current_channel) ? "selected=\"selected\"" : ""; + hh->ParamList["program_row"] += + string_printf("\n", + (*cit)->channel_id, sel.c_str(), (*cit)->getName().c_str()); + } + cit = g_bouquetManager->radioChannelsBegin(); + for (; !(cit.EndOfChannels()); cit++) { + sel = ((*cit)->channel_id == current_channel) ? "selected=\"selected\"" : ""; + hh->ParamList["program_row"] += + string_printf("\n", + (*cit)->channel_id, sel.c_str(), (*cit)->getName().c_str()); + } + // recordingDir + hh->ParamList["RECORD_DIR_MAXLEN"] = itoa(RECORD_DIR_MAXLEN-1); + if(cmd != "new") { + if(timer.eventType == CTimerd::TIMER_RECORD) + hh->ParamList["timer_recordingDir"] = timer.recordingDir; + } + else + { + // get Default Recordingdir + CConfigFile *Config = new CConfigFile(','); + Config->loadConfig(NEUTRINO_CONFIGFILE); + hh->ParamList["timer_recordingDir"] = Config->getString("network_nfs_recordingdir", "/mnt/filme"); + delete Config; + } + hh->ParamList["standby"] = (cmd == "new")? "0" : ((timer.standby_on)?"1":"0"); + hh->ParamList["message"] = (cmd == "new")? "" : timer.message; + hh->ParamList["pluginname"] = (cmd == "new")? "" : timer.pluginName; + + return ""; +} + +//------------------------------------------------------------------------- +// func: Bouquet Editor List +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_bouquet_editor_main(CyhookHandler *hh, std::string para) +{ + std::string yresult; + int selected = -1; + if (hh->ParamList["saved"] == "1") + hh->ParamList["have_saved"]="true"; + + if (hh->ParamList["selected"] != "") + selected = atoi(hh->ParamList["selected"].c_str()); + + int bouquetSize = (int) g_bouquetManager->Bouquets.size(); + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) { + + CZapitBouquet * bouquet = g_bouquetManager->Bouquets[i]; + + char classname = ((i & 1) == 0) ? 'a' : 'b'; + classname = (selected == (int) i + 1)?'c':classname; + + std::string akt = (selected == (int) (i + 1)) ? "" : ""; + // lock/unlock + std::string lock_action = (bouquet->bLocked) ? "unlock" : "lock"; + std::string lock_img = (bouquet->bLocked) ? "lock" : "unlock"; + std::string lock_alt = (bouquet->bLocked) ? "entsperren" : "sperren"; + // hide/show + std::string hidden_action= (bouquet->bHidden) ? "show" : "hide"; + std::string hidden_img = (bouquet->bHidden) ? "hidden" : "visible"; + std::string hidden_alt = (bouquet->bHidden) ? "verstecken" : "anzeigen"; + // move down + std::string down_show = (i + 1 < bouquetSize) ? "visible" : "hidden"; + //move up + std::string up_show = (i > 0) ? "visible" : "hidden"; + // build from template + yresult += string_printf(para.c_str(), classname, akt.c_str(), + i + 1, lock_action.c_str(), lock_img.c_str(), lock_alt.c_str(), //lock + i + 1, hidden_action.c_str(), hidden_img.c_str(), hidden_alt.c_str(), //hhidden + i + 1, bouquet->Name.c_str(), bouquet->Name.c_str(), //link + i + 1, bouquet->Name.c_str(), //rename + i + 1, bouquet->Name.c_str(), //delete + down_show.c_str(), i + 1, //down arrow + up_show.c_str(), i + 1); //up arrow + } + return yresult; +} + +//------------------------------------------------------------------------- +// func: Bouquet Edit +//------------------------------------------------------------------------- +std::string CNeutrinoYParser::func_set_bouquet_edit_form(CyhookHandler *hh, std::string) +{ + if (!(hh->ParamList["selected"].empty())) + { + int selected = atoi(hh->ParamList["selected"].c_str()) - 1; + int mode = NeutrinoAPI->Zapit->getMode(); + ZapitChannelList* channels = mode == CZapitClient::MODE_TV ? &(g_bouquetManager->Bouquets[selected]->tvChannels) : &(g_bouquetManager->Bouquets[selected]->radioChannels); + for(int j = 0; j < (int) channels->size(); j++) { + hh->ParamList["bouquet_channels"] += + string_printf("\n", + (*channels)[j]->channel_id, + (*channels)[j]->getName().c_str()); + } + ZapitChannelList Channels; + Channels.clear(); + if (mode == CZapitClient::MODE_RADIO) { + for (tallchans_iterator it = allchans.begin(); it != allchans.end(); it++) + if (it->second.getServiceType() == ST_DIGITAL_RADIO_SOUND_SERVICE) + Channels.push_back(&(it->second)); + } else { + for (tallchans_iterator it = allchans.begin(); it != allchans.end(); it++) + if (it->second.getServiceType() != ST_DIGITAL_RADIO_SOUND_SERVICE) + Channels.push_back(&(it->second)); + } + sort(Channels.begin(), Channels.end(), CmpChannelByChName()); + + for (int i = 0; i < (int) Channels.size(); i++) { + if (!g_bouquetManager->existsChannelInBouquet(selected, Channels[i]->channel_id)){ + hh->ParamList["all_channels"] += + string_printf("\n", + Channels[i]->channel_id, + Channels[i]->getName().c_str()); + } + } + return ""; + } + else + return "No Bouquet selected"; +} diff --git a/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.h b/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.h new file mode 100644 index 000000000..126a84e7e --- /dev/null +++ b/src/nhttpd/tuxboxapi/coolstream/neutrinoyparser.h @@ -0,0 +1,70 @@ +//============================================================================= +// NHTTPD +// Neutrino yParser Extenstion +//============================================================================= + +#ifndef __nhttpd_neutrinoyparser_h__ +#define __nhttpd_neutrinoyparser_h__ + +// c++ +#include +// yhttpd +#include "yhttpd.h" +#include "ytypes_globals.h" +#include "mod_yparser.h" + +// forward declaration +class CNeutrinoAPI; +//----------------------------------------------------------------------------- +class CNeutrinoYParser : public CyParser +{ +private: + // yParser funcs for Tuxbox + typedef std::string (CNeutrinoYParser::*TyFunc)(CyhookHandler *hh, std::string para); + typedef struct + { + const char *func_name; + TyFunc pfunc; + } TyFuncCall; + const static TyFuncCall yFuncCallList[]; + + // func TUXBOX + std::string func_mount_get_list(CyhookHandler *hh, std::string para); + std::string func_mount_set_values(CyhookHandler *hh, std::string para); + std::string func_get_bouquets_as_dropdown(CyhookHandler *hh, std::string para); + std::string func_get_bouquets_as_templatelist(CyhookHandler *hh, std::string para); + std::string func_get_actual_bouquet_number(CyhookHandler *hh, std::string para); + std::string func_get_channels_as_dropdown(CyhookHandler *hh, std::string para); + std::string func_get_actual_channel_id(CyhookHandler *hh, std::string para); + std::string func_get_bouquets_with_epg(CyhookHandler *hh, std::string para); + std::string func_get_mode(CyhookHandler *hh, std::string para); + std::string func_get_video_pids(CyhookHandler *hh, std::string para); + std::string func_get_radio_pid(CyhookHandler *hh, std::string para); + std::string func_get_audio_pids_as_dropdown(CyhookHandler *hh, std::string para); + std::string func_unmount_get_list(CyhookHandler *hh, std::string para); + std::string func_get_partition_list(CyhookHandler *hh, std::string para); + std::string func_get_boxtype(CyhookHandler *hh, std::string para); + std::string func_get_current_stream_info(CyhookHandler *hh, std::string para); + std::string func_get_timer_list(CyhookHandler *hh, std::string para); + std::string func_set_timer_form(CyhookHandler *hh, std::string para); + std::string func_bouquet_editor_main(CyhookHandler *hh, std::string para); + std::string func_set_bouquet_edit_form(CyhookHandler *hh, std::string para); + +protected: + CNeutrinoAPI *NeutrinoAPI; + +public: + // constructor & deconstructor + CNeutrinoYParser(CNeutrinoAPI *_NeutrinoAPI); + virtual ~CNeutrinoYParser(void); + + // virtual functions for BaseClass + virtual std::string YWeb_cgi_func(CyhookHandler *hh, std::string ycmd); + // virtual functions for HookHandler/Hook + virtual std::string getHookName(void) {return std::string("mod_NeutrinoYParser-Coolstream");} + virtual std::string getHookVersion(void) {return std::string("$Revision: 1.1.2.1 $");} + virtual THandleStatus Hook_SendResponse(CyhookHandler *hh); + virtual THandleStatus Hook_ReadConfig(CConfigFile *Config, CStringList &ConfigList); +}; + +#endif /*__nhttpd_neutrinoyparser_h__*/