int tune(int aid, int sid) { adapter *ad = get_adapter(aid); int rv = 0; SPid *p; if (!ad) return -400; mutex_lock(&ad->mutex); ad->last_sort = getTick(); if (sid == ad->master_sid && ad->do_tune) { ad->tp.switch_type = ad->switch_type; ad->tp.uslot = ad->uslot; ad->tp.ufreq = ad->ufreq; ad->tp.pin = ad->pin; ad->tp.committed_no = ad->committed_no; ad->tp.uncommitted_no = ad->uncommitted_no; rv = ad->tune(ad->id, &ad->tp); ad->status = 0; ad->status_cnt = 0; set_socket_pos(ad->sock, 0); // flush the existing buffer ad->rlen = 0; if (ad->sid_cnt > 1) // the master changed the frequency { close_streams_for_adapter(aid, sid); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -503; } } #ifdef TABLES_H p = find_pid(aid, 0); if (!p || p->flags == 3) // add pid 0 if not explicitly added { LOG( "Adding pid 0 to the list of pids as not explicitly added for adapter %d", aid); mark_pid_add(-1, aid, 0); } #endif } else LOG("not tuning for SID %d (do_tune=%d, master_sid=%d)", sid, ad->do_tune, ad->master_sid); if (rv < 0) mark_pids_deleted(aid, sid, NULL); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -503; } mutex_unlock(&ad->mutex); return rv; }
void close_adapter_for_stream(int sid, int aid) { adapter *ad; if (!(ad = get_adapter(aid))) return; mutex_lock(&ad->mutex); if (ad->master_sid == sid) { ad->master_sid = -1; fix_master_sid(aid); } if (ad->sid_cnt > 0) ad->sid_cnt--; else mark_pids_deleted(aid, -1, NULL); LOG("closed adapter %d for stream %d m:%d s:%d", aid, sid, ad->master_sid, ad->sid_cnt); // delete the attached PIDs as well mark_pids_deleted(aid, sid, NULL); update_pids(aid); // if (a[aid]->sid_cnt == 0) // close_adapter (aid); mutex_unlock(&ad->mutex); }
void eRTSPStreamClient::del_pid(int p) { std::set<int>::iterator findIter = std::find(pids.begin(), pids.end(), p); if (findIter == pids.end()) { eDebug("pid already removed from the list %d", p); return; } pids.erase(p); update_pids(); // update_service_list(); }
void eRTSPStreamClient::add_pid(int p) { if (p < 0 || p > 8192) return; std::set<int>::iterator findIter = std::find(pids.begin(), pids.end(), p); if (findIter != pids.end()) { eDebug("pid already in the list %d", p); return; } pids.insert(p); update_pids(); // update_service_list(); }
int set_adapter_parameters(int aid, int sid, transponder * tp) { adapter *ad = get_adapter(aid); if (!ad) return -1; LOG("setting DVB parameters for adapter %d - master_sid %d sid %d old f:%d", aid, ad->master_sid, sid, ad->tp.freq); mutex_lock(&ad->mutex); if (ad->master_sid == -1) ad->master_sid = sid; // master sid was closed ad->do_tune = 0; if (tp->freq != ad->tp.freq || tp->plp != ad->tp.plp || tp->diseqc != ad->tp.diseqc || (tp->pol > 0 && tp->pol != ad->tp.pol) || (tp->sr > 1000 && tp->sr != ad->tp.sr) || (tp->mtype > 0 && tp->mtype != ad->tp.mtype)) { if (sid != ad->master_sid) // slave sid requesting to tune to a different frequency { mutex_unlock(&ad->mutex); LOG( "secondary stream requested tune, not gonna happen\n ad: f:%d sr:%d pol:%d plp:%d src:%d mod %d\n \ new: f:%d sr:%d pol:%d plp:%d src:%d mod %d", ad->tp.freq, ad->tp.sr, ad->tp.pol, ad->tp.plp, ad->tp.diseqc, ad->tp.mtype, tp->freq, tp->sr, tp->pol, tp->plp, tp->diseqc, tp->mtype); return -1; } mark_pids_deleted(aid, -1, NULL); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -1; } ad->do_tune = 1; }
void close_adapter(int na) { adapter *ad; init_complete = 0; ad = get_adapter_nw(na); if (!ad) return; mutex_lock(&ad->mutex); if (!ad->enabled) { mutex_unlock(&ad->mutex); return; } LOG("closing adapter %d -> fe:%d dvr:%d", na, ad->fe, ad->dvr); ad->enabled = 0; if (ad->close) ad->close(ad); //close all streams attached to this adapter // close_streams_for_adapter (na, -1); mark_pids_deleted(na, -1, NULL); update_pids(na); // if(ad->dmx>0)close(ad->dmx); if (ad->fe > 0) close(ad->fe); if (ad->sock > 0) sockets_del(ad->sock); if (ad->ca_mask > 0) tables_close_device(ad); ad->ca_mask = 0; ad->fe = 0; ad->dvr = 0; ad->strength = 0; ad->snr = 0; mutex_unlock(&ad->mutex); mutex_destroy(&ad->mutex); // if(a[na]->buf)free1(a[na]->buf);a[na]->buf=NULL; LOG("done closing adapter %d", na); }
void eRTSPStreamClient::eventUpdate(int event) { if (event >= 0 && event <= (int)sizeof(event_desc)) eDebug("eventUpdate %s", event_desc[event]); else eDebug("eventUpdate %d", event); if (event == eDVBServicePMTHandler::eventNoResources && m_mgr) { ePtr<iDVBFrontend> frontend; eDebug("No available tunners"); for (std::list<eDVBResourceManager::active_channel>::iterator i(m_mgr->m_active_channels.begin()); i != m_mgr->m_active_channels.end(); ++i) { i->m_channel->getFrontend(frontend); eDVBFrontend *f = (eDVBFrontend *)(iDVBFrontend *)frontend; if (f) eDebug("Adapter %d slot %d frequency %d", f->getDVBID(), f->getSlotID(), frontend->readFrontendData(iFrontendInformation_ENUMS::frequency)); } } if (event == eDVBServicePMTHandler::eventNoPMT || event == eDVBServicePMTHandler::eventNoPMT || event == eDVBServicePMTHandler::eventNoPATEntry) clear_previous_channel = 0; if (running && m_record) { mr = (eDVBRecordFileThread *)((eDVBTSRecorder *)(iDVBTSRecorder *)m_record)->m_thread; if (mr->getProtocol() != proto) { eDebug("Setting protocol %d", proto); mr->setProtocol(proto); mr->setSession(session_id, stream_id); update_pids(); } } update_service_list(); }
int init_hw(int i) { char name[100]; adapter *ad; if (i < 0 || i >= MAX_ADAPTERS) return 1; if (a[i] && a[i]->enabled) return 1; if (!a[i]) return 1; ad = a[i]; mutex_init(&ad->mutex); mutex_lock(&ad->mutex); if (ad->force_disable) goto NOK; if (ad->enabled) goto NOK; ad->sock = -1; ad->id = i; ad->fe_sock = -1; ad->sock = -1; if (ad->enabled) { goto NOK; } if (ad->open(ad)) { init_complete = 0; goto NOK; } ad->enabled = 1; if (!ad->buf) ad->buf = malloc1(opts.adapter_buffer + 10); if (!ad->buf) { LOG( "memory allocation failed for %d bytes failed, adapter %d, trying %d bytes", opts.adapter_buffer, i, ADAPTER_BUFFER); opts.adapter_buffer = ADAPTER_BUFFER; ad->buf = malloc1(opts.adapter_buffer + 10); if (!ad->buf) { LOG("memory allocation failed for %d bytes failed, adapter %d", opts.adapter_buffer, i); close_adapter(i); } goto NOK; } memset(ad->buf, 0, opts.adapter_buffer + 1); init_dvb_parameters(&ad->tp); mark_pids_deleted(i, -1, NULL); update_pids(i); ad->delsys(i, ad->fe, ad->sys); ad->master_sid = -1; ad->sid_cnt = 0; ad->pid_err = ad->dec_err = 0; ad->new_gs = 0; ad->force_close = 0; ad->ca_mask = 0; ad->rtime = getTick(); ad->sock = sockets_add(ad->dvr, NULL, i, TYPE_DVR, (socket_action) read_dmx, (socket_action) close_adapter_for_socket, (socket_action) adapter_timeout); memset(ad->buf, 0, opts.adapter_buffer + 1); set_socket_buffer(ad->sock, (unsigned char*) ad->buf, opts.adapter_buffer); sockets_timeout(ad->sock, ADAPTER_TIMEOUT); snprintf(ad->name, sizeof(ad->name), "AD%d", i); set_socket_thread(ad->sock, start_new_thread(ad->name)); tables_init_device(ad); if (ad->post_init) ad->post_init(ad); // set_sock_lock(ad->sock, &ad->mutex); // locks automatically the adapter on reading from the DVR LOG("done opening adapter %i fe_sys %d %d %d %d", i, ad->sys[0], ad->sys[1], ad->sys[2], ad->sys[3]); OK: mutex_unlock(&ad->mutex); return 0; NOK: mutex_unlock(&ad->mutex); return 1; }
int eRTSPStreamClient::satip2enigma(std::string satipstr) { int new_freq = 0, new_pol = -1, new_sys = 0, sid = 0; int do_tune = 0; eDVBResourceManager::getInstance(m_mgr); /* als Primary datenbank setzen */ m_dvbdb = eDVBDB::getInstance(); eDebug("Start %s", __FUNCTION__); URI u(satipstr); // parse URL using new class URI eDebug("Is URL %s valid? %d fe=%s src=%s freq=%s msys=%s pol=%s sid=%s addpids=%s delpids=%s pids=%s", satipstr.c_str(), u.Valid(), u.Query("fe").c_str(), u.Query("src").c_str(), u.Query("freq").c_str(), u.Query("msys").c_str(), u.Query("pol").c_str(), u.Query("sid").c_str(), u.Query("addpids").c_str(), u.Query("delpids").c_str(), u.Query("pids").c_str()); if (!u.Query("fe").empty()) fe = atoi(u.Query("fe").c_str()) + 1; if (!u.Query("src").empty()) src = atoi(u.Query("src").c_str()) - 1; if (!u.Query("freq").empty()) new_freq = atof(u.Query("freq").c_str()) * 1000; if (!u.Query("msys").empty()) { new_sys = 0; const char *s = u.Query("msys").c_str(); for (int i = 0; fe_delsys[i]; i++) if (!strncasecmp(s, fe_delsys[i], strlen(fe_delsys[i]))) new_sys = i; } if (!u.Query("pol").empty()) { new_pol = -1; const char *s = u.Query("pol").c_str(); for (int i = 0; fe_pol[i]; i++) if (!strncasecmp(s, fe_pol[i], strlen(fe_pol[i]))) new_pol = i; } if (!u.Query("sid").empty()) sid = atoi(u.Query("sid").c_str()); if (freq && new_freq && freq != new_freq) do_tune = 1; if (pol != -1 && new_pol != -1 && pol != new_pol) do_tune = 1; eDebug("initial values, freq %d, pol %d, sys %d, old freq = %d, tune %d", new_freq, new_pol, new_sys, freq, do_tune); if (do_tune) { eDebug("Tuning multiple transponders not supported, state %d", m_state); clear_previous_channel = 1; this->pids.clear(); // m_state = stateIdle; update_pids(); return -1; stop(); eDebug("free service handler, state %d", m_state); m_service_handler.free(); eDebug("done freeing service handler"); m_mgr->removeChannel(m_channel); m_channel->stop(); m_record = NULL; init_rtsp(); clear_previous_channel = 1; //return -1; } if (new_freq) freq = new_freq; if (new_pol != -1) pol = new_pol; if (new_sys) sys = new_sys; if (!u.Query("addpids").empty()) process_pids(_ADD_PIDS, u.Query("addpids")); if (!u.Query("delpids").empty()) process_pids(_DEL_PIDS, u.Query("delpids")); if (!u.Query("pids").empty() && u.Query("addpids").empty() && u.Query("delpids").empty()) process_pids(_PIDS, u.Query("pids")); int op = 0; if (sys == SYS_DVBS || sys == SYS_DVBS2) op = getOrbitalPosition(fe, src); // searchServiceRef should be executed just once, when freq= is specified std::string sref; if (new_freq > 0) { sref = searchServiceRef(sys, freq, pol, op, sid); eDebug("tunning to %d, pol %d, sys %d -> SR: %s", freq, pol, sys, sref.c_str()); } if ((new_freq > 0) && !sref.empty()) // 0 - horizontal, 1 - vertical , 2 ->left, 3->Right { eDebug("Using service ref %s, state %d %d", sref.c_str(), m_state, stateIdle); m_serviceref = sref; running = true; if (!stream_id) { stream_id = __sync_add_and_fetch(&global_stream_id, 1); session_id = random(); } } else eDebug("no service ref used"); return 0; }
int process_pat(adapter *ad, unsigned char *b) { int pat_len = 0, i, tid = 0, sid, pid, ver, csid = 0; int64_t pid_key = TABLES_ITEM + ((1 + ad->id) << 24) + 0; int16_t *pids; unsigned char *init_b = b; SPid *p; if (((b[1] & 0x1F) != 0) || (b[2] != 0)) return 0; if (b[0] != 0x47) return 0; if ((b[1] & 0x40) && ((b[4] != 0) || (b[5] != 0))) return 0; // p = find_pid(ad->id, 0); // if(!p) // return 0; tid = b[8] * 256 + b[9]; ver = b[10] & 0x3E; if ((ad->transponder_id == tid) && (ad->pat_ver == ver)) //pat already processed return 0; if (!(pat_len = assemble_packet(&b, ad, 1))) return 0; tid = b[3] * 256 + b[4]; ver = b[5] & 0x3E; if (((ad->transponder_id != tid) || (ad->pat_ver != ver)) && (pat_len > 0) && (pat_len < 1500)) { ad->pat_processed = 0; } if (ad->pat_processed) return 0; ad->pat_ver = ver; ad->transponder_id = tid; #ifndef DISABLE_DVBAPI dvbapi_delete_keys_for_adapter(ad->id); #endif // LOG("tid %d pat_len %d: %02X %02X %02X %02X %02X %02X %02X %02X", tid, pat_len, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); setItem(pid_key, b, 1, 0); setItemSize(pid_key, 8192 * sizeof(*pids)); pids = (int16_t *) getItem(pid_key); memset(pids, 0, 8192 * sizeof(*pids)); pat_len -= 9; b += 8; LOGL(2, "PAT Adapter %d, Transponder ID %d, len %d, version %d", ad->id, tid, pat_len, ad->pat_ver); if (pat_len > 1500) return 0; for (i = 0; i < pat_len; i += 4) { sid = b[i] * 256 + b[i + 1]; pid = (b[i + 2] & 0x1F) * 256 + b[i + 3]; LOGL(2, "Adapter %d, PMT sid %d (%04X), pid %d", ad->id, sid, sid, pid); if (sid > 0) { pids[pid] = -TYPE_PMT; p = find_pid(ad->id, pid); if (!p) mark_pid_add(-1, ad->id, pid); if ((p = find_pid(ad->id, pid))) { p->type = TYPE_PMT; csid = pid; if (p->flags == 3) p->flags = 1; } } } update_pids(ad->id); ad->pat_processed = 1; return csid; }