/* * $Header: /cvs/tuxbox/apps/dvb/zapit/lib/zapitclient.cpp,v 1.105 2004/10/27 16:08:41 lucgas Exp $ * * * Zapit client interface - DBoxII-Project * * (C) 2002 by thegoodguy & the DBoxII-Project * * License: GPL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include /* libevent */ #include #include #include #include unsigned char CZapitClient::getVersion() const { return CZapitMessages::ACTVERSION; } const char * CZapitClient::getSocketName() const { return ZAPIT_UDS_NAME; } void CZapitClient::shutdown() { send(CZapitMessages::CMD_SHUTDOWN); close_connection(); } //***********************************************/ /* */ /* general functions for zapping */ /* */ /***********************************************/ /* zaps to channel of specified bouquet */ /* bouquets are numbered starting at 0 */ void CZapitClient::zapTo(const unsigned int bouquet, const unsigned int channel) { CZapitMessages::commandZapto msg; msg.bouquet = bouquet; msg.channel = channel - 1; send(CZapitMessages::CMD_ZAPTO, (char*)&msg, sizeof(msg)); close_connection(); } /* zaps to channel by nr */ void CZapitClient::zapTo(const unsigned int channel) { CZapitMessages::commandZaptoChannelNr msg; msg.channel = channel - 1; send(CZapitMessages::CMD_ZAPTO_CHANNELNR, (const char *) & msg, sizeof(msg)); close_connection(); } t_channel_id CZapitClient::getCurrentServiceID() { send(CZapitMessages::CMD_GET_CURRENT_SERVICEID); CZapitMessages::responseGetCurrentServiceID response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response.channel_id; } CZapitClient::CCurrentServiceInfo CZapitClient::getCurrentServiceInfo() { send(CZapitMessages::CMD_GET_CURRENT_SERVICEINFO); CZapitClient::CCurrentServiceInfo response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response; } void CZapitClient::getLastChannel(t_channel_id &channel_id, int &mode) { send(CZapitMessages::CMD_GET_LAST_CHANNEL); CZapitClient::responseGetLastChannel response; CBasicClient::receive_data((char* )&response, sizeof(response)); channel_id = response.channel_id; mode = response.mode; close_connection(); } int32_t CZapitClient::getCurrentSatellitePosition(void) { send(CZapitMessages::CMD_GET_CURRENT_SATELLITE_POSITION); int32_t response; CBasicClient::receive_data((char *)&response, sizeof(response)); close_connection(); return response; } void CZapitClient::setAudioChannel(const unsigned int channel) { CZapitMessages::commandSetAudioChannel msg; msg.channel = channel; send(CZapitMessages::CMD_SET_AUDIOCHAN, (const char *) & msg, sizeof(msg)); close_connection(); } /* zaps to onid_sid, returns the "zap-status" */ unsigned int CZapitClient::zapTo_serviceID(const t_channel_id channel_id) { CZapitMessages::commandZaptoServiceID msg; msg.channel_id = channel_id; msg.record = false; send(CZapitMessages::CMD_ZAPTO_SERVICEID, (const char *) & msg, sizeof(msg)); CZapitMessages::responseZapComplete response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response.zapStatus; } unsigned int CZapitClient::zapTo_record(const t_channel_id channel_id) { CZapitMessages::commandZaptoServiceID msg; msg.channel_id = channel_id; msg.record = true; send(CZapitMessages::CMD_ZAPTO_SERVICEID, (const char *) & msg, sizeof(msg)); CZapitMessages::responseZapComplete response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response.zapStatus; } unsigned int CZapitClient::zapTo_subServiceID(const t_channel_id channel_id) { CZapitMessages::commandZaptoServiceID msg; msg.channel_id = channel_id; send(CZapitMessages::CMD_ZAPTO_SUBSERVICEID, (const char *) & msg, sizeof(msg)); CZapitMessages::responseZapComplete response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response.zapStatus; } /* zaps to channel, does NOT wait for completion (uses event) */ void CZapitClient::zapTo_serviceID_NOWAIT(const t_channel_id channel_id) { CZapitMessages::commandZaptoServiceID msg; msg.channel_id = channel_id; send(CZapitMessages::CMD_ZAPTO_SERVICEID_NOWAIT, (const char *) & msg, sizeof(msg)); close_connection(); } /* zaps to subservice, does NOT wait for completion (uses event) */ void CZapitClient::zapTo_subServiceID_NOWAIT(const t_channel_id channel_id) { CZapitMessages::commandZaptoServiceID msg; msg.channel_id = channel_id; send(CZapitMessages::CMD_ZAPTO_SUBSERVICEID_NOWAIT, (const char *) & msg, sizeof(msg)); close_connection(); } void CZapitClient::setMode(const channelsMode mode) { CZapitMessages::commandSetMode msg; msg.mode = mode; send(CZapitMessages::CMD_SET_MODE, (const char *) & msg, sizeof(msg)); close_connection(); } int CZapitClient::getMode() { send(CZapitMessages::CMD_GET_MODE); CZapitMessages::responseGetMode response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response.mode; } void CZapitClient::setSubServices( subServiceList& subServices ) { unsigned int i; send(CZapitMessages::CMD_SETSUBSERVICES); for (i = 0; i< subServices.size(); i++) send_data((char*)&subServices[i], sizeof(subServices[i])); close_connection(); } void CZapitClient::getPIDS(responseGetPIDs& pids) { CZapitMessages::responseGeneralInteger responseInteger; responseGetAPIDs responseAPID; send(CZapitMessages::CMD_GETPIDS); CBasicClient::receive_data((char* )&(pids.PIDs), sizeof(pids.PIDs)); pids.APIDs.clear(); if (CBasicClient::receive_data((char* )&responseInteger, sizeof(responseInteger))) { pids.APIDs.reserve(responseInteger.number); while (responseInteger.number-- > 0) { CBasicClient::receive_data((char*)&responseAPID, sizeof(responseAPID)); pids.APIDs.push_back(responseAPID); }; } close_connection(); } void CZapitClient::zaptoNvodSubService(const int num) { CZapitMessages::commandInt msg; msg.val = num; send(CZapitMessages::CMD_NVOD_SUBSERVICE_NUM, (const char *) & msg, sizeof(msg)); close_connection(); } /* gets all bouquets */ /* bouquets are numbered starting at 0 */ void CZapitClient::getBouquets(BouquetList& bouquets, const bool emptyBouquetsToo, const bool utf_encoded, channelsMode mode) { char buffer[30 + 1]; CZapitMessages::commandGetBouquets msg; msg.emptyBouquetsToo = emptyBouquetsToo; msg.mode = mode; send(CZapitMessages::CMD_GET_BOUQUETS, (char*)&msg, sizeof(msg)); responseGetBouquets response; while (CBasicClient::receive_data((char*)&response, sizeof(responseGetBouquets))) { if (response.bouquet_nr == RESPONSE_GET_BOUQUETS_END_MARKER) break; if (!utf_encoded) { buffer[30] = (char) 0x00; strncpy(buffer, response.name, 30); strncpy(response.name, ZapitTools::UTF8_to_Latin1(buffer).c_str(), 30); } bouquets.push_back(response); } close_connection(); } bool CZapitClient::receive_channel_list(BouquetChannelList& channels, const bool utf_encoded) { CZapitMessages::responseGeneralInteger responseInteger; responseGetBouquetChannels response; channels.clear(); if (CBasicClient::receive_data((char* )&responseInteger, sizeof(responseInteger))) { channels.reserve(responseInteger.number); while (responseInteger.number-- > 0) { if (!CBasicClient::receive_data((char*)&response, sizeof(responseGetBouquetChannels))) return false; response.nr++; if (!utf_encoded) { char buffer[CHANNEL_NAME_SIZE + 1]; buffer[CHANNEL_NAME_SIZE] = (char) 0x00; strncpy(buffer, response.name, CHANNEL_NAME_SIZE); strncpy(response.name, ZapitTools::UTF8_to_Latin1(buffer).c_str(), CHANNEL_NAME_SIZE); } channels.push_back(response); } } return true; } bool CZapitClient::receive_nchannel_list(BouquetNChannelList& channels) { CZapitMessages::responseGeneralInteger responseInteger; responseGetBouquetNChannels response; channels.clear(); if (CBasicClient::receive_data((char* )&responseInteger, sizeof(responseInteger))) { channels.reserve(responseInteger.number); while (responseInteger.number-- > 0) { if (!CBasicClient::receive_data((char*)&response, sizeof(responseGetBouquetNChannels))) return false; response.nr++; channels.push_back(response); } } return true; } /* gets all channels that are in specified bouquet */ /* bouquets are numbered starting at 0 */ bool CZapitClient::getBouquetChannels(const unsigned int bouquet, BouquetChannelList& channels, channelsMode mode, const bool utf_encoded) { bool return_value; CZapitMessages::commandGetBouquetChannels msg; msg.bouquet = bouquet; msg.mode = mode; return_value = (send(CZapitMessages::CMD_GET_BOUQUET_CHANNELS, (char*)&msg, sizeof(msg))) ? receive_channel_list(channels, utf_encoded) : false; close_connection(); return return_value; } bool CZapitClient::getBouquetNChannels(const unsigned int bouquet, BouquetNChannelList& channels, channelsMode mode, const bool /*utf_encoded*/) { bool return_value; CZapitMessages::commandGetBouquetChannels msg; msg.bouquet = bouquet; msg.mode = mode; return_value = (send(CZapitMessages::CMD_GET_BOUQUET_NCHANNELS, (char*)&msg, sizeof(msg))) ? receive_nchannel_list(channels) : false; close_connection(); return return_value; } /* gets all channels */ bool CZapitClient::getChannels( BouquetChannelList& channels, channelsMode mode, channelsOrder order, const bool utf_encoded) { bool return_value; CZapitMessages::commandGetChannels msg; msg.mode = mode; msg.order = order; return_value = (send(CZapitMessages::CMD_GET_CHANNELS, (char*)&msg, sizeof(msg))) ? receive_channel_list(channels, utf_encoded) : false; close_connection(); return return_value; } /* request information about a particular channel_id */ /* channel name */ std::string CZapitClient::getChannelName(const t_channel_id channel_id) { send(CZapitMessages::CMD_GET_CHANNEL_NAME, (char *) & channel_id, sizeof(channel_id)); CZapitMessages::responseGetChannelName response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return std::string(response.name); } /* is channel a TV channel ? */ bool CZapitClient::isChannelTVChannel(const t_channel_id channel_id) { send(CZapitMessages::CMD_IS_TV_CHANNEL, (char *) & channel_id, sizeof(channel_id)); CZapitMessages::responseGeneralTrueFalse response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); return response.status; } /* restore bouquets so as if they were just loaded */ void CZapitClient::restoreBouquets() { send(CZapitMessages::CMD_BQ_RESTORE); CZapitMessages::responseCmd response; CBasicClient::receive_data((char* )&response, sizeof(response)); close_connection(); } /* reloads channels and services*/ void CZapitClient::reinitChannels() { send(CZapitMessages::CMD_REINIT_CHANNELS); CZapitMessages::responseCmd response; CBasicClient::receive_data((char* )&response, sizeof(response), true); close_connection(); } //called when sectionsd updates currentservices.xml void CZapitClient::reloadCurrentServices() { send(CZapitMessages::CMD_RELOAD_CURRENTSERVICES); #if 0 CZapitMessages::responseCmd response; CBasicClient::receive_data((char* )&response, sizeof(response), true); #endif close_connection(); } void CZapitClient::muteAudio(const bool mute) { CZapitMessages::commandBoolean msg; msg.truefalse = mute; send(CZapitMessages::CMD_MUTE, (char*)&msg, sizeof(msg)); close_connection(); } // Get mute status bool CZapitClient::getMuteStatus() { CZapitMessages::commandBoolean msg; send(CZapitMessages::CMD_GET_MUTE_STATUS, (char*)&msg, sizeof(msg)); CBasicClient::receive_data((char*)&msg, sizeof(msg)); close_connection(); return msg.truefalse; } void CZapitClient::setVolume(const unsigned int left, const unsigned int right) { CZapitMessages::commandVolume msg; msg.left = left; msg.right = right; send(CZapitMessages::CMD_SET_VOLUME, (char*)&msg, sizeof(msg)); close_connection(); } void CZapitClient::getVolume(unsigned int *left, unsigned int *right) { CZapitMessages::commandVolume msg; send(CZapitMessages::CMD_GET_VOLUME, 0, 0); CBasicClient::receive_data((char*)&msg, sizeof(msg)); *left = msg.left; *right = msg.right; close_connection(); } delivery_system_t CZapitClient::getDeliverySystem(void) { send(CZapitMessages::CMD_GET_DELIVERY_SYSTEM, 0, 0); CZapitMessages::responseDeliverySystem response; if (!CBasicClient::receive_data((char* )&response, sizeof(response))) response.system = DVB_S; // return DVB_S if communication fails close_connection(); return response.system; } #if 0 bool CZapitClient::get_current_TP(TP_params* TP) { TP_params TP_temp; send(CZapitMessages::CMD_GET_CURRENT_TP); bool reply = CBasicClient::receive_data((char*)&TP_temp, sizeof(TP_temp)); memmove(TP, &TP_temp, sizeof(TP_temp)); close_connection(); return reply; } #endif /* sends diseqc 1.2 motor command */ void CZapitClient::sendMotorCommand(uint8_t cmdtype, uint8_t address, uint8_t cmd, uint8_t num_parameters, uint8_t param1, uint8_t param2) { CZapitMessages::commandMotor msg; msg.cmdtype = cmdtype; msg.address = address; msg.cmd = cmd; msg.num_parameters = num_parameters; msg.param1 = param1; msg.param2 = param2; send(CZapitMessages::CMD_SEND_MOTOR_COMMAND, (char*)&msg, sizeof(msg)); close_connection(); } /***********************************************/ /* */ /* Scanning stuff */ /* */ /***********************************************/ /* start TS-Scan */ bool CZapitClient::startScan(const int scan_mode) { bool reply = send(CZapitMessages::CMD_SCANSTART, (char*)&scan_mode, sizeof(scan_mode)); close_connection(); return reply; } bool CZapitClient::stopScan() { bool reply = send(CZapitMessages::CMD_SCANSTOP); close_connection(); return reply; } #if 0 bool CZapitClient::setConfig(Zapit_config Cfg) { //bool reply = send(CZapitMessages::CMD_LOADCONFIG); bool reply = send(CZapitMessages::CMD_SETCONFIG, (char*)&Cfg, sizeof(Cfg)); close_connection(); return reply; } void CZapitClient::getConfig (Zapit_config * Cfg) { send(CZapitMessages::CMD_GETCONFIG); CBasicClient::receive_data((char *) Cfg, sizeof(Zapit_config)); close_connection(); } #endif bool CZapitClient::Rezap() { bool reply = send(CZapitMessages::CMD_REZAP); close_connection(); return reply; } /* start manual scan */ bool CZapitClient::scan_TP(TP_params TP) { bool reply = send(CZapitMessages::CMD_SCAN_TP, (char*)&TP, sizeof(TP)); close_connection(); return reply; } bool CZapitClient::tune_TP(TP_params TP) { bool reply = send(CZapitMessages::CMD_TUNE_TP, (char*)&TP, sizeof(TP)); close_connection(); return reply; } /* query if ts-scan is ready - response gives status */ bool CZapitClient::isScanReady(unsigned int &satellite, unsigned int &processed_transponder, unsigned int &transponder, unsigned int &services ) { send(CZapitMessages::CMD_SCANREADY); CZapitMessages::responseIsScanReady response; CBasicClient::receive_data((char* )&response, sizeof(response)); satellite = response.satellite; processed_transponder = response.processed_transponder; transponder = response.transponder; services = response.services; close_connection(); return response.scanReady; } /* query possible satellits*/ void CZapitClient::getScanSatelliteList(SatelliteList& satelliteList) { uint32_t satlength; send(CZapitMessages::CMD_SCANGETSATLIST); responseGetSatelliteList response; while (CBasicClient::receive_data((char*)&satlength, sizeof(satlength))) { if (satlength == SATNAMES_END_MARKER) break; if (!CBasicClient::receive_data((char*)&(response), satlength)) break; satelliteList.push_back(response); } close_connection(); } /* tell zapit which satellites to scan*/ void CZapitClient::setScanSatelliteList( ScanSatelliteList& satelliteList ) { send(CZapitMessages::CMD_SCANSETSCANSATLIST); for (uint32_t i=0; i