Beispiel #1
0
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;
}
Beispiel #2
0
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);

}
Beispiel #3
0
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();
}
Beispiel #4
0
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();
}
Beispiel #5
0
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;
	}
Beispiel #6
0
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);
}
Beispiel #7
0
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();
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}