static void rpi_tv_vpi(vpi_op_t op, struct htsmsg *info, struct prop *p, struct prop *origin) { if(!respond) return; if(op == VPI_START) { double framerate; unsigned int width, height; if(htsmsg_get_dbl(info, "framerate", &framerate)) return; if(htsmsg_get_u32(info, "width", &width)) return; if(htsmsg_get_u32(info, "height", &height)) return; rpi_set_display_framerate(framerate, width, height); restart_ui = 1; } if(op == VPI_STOP) { vc_tv_hdmi_power_on_preferred(); restart_ui = 1; } }
/* Initialise */ void tvhtime_init ( void ) { htsmsg_t *m = hts_settings_load("tvhtime/config"); if (htsmsg_get_u32(m, "update_enabled", &tvhtime_update_enabled)) tvhtime_update_enabled = 0; if (htsmsg_get_u32(m, "ntp_enabled", &tvhtime_ntp_enabled)) tvhtime_ntp_enabled = 0; if (htsmsg_get_u32(m, "tolerance", &tvhtime_tolerance)) tvhtime_tolerance = 5000; }
static void htsp_channelAddUpdate(htsp_connection_t *hc, htsmsg_t *m, int create) { uint32_t id, next; int chnum; char txt[200]; const char *title, *icon; htsp_channel_t *ch; if(htsmsg_get_u32(m, "channelId", &id)) return; title = htsmsg_get_str(m, "channelName"); icon = htsmsg_get_str(m, "channelIcon"); chnum = htsmsg_get_s32_or_default(m, "channelNumber", -1); snprintf(txt, sizeof(txt), "%d", id); hts_mutex_lock(&hc->hc_meta_mutex); if(create) { ch = htsp_channel_get(hc, id, 1); if(prop_set_parent(ch->ch_root, hc->hc_channels_nodes)) abort(); } else { ch = htsp_channel_get(hc, id, 0); if(ch == NULL) { TRACE(TRACE_ERROR, "HTSP", "Got update for unknown channel %d", id); hts_mutex_unlock(&hc->hc_meta_mutex); return; } } hts_mutex_unlock(&hc->hc_meta_mutex); if(icon != NULL) prop_set_string(ch->ch_prop_icon, icon); if(title != NULL) { mystrset(&ch->ch_title, title); prop_set_string(ch->ch_prop_title, title); } if(chnum != -1) prop_set_int(ch->ch_prop_channelNumber, chnum); if(htsmsg_get_u32(m, "eventId", &id)) id = 0; if(htsmsg_get_u32(m, "nextEventId", &next)) next = 0; update_events(hc, ch->ch_prop_events, id, next); }
PVR_ERROR cHTSPData::AddTimer(const PVR_TIMERINFO &timerinfo) { XBMC->Log(LOG_DEBUG, "%s - id=%d", __FUNCTION__, timerinfo.index); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "addDvrEntry"); htsmsg_add_u32(msg, "eventId", timerinfo.index); htsmsg_add_str(msg, "title", timerinfo.title); htsmsg_add_u32(msg, "starttime", timerinfo.starttime); htsmsg_add_u32(msg, "endtime", timerinfo.endtime); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get addDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
bool CHTSPData::GetBackendTime(time_t *utcTime, int *gmtOffset) { htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "getSysTime"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_ERROR, "%s - failed to get sysTime", __FUNCTION__); return false; } unsigned int secs; if (htsmsg_get_u32(msg, "time", &secs) != 0) return false; int offset; if (htsmsg_get_s32(msg, "timezone", &offset) != 0) return false; XBMC->Log(LOG_DEBUG, "%s - tvheadend reported time=%u, timezone=%d, correction=%d" , __FUNCTION__, secs, offset); *utcTime = secs; *gmtOffset = offset; return true; }
bool cHTSPData::GetTime(time_t *localTime, int *gmtOffset) { XBMC->Log(LOG_DEBUG, "%s", __FUNCTION__); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "getSysTime"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_ERROR, "%s - failed to get sysTime", __FUNCTION__); return false; } unsigned int secs; if (htsmsg_get_u32(msg, "time", &secs) != 0) return false; int offset; if (htsmsg_get_s32(msg, "timezone", &offset) != 0) return false; XBMC->Log(LOG_DEBUG, "%s - tvheadend reported time=%u, timezone=%d, correction=%d" , __FUNCTION__, secs, offset, g_iEpgOffsetCorrection * 60); /* XBMC needs the timezone difference in seconds from GMT */ offset = (offset - (g_iEpgOffsetCorrection * 60)) * 60; *localTime = secs + offset; *gmtOffset = -offset; return true; }
PVR_ERROR CHTSPData::UpdateTimer(const PVR_TIMER &timer) { XBMC->Log(LOG_DEBUG, "%s - channelUid=%d title=%s epgid=%d", __FUNCTION__, timer.iClientChannelUid, timer.strTitle, timer.iEpgUid); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "updateDvrEntry"); htsmsg_add_u32(msg, "id", timer.iClientIndex); htsmsg_add_str(msg, "title", timer.strTitle); htsmsg_add_u32(msg, "start", timer.startTime); htsmsg_add_u32(msg, "stop", timer.endTime); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get updateDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_SAVED; }
PVR_ERROR CHTSPData::DeleteTimer(const PVR_TIMER &timer, bool bForce) { XBMC->Log(LOG_DEBUG, "%s", __FUNCTION__); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "cancelDvrEntry"); htsmsg_add_u32(msg, "id", timer.iClientIndex); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get cancelDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } const char *strError = NULL; if ((strError = htsmsg_get_str(msg, "error"))) { XBMC->Log(LOG_DEBUG, "%s - Error deleting timer: '%s'", __FUNCTION__, strError); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
/* * Intialise global file manager */ void timeshift_init ( void ) { htsmsg_t *m; const char *str; uint32_t u32; timeshift_filemgr_init(); /* Defaults */ timeshift_enabled = 0; // Disabled timeshift_ondemand = 0; // Permanent timeshift_path = NULL; // setting dir timeshift_unlimited_period = 0; timeshift_max_period = 3600; // 1Hr timeshift_unlimited_size = 0; timeshift_max_size = 10000 * (size_t)1048576; // 10G /* Load settings */ if ((m = hts_settings_load("timeshift/config"))) { if (!htsmsg_get_u32(m, "enabled", &u32)) timeshift_enabled = u32 ? 1 : 0; if (!htsmsg_get_u32(m, "ondemand", &u32)) timeshift_ondemand = u32 ? 1 : 0; if ((str = htsmsg_get_str(m, "path"))) timeshift_path = strdup(str); if (!htsmsg_get_u32(m, "unlimited_period", &u32)) timeshift_unlimited_period = u32 ? 1 : 0; htsmsg_get_u32(m, "max_period", ×hift_max_period); if (!htsmsg_get_u32(m, "unlimited_size", &u32)) timeshift_unlimited_size = u32 ? 1 : 0; if (!htsmsg_get_u32(m, "max_size", &u32)) timeshift_max_size = 1048576LL * u32; htsmsg_destroy(m); } }
static void htsp_channelDelete(htsp_connection_t *hc, htsmsg_t *m) { uint32_t id; htsp_channel_t *ch; if(htsmsg_get_u32(m, "channelId", &id)) return; hts_mutex_lock(&hc->hc_meta_mutex); if((ch = htsp_channel_get(hc, id, 0)) != NULL) channel_destroy(ch); hts_mutex_unlock(&hc->hc_meta_mutex); }
PVR_ERROR CHTSPData::AddTimer(const PVR_TIMER &timer) { XBMC->Log(LOG_DEBUG, "%s - channelUid=%d title=%s epgid=%d", __FUNCTION__, timer.iClientChannelUid, timer.strTitle, timer.iEpgUid); time_t startTime = timer.startTime; if (startTime <= 0) { int iGmtOffset; GetBackendTime(&startTime, &iGmtOffset); } htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "addDvrEntry"); htsmsg_add_u32(msg, "eventId", -1); // XXX tvheadend doesn't correct epg tags with wrong start and end times, so we'll use xbmc's values htsmsg_add_str(msg, "title", timer.strTitle); htsmsg_add_u32(msg, "start", startTime); htsmsg_add_u32(msg, "stop", timer.endTime); htsmsg_add_u32(msg, "channelId", timer.iClientChannelUid); htsmsg_add_u32(msg, "priority", timer.iPriority); htsmsg_add_str(msg, "description", timer.strSummary); htsmsg_add_str(msg, "creator", "XBMC"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get addDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } const char *strError = NULL; if ((strError = htsmsg_get_str(msg, "error"))) { XBMC->Log(LOG_DEBUG, "%s - Error adding timer: '%s'", __FUNCTION__, strError); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
PVR_ERROR CHTSPData::DeleteRecording(const PVR_RECORDING &recording) { XBMC->Log(LOG_DEBUG, "%s", __FUNCTION__); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "deleteDvrEntry"); htsmsg_add_u32(msg, "id", atoi(recording.strRecordingId)); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get deleteDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
PVR_ERROR cHTSPData::DeleteTimer(const PVR_TIMERINFO &timerinfo, bool force) { XBMC->Log(LOG_DEBUG, "%s", __FUNCTION__); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "deleteDvrEntry"); htsmsg_add_u32(msg, "id", timerinfo.index); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get deleteDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
PVR_ERROR cHTSPData::AddTimer(const PVR_TIMERINFO &timerinfo) { XBMC->Log(LOG_DEBUG, "%s - channelNumber=%d channelUid=%d title=%s epgid=%d", __FUNCTION__, timerinfo.channelUid, timerinfo.channelUid, timerinfo.title, timerinfo.epgid); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "addDvrEntry"); htsmsg_add_u32(msg, "eventId", timerinfo.epgid); htsmsg_add_str(msg, "title", timerinfo.title); htsmsg_add_u32(msg, "start", timerinfo.starttime); htsmsg_add_u32(msg, "stop", timerinfo.endtime); htsmsg_add_u32(msg, "channelId", timerinfo.channelUid); htsmsg_add_u32(msg, "priority", timerinfo.priority); htsmsg_add_str(msg, "description", timerinfo.description); htsmsg_add_str(msg, "creator", "XBMC"); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get addDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } const char *strError = NULL; if ((strError = htsmsg_get_str(msg, "error"))) { XBMC->Log(LOG_DEBUG, "%s - Error adding timer: '%s'", __FUNCTION__, strError); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_DELETED; }
PVR_ERROR CHTSPData::RenameRecording(const PVR_RECORDING &recording, const char *strNewName) { XBMC->Log(LOG_DEBUG, "%s - id=%s", __FUNCTION__, recording.strRecordingId); htsmsg_t *msg = htsmsg_create_map(); htsmsg_add_str(msg, "method", "updateDvrEntry"); htsmsg_add_u32(msg, "id", atoi(recording.strRecordingId)); htsmsg_add_str(msg, "title", recording.strTitle); if ((msg = ReadResult(msg)) == NULL) { XBMC->Log(LOG_DEBUG, "%s - Failed to get updateDvrEntry", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } unsigned int success; if (htsmsg_get_u32(msg, "success", &success) != 0) { XBMC->Log(LOG_DEBUG, "%s - Failed to parse param", __FUNCTION__); return PVR_ERROR_SERVER_ERROR; } return success > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_NOT_SAVED; }
DemuxPacket* cHTSPDemux::Read() { htsmsg_t * msg; const char* method; while((msg = ReadStream())) { method = htsmsg_get_str(msg, "method"); if(method == NULL) break; if (strcmp("subscriptionStart", method) == 0) { SubscriptionStart(msg); DemuxPacket* pkt = PVR->AllocateDemuxPacket(0); pkt->iStreamId = DMX_SPECIALID_STREAMCHANGE; htsmsg_destroy(msg); return pkt; } else if(strcmp("subscriptionStop", method) == 0) SubscriptionStop (msg); else if(strcmp("subscriptionStatus", method) == 0) SubscriptionStatus(msg); else if(strcmp("queueStatus" , method) == 0) cHTSPSession::ParseQueueStatus(msg, m_QueueStatus); else if(strcmp("signalStatus" , method) == 0) cHTSPSession::ParseSignalStatus(msg, m_Quality); else if(strcmp("muxpkt" , method) == 0) { uint32_t index, duration, frametype; const void* bin; size_t binlen; int64_t ts; char frametypechar[1]; htsmsg_get_u32(msg, "frametype", &frametype); frametypechar[0] = static_cast<char>( frametype ); // XBMC->Log(LOG_DEBUG, "%s - Frame type %c", __FUNCTION__, frametypechar[0]); if(htsmsg_get_u32(msg, "stream" , &index) || htsmsg_get_bin(msg, "payload", &bin, &binlen)) break; DemuxPacket* pkt = PVR->AllocateDemuxPacket(binlen); memcpy(pkt->pData, bin, binlen); pkt->iSize = binlen; if(!htsmsg_get_u32(msg, "duration", &duration)) pkt->duration = (double)duration * DVD_TIME_BASE / 1000000; if(!htsmsg_get_s64(msg, "dts", &ts)) pkt->dts = (double)ts * DVD_TIME_BASE / 1000000; else pkt->dts = DVD_NOPTS_VALUE; if(!htsmsg_get_s64(msg, "pts", &ts)) pkt->pts = (double)ts * DVD_TIME_BASE / 1000000; else pkt->pts = DVD_NOPTS_VALUE; pkt->iStreamId = -1; for(unsigned int i = 0; i < m_Streams.iStreamCount; i++) { if(m_Streams.stream[i].iPhysicalId == (unsigned int)index) { pkt->iStreamId = i; break; } } htsmsg_destroy(msg); return pkt; } break; } if(msg) { htsmsg_destroy(msg); DemuxPacket* pkt = PVR->AllocateDemuxPacket(0); return pkt; } return NULL; }
static int scanfile_load_dvbv5 ( scanfile_network_t *net, char *line, fb_file *fp ) { int res = 1, r = 1; char buf[256]; char *s, *t; const char *x; dvb_mux_conf_t *mux; htsmsg_t *l; /* validity check for [text] */ s = str_trim(line); if (s == '\0' || s[strlen(s) - 1] != ']') return 1; l = htsmsg_create_map(); /* Process file */ while (!fb_eof(fp)) { /* Get line */ buf[sizeof(buf)-1] = '\0'; if (!fb_gets(fp, buf, sizeof(buf) - 1)) break; s = str_trim(buf); if (*s == '#' || *s == '\0') continue; if (*s == '[') { res = 0; break; } if ((t = strchr(s, '=')) == NULL) continue; *t = '\0'; s = str_trim(s); t = str_trim(t + 1); htsmsg_add_str(l, s, t); } mux = malloc(sizeof(dvb_mux_conf_t)); mux->dmc_fe_delsys = -1; x = htsmsg_get_str(l, "DELIVERY_SYSTEM"); if (x && (mux->dmc_fe_delsys = dvb_str2delsys(x)) == -1) { if (!strcmp(s, "DVBC")) mux->dmc_fe_delsys = DVB_SYS_DVBC_ANNEX_A; } if (!x || (int)mux->dmc_fe_delsys < 0) mux_fail(r, "wrong system '%s'", x); dvb_mux_conf_init(mux, mux->dmc_fe_delsys); if (mux->dmc_fe_delsys == DVB_SYS_DVBT || mux->dmc_fe_delsys == DVB_SYS_DVBT2) { mux->u.dmc_fe_ofdm.bandwidth = DVB_BANDWIDTH_AUTO; mux->u.dmc_fe_ofdm.code_rate_HP = DVB_FEC_AUTO; mux->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE; mux->dmc_fe_modulation = DVB_MOD_QAM_64; mux->u.dmc_fe_ofdm.transmission_mode = DVB_TRANSMISSION_MODE_8K; mux->u.dmc_fe_ofdm.hierarchy_information = DVB_HIERARCHY_NONE; if ((x = htsmsg_get_str(l, "BANDWIDTH_HZ"))) { if (isdigit(x[0])) { /* convert to kHz */ int64_t ll = strtoll(x, NULL, 0); ll /= 1000; snprintf(buf, sizeof(buf), "%llu", (long long unsigned)ll); x = buf; } if ((mux->u.dmc_fe_ofdm.bandwidth = dvb_str2bw(x)) == -1) mux_fail(r, "wrong bandwidth '%s'", x); } if ((x = htsmsg_get_str(l, "CODE_RATE_HP"))) if ((mux->u.dmc_fe_ofdm.code_rate_HP = dvb_str2fec(x)) == -1) mux_fail(r, "wrong code rate HP '%s'", x); if ((x = htsmsg_get_str(l, "CODE_RATE_LP"))) if ((mux->u.dmc_fe_ofdm.code_rate_LP = dvb_str2fec(x)) == -1) mux_fail(r, "wrong code rate LP '%s'", x); if ((x = htsmsg_get_str(l, "MODULATION"))) if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1) mux_fail(r, "wrong modulation '%s'", x); if ((x = htsmsg_get_str(l, "TRANSMISSION_MODE"))) if ((mux->u.dmc_fe_ofdm.transmission_mode = dvb_str2mode(x)) == -1) mux_fail(r, "wrong transmission mode '%s'", x); if ((x = htsmsg_get_str(l, "GUARD_INTERVAL"))) if ((mux->u.dmc_fe_ofdm.guard_interval = dvb_str2guard(x)) == -1) mux_fail(r, "wrong guard interval '%s'", x); if ((x = htsmsg_get_str(l, "HIERARCHY"))) if ((mux->u.dmc_fe_ofdm.hierarchy_information = dvb_str2hier(x)) == -1) mux_fail(r, "wrong hierarchy '%s'", x); if ((x = htsmsg_get_str(l, "INVERSION"))) if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1) mux_fail(r, "wrong inversion '%s'", x); if (htsmsg_get_s32(l, "STREAM_ID", &mux->dmc_fe_stream_id)) mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; } else if (mux->dmc_fe_delsys == DVB_SYS_DVBS || mux->dmc_fe_delsys == DVB_SYS_DVBS2) { mux->dmc_fe_modulation = mux->dmc_fe_delsys == DVB_SYS_DVBS2 ? DVB_MOD_PSK_8 : DVB_MOD_QPSK; mux->u.dmc_fe_qpsk.fec_inner = DVB_FEC_AUTO; mux->dmc_fe_rolloff = DVB_ROLLOFF_35; if ((x = htsmsg_get_str(l, "MODULATION"))) if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1) mux_fail(r, "wrong modulation '%s'", x); if ((x = htsmsg_get_str(l, "INNER_FEC"))) if ((mux->u.dmc_fe_qpsk.fec_inner = dvb_str2fec(x)) == -1) mux_fail(r, "wrong inner FEC '%s'", x); if ((x = htsmsg_get_str(l, "INVERSION"))) if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1) mux_fail(r, "wrong inversion '%s'", x); if ((x = htsmsg_get_str(l, "ROLLOFF"))) if ((mux->dmc_fe_rolloff = dvb_str2rolloff(x)) == -1) mux_fail(r, "wrong rolloff '%s'", x); if ((x = htsmsg_get_str(l, "PILOT"))) if ((mux->dmc_fe_pilot = dvb_str2rolloff(x)) == -1) mux_fail(r, "wrong pilot '%s'", x); if (htsmsg_get_s32(l, "STREAM_ID", &r)) { mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; mux->dmc_fe_pls_mode = 0; mux->dmc_fe_pls_code = 1; } else { mux->dmc_fe_stream_id = r&0xff; mux->dmc_fe_pls_mode = (r>>26)&0x3; mux->dmc_fe_pls_code = (r>>8)&0x3FFFF; } if ((x = htsmsg_get_str(l, "POLARIZATION"))) { char pol[2]; pol[0] = x[0]; pol[1] = '\0'; if ((mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol)) == -1) mux_fail(r, "wrong polarisation '%s'", x); } else { mux_fail0(r, "dvb-s: undefined polarisation"); } if (htsmsg_get_u32(l, "SYMBOL_RATE", &mux->u.dmc_fe_qpsk.symbol_rate)) mux_fail0(r, "dvb-s: undefined symbol rate"); } else if (mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_A ||
static void update_events(htsp_connection_t *hc, prop_t *metadata, int id, int next) { int i; htsmsg_t *m; prop_t *events = prop_create(metadata, "list"); prop_t *current_event = prop_create(metadata, "current"); prop_t *next_event = prop_create(metadata, "next"); int linkstate = 0; htsmsg_field_t *f; if(id == 0) { if(next == 0) { // No events at all prop_destroy_childs(events); return; } id = next; linkstate = 1; } m = htsmsg_create_map(); htsmsg_add_str(m, "method", "getEvents"); htsmsg_add_u32(m, "eventId", id); htsmsg_add_u32(m, "numFollowing", EPG_TAIL); if((m = htsp_reqreply(hc, m)) != NULL) { htsmsg_t *events = htsmsg_get_list(m, "events"); f = events ? TAILQ_FIRST(&events->hm_fields) : NULL; } else { f = NULL; } for(i = 0; i < EPG_TAIL; i++) { char buf[10]; uint32_t u32; snprintf(buf, sizeof(buf), "%d", i); if(f != NULL && f->hmf_type != HMF_MAP) f = NULL; if(f != NULL) { m = htsmsg_get_map_by_field(f); prop_t *e = prop_create(events, buf); prop_set_string(prop_create(e, "title"), htsmsg_get_str(m, "title")); prop_set_string(prop_create(e, "description"), htsmsg_get_str(m, "description")); if(!htsmsg_get_u32(m, "start", &u32)) prop_set_int(prop_create(e, "start"), u32); if(!htsmsg_get_u32(m, "stop", &u32)) prop_set_int(prop_create(e, "stop"), u32); switch(linkstate) { case 0: prop_link(e, current_event); break; case 1: prop_link(e, next_event); break; } linkstate++; f = TAILQ_NEXT(f, hmf_link); continue; } prop_destroy_by_name(events, buf); switch(linkstate) { case 0: prop_unlink(current_event); break; case 1: prop_unlink(next_event); break; } linkstate++; } }
static htsmsg_t * htsp_reqreply(htsp_connection_t *hc, htsmsg_t *m) { void *buf; size_t len; uint32_t seq; int r; tcpcon_t *tc = hc->hc_tc; uint32_t noaccess; htsmsg_t *reply; htsp_msg_t *hm = NULL; int retry = 0; char id[100]; char *username; char *password; sha1_decl(shactx); uint8_t d[20]; if(tc == NULL) return NULL; /* Generate a sequence number for our message */ seq = atomic_add(&hc->hc_seq_generator, 1); htsmsg_add_u32(m, "seq", seq); again: snprintf(id, sizeof(id), "htsp://%s:%d", hc->hc_hostname, hc->hc_port); r = keyring_lookup(id, &username, &password, NULL, NULL, "TV client", "Access denied", (retry ? KEYRING_QUERY_USER : 0) | KEYRING_SHOW_REMEMBER_ME | KEYRING_REMEMBER_ME_SET); if(r == -1) { /* User rejected */ return NULL; } if(r == 0) { /* Got auth credentials */ htsmsg_delete_field(m, "username"); htsmsg_delete_field(m, "digest"); if(username != NULL) htsmsg_add_str(m, "username", username); if(password != NULL) { sha1_init(shactx); sha1_update(shactx, (const uint8_t *)password, strlen(password)); sha1_update(shactx, hc->hc_challenge, 32); sha1_final(shactx, d); htsmsg_add_bin(m, "digest", d, 20); } free(username); free(password); } if(htsmsg_binary_serialize(m, &buf, &len, -1) < 0) { htsmsg_destroy(m); return NULL; } if(hc->hc_is_async) { /* Async, set up a struct that will be signalled when we get a reply */ hm = malloc(sizeof(htsp_msg_t)); hm->hm_msg = NULL; hm->hm_seq = seq; hm->hm_error = 0; hts_mutex_lock(&hc->hc_rpc_mutex); TAILQ_INSERT_TAIL(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); } if(tc->write(tc, buf, len)) { free(buf); htsmsg_destroy(m); if(hm != NULL) { hts_mutex_lock(&hc->hc_rpc_mutex); TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); free(hm); } return NULL; } free(buf); if(hm != NULL) { hts_mutex_lock(&hc->hc_rpc_mutex); while(1) { if(hm->hm_error != 0) { r = hm->hm_error; TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); free(hm); htsmsg_destroy(m); return NULL; } if(hm->hm_msg != NULL) break; hts_cond_wait(&hc->hc_rpc_cond, &hc->hc_rpc_mutex); } TAILQ_REMOVE(&hc->hc_rpc_queue, hm, hm_link); hts_mutex_unlock(&hc->hc_rpc_mutex); reply = hm->hm_msg; free(hm); } else { if((reply = htsp_recv(hc)) == NULL) { htsmsg_destroy(m); return NULL; } } if(!htsmsg_get_u32(reply, "noaccess", &noaccess) && noaccess) { retry++; goto again; } htsmsg_destroy(m); /* Destroy original message */ return reply; }
static void htsp_channelAddUpdate(htsp_connection_t *hc, htsmsg_t *m, int create) { uint32_t id, next; int chnum; prop_t *p; char txt[200]; const char *title, *icon; htsp_channel_t *ch, *n; if(htsmsg_get_u32(m, "channelId", &id)) return; title = htsmsg_get_str(m, "channelName"); icon = htsmsg_get_str(m, "channelIcon"); chnum = htsmsg_get_s32_or_default(m, "channelNumber", -1); if(chnum == 0) chnum = INT32_MAX; snprintf(txt, sizeof(txt), "%d", id); hts_mutex_lock(&hc->hc_meta_mutex); if(create) { ch = calloc(1, sizeof(htsp_channel_t)); p = ch->ch_root = prop_create_root(txt); prop_t *m = prop_create(p, "metadata"); ch->ch_prop_icon = prop_create(m, "icon"); ch->ch_prop_title = prop_create(m, "title"); ch->ch_prop_channelNumber = prop_create(m, "channelNumber"); ch->ch_prop_events = prop_create(m, "events"); ch->ch_id = id; snprintf(txt, sizeof(txt), "htsp://%s:%d/channel/%d", hc->hc_hostname, hc->hc_port, id); prop_set_string(prop_create(p, "url"), txt); prop_set_string(prop_create(p, "type"), "tvchannel"); ch->ch_channel_num = chnum; mystrset(&ch->ch_title, title); TAILQ_INSERT_SORTED(&hc->hc_channels, ch, ch_link, channel_compar); n = TAILQ_NEXT(ch, ch_link); if(prop_set_parent_ex(p, hc->hc_channels_nodes, n ? n->ch_root : NULL, NULL)) abort(); } else { int move = 0; ch = htsp_channel_get(hc, id); if(ch == NULL) { TRACE(TRACE_ERROR, "HTSP", "Got update for unknown channel %d", id); hts_mutex_unlock(&hc->hc_meta_mutex); return; } p = ch->ch_root; if(title != NULL) { move = 1; mystrset(&ch->ch_title, title); } if(chnum != -1) { move = 1; ch->ch_channel_num = chnum; } if(move) { TAILQ_REMOVE(&hc->hc_channels, ch, ch_link); TAILQ_INSERT_SORTED(&hc->hc_channels, ch, ch_link, channel_compar); n = TAILQ_NEXT(ch, ch_link); prop_move(p, n ? n->ch_root : NULL); } } hts_mutex_unlock(&hc->hc_meta_mutex); if(icon != NULL) prop_set_string(ch->ch_prop_icon, icon); if(title != NULL) prop_set_string(ch->ch_prop_title, title); if(chnum != -1) prop_set_int(ch->ch_prop_channelNumber, chnum); if(htsmsg_get_u32(m, "eventId", &id)) id = 0; if(htsmsg_get_u32(m, "nextEventId", &next)) next = 0; update_events(hc, ch->ch_prop_events, id, next); }
static void update_events(htsp_connection_t *hc, prop_t *metadata, int id, int next) { int i; htsmsg_t *m; prop_t *events = prop_create(metadata, "list"); prop_t *current_event = prop_create(metadata, "current"); prop_t *next_event = prop_create(metadata, "next"); char buf[10]; uint32_t u32; int linkstate = 0; if(id == 0) { if(next == 0) { // No events at all prop_destroy_childs(events); return; } id = next; linkstate = 1; } for(i = 0; i < EPG_TAIL; i++) { snprintf(buf, sizeof(buf), "id%d", i); if(id != 0) { m = htsmsg_create_map(); htsmsg_add_str(m, "method", "getEvent"); htsmsg_add_u32(m, "eventId", id); if((m = htsp_reqreply(hc, m)) != NULL) { prop_t *e = prop_create(events, buf); prop_set_string(prop_create(e, "title"), htsmsg_get_str(m, "title")); prop_set_string(prop_create(e, "description"), htsmsg_get_str(m, "description")); if(!htsmsg_get_u32(m, "start", &u32)) prop_set_int(prop_create(e, "start"), u32); if(!htsmsg_get_u32(m, "stop", &u32)) prop_set_int(prop_create(e, "stop"), u32); switch(linkstate) { case 0: prop_link(e, current_event); break; case 1: prop_link(e, next_event); break; } linkstate++; id = htsmsg_get_u32_or_default(m, "nextEventId", 0); continue; } else { id = 0; } } prop_destroy_by_name(events, buf); switch(linkstate) { case 0: prop_unlink(current_event); break; case 1: prop_unlink(next_event); break; } linkstate++; } }
void CHTSPData::Action() { XBMC->Log(LOG_DEBUG, "%s - starting", __FUNCTION__); htsmsg_t* msg; while (Running()) { if (!CheckConnection()) { cCondWait::SleepMs(1000); continue; } if((msg = m_session->ReadMessage(250)) == NULL) continue; uint32_t seq; if(htsmsg_get_u32(msg, "seq", &seq) == 0) { CMD_LOCK; SMessages::iterator it = m_queue.find(seq); if(it != m_queue.end()) { it->second.msg = msg; it->second.event->Signal(); continue; } } const char* method; if((method = htsmsg_get_str(msg, "method")) == NULL) { htsmsg_destroy(msg); continue; } CMD_LOCK; if (strstr(method, "channelAdd")) CHTSPConnection::ParseChannelUpdate(msg, m_channels); else if(strstr(method, "channelUpdate")) CHTSPConnection::ParseChannelUpdate(msg, m_channels); else if(strstr(method, "channelDelete")) CHTSPConnection::ParseChannelRemove(msg, m_channels); else if(strstr(method, "tagAdd")) CHTSPConnection::ParseTagUpdate(msg, m_tags); else if(strstr(method, "tagUpdate")) CHTSPConnection::ParseTagUpdate(msg, m_tags); else if(strstr(method, "tagDelete")) CHTSPConnection::ParseTagRemove(msg, m_tags); else if(strstr(method, "initialSyncCompleted")) m_started.Signal(); else if(strstr(method, "dvrEntryAdd")) CHTSPConnection::ParseDVREntryUpdate(msg, m_recordings); else if(strstr(method, "dvrEntryUpdate")) CHTSPConnection::ParseDVREntryUpdate(msg, m_recordings); else if(strstr(method, "dvrEntryDelete")) CHTSPConnection::ParseDVREntryDelete(msg, m_recordings); else XBMC->Log(LOG_DEBUG, "%s - Unmapped action recieved '%s'", __FUNCTION__, method); htsmsg_destroy(msg); } m_started.Signal(); XBMC->Log(LOG_DEBUG, "%s - exiting", __FUNCTION__); }
void cHTSPData::Action() { XBMC->Log(LOG_DEBUG, "%s - Starting", __FUNCTION__); htsmsg_t* msg; if(!m_session.SendEnableAsync()) { XBMC->Log(LOG_ERROR, "%s - couldn't send EnableAsync().", __FUNCTION__); m_started.Signal(); return; } while (Running()) { if((msg = m_session.ReadMessage()) == NULL) break; uint32_t seq; if(htsmsg_get_u32(msg, "seq", &seq) == 0) { CMD_LOCK; SMessages::iterator it = m_queue.find(seq); if(it != m_queue.end()) { it->second.msg = msg; it->second.event->Signal(); continue; } } const char* method; if((method = htsmsg_get_str(msg, "method")) == NULL) { htsmsg_destroy(msg); continue; } CMD_LOCK; if (strstr(method, "channelAdd")) cHTSPSession::ParseChannelUpdate(msg, m_channels); else if(strstr(method, "channelUpdate")) cHTSPSession::ParseChannelUpdate(msg, m_channels); else if(strstr(method, "channelDelete")) cHTSPSession::ParseChannelRemove(msg, m_channels); else if(strstr(method, "tagAdd")) cHTSPSession::ParseTagUpdate(msg, m_tags); else if(strstr(method, "tagUpdate")) cHTSPSession::ParseTagUpdate(msg, m_tags); else if(strstr(method, "tagDelete")) cHTSPSession::ParseTagRemove(msg, m_tags); else if(strstr(method, "initialSyncCompleted")) m_started.Signal(); else if(strstr(method, "dvrEntryAdd")) cHTSPSession::ParseDVREntryUpdate(msg, m_recordings); else if(strstr(method, "dvrEntryUpdate")) cHTSPSession::ParseDVREntryUpdate(msg, m_recordings); else if(strstr(method, "dvrEntryDelete")) cHTSPSession::ParseDVREntryDelete(msg, m_recordings); else XBMC->Log(LOG_DEBUG, "%s - Unmapped action recieved '%s'", __FUNCTION__, method); htsmsg_destroy(msg); } m_started.Signal(); XBMC->Log(LOG_DEBUG, "%s - Exiting", __FUNCTION__); }
void cHTSPDemux::SubscriptionStart(htsmsg_t *m) { htsmsg_t *streams; htsmsg_field_t *f; if((streams = htsmsg_get_list(m, "streams")) == NULL) { XBMC->Log(LOG_ERROR, "%s - malformed message", __FUNCTION__); return; } m_Streams.iStreamCount = 0; HTSMSG_FOREACH(f, streams) { uint32_t index; const char* type; htsmsg_t* sub; if (f->hmf_type != HMF_MAP) continue; sub = &f->hmf_msg; if ((type = htsmsg_get_str(sub, "type")) == NULL) continue; if (htsmsg_get_u32(sub, "index", &index)) continue; const char *language = htsmsg_get_str(sub, "language"); XBMC->Log(LOG_DEBUG, "%s - id: %d, type: %s, language: %s", __FUNCTION__, index, type, language); m_Streams.stream[m_Streams.iStreamCount].iFPSScale = 0; m_Streams.stream[m_Streams.iStreamCount].iFPSRate = 0; m_Streams.stream[m_Streams.iStreamCount].iHeight = 0; m_Streams.stream[m_Streams.iStreamCount].iWidth = 0; m_Streams.stream[m_Streams.iStreamCount].fAspect = 0.0; m_Streams.stream[m_Streams.iStreamCount].iChannels = 0; m_Streams.stream[m_Streams.iStreamCount].iSampleRate = 0; m_Streams.stream[m_Streams.iStreamCount].iBlockAlign = 0; m_Streams.stream[m_Streams.iStreamCount].iBitRate = 0; m_Streams.stream[m_Streams.iStreamCount].iBitsPerSample = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[0] = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[1] = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[2] = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[3] = 0; m_Streams.stream[m_Streams.iStreamCount].iIdentifier = -1; if(!strcmp(type, "AC3")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_AC3; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "EAC3")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_EAC3; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "MPEG2AUDIO")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_MP2; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "AAC")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_AAC; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "MPEG2VIDEO")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_VIDEO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_MPEG2VIDEO; m_Streams.stream[m_Streams.iStreamCount].iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); m_Streams.stream[m_Streams.iStreamCount].iHeight = htsmsg_get_u32_or_default(sub, "height" , 0); m_Streams.iStreamCount++; } else if(!strcmp(type, "H264")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_VIDEO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_H264; m_Streams.stream[m_Streams.iStreamCount].iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); m_Streams.stream[m_Streams.iStreamCount].iHeight = htsmsg_get_u32_or_default(sub, "height" , 0); m_Streams.iStreamCount++; } else if(!strcmp(type, "DVBSUB")) { uint32_t composition_id = 0, ancillary_id = 0; htsmsg_get_u32(sub, "composition_id", &composition_id); htsmsg_get_u32(sub, "ancillary_id" , &ancillary_id); m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_SUBTITLE; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_DVB_SUBTITLE; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.stream[m_Streams.iStreamCount].iIdentifier = (composition_id & 0xffff) | ((ancillary_id & 0xffff) << 16); m_Streams.iStreamCount++; } else if(!strcmp(type, "TEXTSUB")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_SUBTITLE; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_TEXT; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "TELETEXT")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_SUBTITLE; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_DVB_TELETEXT; m_Streams.iStreamCount++; } if (m_Streams.iStreamCount >= PVR_STREAM_MAX_STREAMS) { XBMC->Log(LOG_ERROR, "%s - max amount of streams reached", __FUNCTION__); break; } }