Example #1
0
int satipc_open_device(adapter *ad)
{
	if (!ad->sip)
		return 1;

	int ctime = getTick();
	if ((ad->last_connect > 0) && (ctime - ad->last_connect < 30000))
		return 3;

	ad->last_connect = ctime;
	ad->fe = tcp_connect(ad->sip, ad->sport, NULL, 0); // non-blockin socket
	if (ad->fe < 0)
		return 2;

	LOG("satipc: connected to SAT>IP server %s port %d, handle %d", ad->sip,
			ad->sport, ad->fe);
	ad->listen_rtp = opts.start_rtp + 1000 + ad->id * 2;
	ad->dvr = udp_bind(NULL, ad->listen_rtp);
	ad->rtcp = udp_bind(NULL, ad->listen_rtp + 1);

	ad->fe_sock = sockets_add(ad->fe, NULL, ad->id, TYPE_TCP,
			(socket_action) satipc_reply, (socket_action) satipc_close,
			(socket_action) satipc_timeout);
	ad->rtcp_sock = sockets_add(ad->rtcp, NULL, ad->id, TYPE_TCP,
			(socket_action) satipc_rtcp_reply, (socket_action) satipc_close,
			NULL);
	sockets_timeout(ad->fe_sock, 15000); // 15s
	set_socket_receive_buffer(ad->dvr, opts.output_buffer);
	if (ad->fe_sock < 0 || ad->dvr < 0 || ad->rtcp < 0 || ad->rtcp_sock < 0)
	{
		sockets_del(ad->rtcp_sock);
		sockets_del(ad->fe_sock);
		close(ad->rtcp);
		close(ad->dvr);
		close(ad->fe);
	}
	ad->type = ADAPTER_SATIP;
	ad->session[0] = 0;
	lap[ad->id] = 0;
	ldp[ad->id] = 0;
	ad->cseq = 1;
	ad->err = 0;
	ad->expect_reply = 0;
	ad->last_connect = 0;
	ad->sent_transport = 0;
	ad->session[0] = 0;
	ad->stream_id = -1;
	ad->wp = ad->qp = ad->want_commit = 0;
	ad->rcvp = ad->repno = 0;
	ad->rtp_miss = ad->rtp_ooo = 0;
	ad->rtp_seq = 0xFFFF;
	ad->ignore_packets = 1;
	ad->force_commit = 0;
	ad->satip_last_setup = -10000;
	ad->last_cmd = 0;
	return 0;

}
Example #2
0
void free_all()
{
    int i = 0;

    for (i = MAX_SOCKS - 1; i > 0; i--)
        if (s[i].sock >= 0)
            sockets_del(i);
    free_all_streams();
    free_all_adapters();
}
Example #3
0
void free_all()
{
	int i = 0;

	for (i = MAX_SOCKS - 1; i > 0; i--)
	{
		if (s[i] && s[i]->enabled)
			sockets_del(i);
		if (s[i])
			free(s[i]);
		s[i] = NULL;
	}
	free_all_streams();
	free_all_adapters();
}
Example #4
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);
}
Example #5
0
void *select_and_execute(void *arg)
{
	fd_set io;
	int i, rv, rlen, les, es;
	unsigned char buf[2001];
	int err;
	struct pollfd pf[MAX_SOCKS];
	int64_t lt, c_time;
	int read_ok;
	char ra[50];

	if (arg)
		thread_name = (char *) arg;
	else
		thread_name = "main";

	tid = get_tid();
	les = 1;
	es = 0;
	lt = getTick();
	memset(&pf, -1, sizeof(pf));
	LOG("Starting select_and_execute on thread ID %x, thread_name %s", tid,
			thread_name);
	while (run_loop)
	{
		c_time = getTick();
		es = 0;
		clean_mutexes();
		for (i = 0; i < max_sock; i++)
			if (s[i] && s[i]->enabled && s[i]->tid == tid)
			{
				pf[i].fd = s[i]->sock;
				pf[i].events = s[i]->events;
				pf[i].revents = 0;
				s[i]->last_poll = c_time;
				es++;
			}
			else
			{
				pf[i].fd = -1;
				pf[i].events = pf[i].revents = 0;
			}
		i = -1;
		if (les == 0 && es == 0 && tid != main_tid)
		{
			LOG("No enabled sockets for Thread ID %lx name %s ... exiting ",
					tid, thread_name);
			break;
		}
		les = es;
		//    LOG("start select");
		if ((rv = poll(pf, max_sock, 100)) < 0)
		{
			LOG("select_and_execute: select() error %d: %s", errno,
					strerror(errno));
			continue;
		}
		//              LOG("select returned %d",rv);
		if (rv > 0)
			while (++i < max_sock)
				if ((pf[i].fd >= 0) && pf[i].revents)
				{
					sockets *ss = s[i];
					if (!ss)
						continue;

					c_time = getTick();

					LOGL(6,
							"event on socket index %d handle %d type %d (poll fd:%d, revents=%d)",
							i, ss->sock, ss->type, pf[i].fd, pf[i].revents);
					sockets_lock(ss);

					if (pf[i].revents & POLLOUT)
					{
						ss->events &= ~POLLOUT;
					}
					if (!ss->buf || ss->buf == buf)
					{
						ss->buf = buf;
						ss->lbuf = sizeof(buf) - 1;
						ss->rlen = 0;
					}
					if (ss->rlen >= ss->lbuf)
					{
						LOG(
								"Socket buffer full, handle %d, sock_id %d, type %d, lbuf %d, rlen %d, ss->buf = %p, buf %p",
								ss->sock, i, ss->type, ss->lbuf, ss->rlen,
								ss->buf, buf);
						ss->rlen = 0;
					}
					rlen = 0;
					if (opts.bw > 0 && bw > opts.bw && ss->type == TYPE_DVR)
					{
						int64_t ms = 1000 - c_time + bwtt;
						if (bwnotify++ == 0)
							LOG(
									"capping %d sock %d for the next %jd ms, sleeping for the next %jd ms",
									i, ss->sock, ms, ms / 50);
						if (ms > 50)
							usleep(ms * 20);
						sockets_unlock(ss);
						continue;

					}

					read_ok = ss->read(ss->sock, &ss->buf[ss->rlen],
							ss->lbuf - ss->rlen, ss, &rlen);

					if (opts.log >= 1)
					{
						int64_t now = getTick();
						if (now - c_time > 100)
							LOG(
									"WARNING: read on socket id %d, handle %d, took %jd ms",
									ss->id, ss->sock, now - c_time);
					}

					err = 0;
					if (rlen < 0)
						err = errno;
					if (rlen > 0)
						ss->rtime = c_time;
					if (read_ok && rlen >= 0)
						ss->rlen += rlen;
					else
						ss->rlen = 0;
					//force 0 at the end of the string
					if (ss->lbuf >= ss->rlen)
						ss->buf[ss->rlen] = 0;
					LOGL(6,
							"Read %s %d (rlen:%d/total:%d) bytes from %d -> %p - iteration %d action %p",
							read_ok ? "OK" : "NOK", rlen, ss->rlen, ss->lbuf,
							ss->sock, ss->buf, it++, ss->action);

					if (((ss->rlen > 0) || err == EWOULDBLOCK) && ss->action
							&& (ss->type != TYPE_SERVER))
						ss->action(ss);
					sockets_unlock(ss);

					if (!read_ok && ss->type != TYPE_SERVER)
					{
						char *err_str;
						char *types[] =
						{ "udp", "tcp", "server", "http", "rtsp", "dvr" };
						if (rlen == 0)
						{
							err = 0;
							err_str = "Close";
						}
						else if (err == EOVERFLOW)
							err_str = "EOVERFLOW";
						else if (err == EWOULDBLOCK)
							err_str = "Connected";
						else
							err_str = strerror(err);

						if (ss->type == TYPE_RTCP || ss->sock == SOCK_TIMEOUT)
						{
							LOG(
									"ignoring error on sock_id %d handle %d type %d error %d : %s",
									ss->id, ss->sock, ss->type, err, err_str);
							continue; // do not close the RTCP socket, we might get some errors here but ignore them
						}
						LOG(
								"select_and_execute[%d]: %s on socket %d (sid:%d) from %s:%d - type %s errno %d",
								i, err_str, ss->sock, ss->sid,
								get_socket_rhost(ss->id, ra, sizeof(ra)),
								ntohs(ss->sa.sin_port), types[ss->type], err);
						if (err == EOVERFLOW || err == EWOULDBLOCK)
							continue;
						if (err == EAGAIN)
						{
							ss->err++;
							if (ss->err < 10)
								continue;
						}
						sockets_del(i);

						LOG("Delete socket %d done: sid %d", i, ss->sid);
						continue;
					}

//					ss->err = 0;					
				}
		// checking every 60seconds for idle connections - or if select times out
		c_time = getTick();
		if (rv == 0 || (c_time - lt >= 200))
		{
			sockets *ss;
			lt = c_time;
			i = -1;
			while (++i < max_sock)
				if ((ss = get_sockets(i)) && (ss->tid == tid)
						&& ((ss->timeout_ms > 0
								&& lt - ss->rtime > ss->timeout_ms)
								|| (ss->timeout_ms == 1)))
				{
					if (ss->timeout)
					{
						int rv;
						if (ss->sock == SOCK_TIMEOUT)
							ss->rtime = getTick();
						sockets_lock(ss);
						rv = ss->timeout(ss);
						sockets_unlock(ss);
						if (rv)
							sockets_del(i);
					}

					if (!ss->timeout)
						sockets_del(i);
				}
		}
	}

	clean_mutexes();

	if (tid == main_tid)
		LOG("The main loop ended, run_loop = %d", run_loop);
	add_join_thread(tid);

	return NULL;
}
Example #6
0
int select_and_execute()
{
    fd_set io;
    int i, rv, rlen;
    unsigned char buf[2001];
    int err;
    run_loop = 1;
    int lt, read_ok, c_time;
    char ra[50];
    lt = getTick();
    while (run_loop)
    {
        FD_ZERO(&io);
        i = -1;
        //    LOG("start select");
        if ((rv = poll(pf, max_sock, 100)) < 0)
        {
            perror("select_and_execute: select() error");
            continue;
        }
        c_time = getTick();
        //              LOG("select returned %d",rv);
        if (rv > 0)
            while (++i < max_sock)
                if (pf[i].revents)
                {
                    sockets *ss = &s[i];
                    c_time = getTick();

                    LOGL(6,
                         "event on socket index %d handle %d type %d (poll fd:%d, revents=%d)",
                         i, ss->sock, ss->type, pf[i].fd, pf[i].revents);
                    if (pf[i].revents & POLLOUT)
                    {
                        pf[i].events &= ~POLLOUT;
                    }
                    if (!ss->buf || ss->buf == buf)
                    {
                        ss->buf = buf;
                        ss->lbuf = sizeof(buf) - 1;
                        ss->rlen = 0;
                    }
                    if (ss->rlen >= ss->lbuf)
                    {
                        LOG(
                            "Socket buffer full, handle %d, sock_id %d, type %d, lbuf %d, rlen %d, ss->buf = %p, buf %p",
                            ss->sock, i, ss->type, ss->lbuf, ss->rlen,
                            ss->buf, buf);
                        ss->rlen = 0;
                    }
                    rlen = 0;
                    if (c_time - bwtt > 1000)
                    {
                        bwtt = c_time;
                        tbw += bw;
                        if (bw > 2000)
                            LOG(
                                "BW %dKB/s, Total BW: %ld MB, ns/read %lld, r: %d, tt: %lld ms, n: %d (s: %d ms, s_cnt %d)",
                                (int ) bw / 1024, tbw / 1024576,
                                nsecs / reads, reads, nsecs / 1000,
                                bwnotify, sleeping / 1000, sleeping_cnt);
                        bw = 0;
                        bwnotify = 0;
                        nsecs = 0;
                        reads = 0;
                        sleeping = sleeping_cnt = 0;
                    }
                    if (opts.bw > 0 && bw > opts.bw && ss->type == TYPE_DVR)
                    {
                        int ms = 1000 - c_time + bwtt;
                        if (bwnotify++ == 0)
                            LOG(
                                "capping %d sock %d for the next %d ms, sleeping for the next %d ms",
                                i, ss->sock, ms, ms / 50);
                        if (ms > 50)
                            usleep(ms * 20);
                        continue;

                    }

                    read_ok = ss->read(ss->sock, &ss->buf[ss->rlen],
                                       ss->lbuf - ss->rlen, ss, &rlen);

                    if (opts.log >= 1)
                    {
                        int now = getTick();
                        if (now - c_time > 100)
                            LOG(
                                "WARNING: read on socket id %d, handle %d, took %d ms",
                                ss->id, ss->sock, now - c_time);
                    }

                    err = 0;
                    if (rlen < 0)
                        err = errno;
                    if (rlen > 0)
                        ss->rtime = c_time;
                    if (read_ok && rlen > 0)
                        ss->rlen += rlen;
                    else
                        ss->rlen = 0;
                    //force 0 at the end of the string
                    if (ss->lbuf >= ss->rlen)
                        ss->buf[ss->rlen] = 0;
                    LOGL(6,
                         "Read %s %d (rlen:%d/total:%d) bytes from %d -> %p - iteration %d action %p",
                         read_ok ? "OK" : "NOK", rlen, ss->rlen, ss->lbuf,
                         ss->sock, ss->buf, it++, ss->action);

                    if (((ss->rlen > 0) || err == EWOULDBLOCK) && ss->action
                            && (ss->type != TYPE_SERVER))
                        ss->action(ss);
                    //              if(s[i].type==TYPE_DVR && (c_time/1000 % 10 == 0))sockets_del(i); // we do this in stream.c in flush_stream*
                    if (!read_ok && ss->type != TYPE_SERVER)
                    {
                        char *err_str;
                        char *types[] =
                        { "udp", "tcp", "server", "http", "rtsp", "dvr" };
                        if (rlen == 0)
                        {
                            err = 0;
                            err_str = "Close";
                        }
                        else if (err == EOVERFLOW)
                            err_str = "EOVERFLOW";
                        else if (err == EWOULDBLOCK)
                            err_str = "Connected";
                        else
                            err_str = strerror(err);

                        if (ss->type == TYPE_RTCP)
                            continue; // do not close the RTCP socket, we might get some errors here but ignore them

                        LOG(
                            "select_and_execute[%d]: %s on socket %d (sid:%d) from %s:%d - type %s errno %d",
                            i, err_str, ss->sock, ss->sid,
                            get_socket_rhost(ss->id, ra, sizeof(ra)),
                            ntohs(ss->sa.sin_port), types[ss->type], err);
                        if (err == EOVERFLOW || err == EWOULDBLOCK)
                            continue;
                        if (err == EAGAIN)
                        {
                            ss->err++;
                            if (ss->err < 10)
                                continue;
                        }
                        sockets_del(i);
                        LOG("Delete socket %d done: sid %d", i, ss->sid);
                        continue;
                    }

//					ss->err = 0;
                }
        // checking every 60seconds for idle connections - or if select times out
        if (rv == 0 || c_time - lt >= 200)
        {
            lt = c_time;
            i = -1;
            while (++i < max_sock)
                if (( s[i].sock > 0 ) && ((s[i].close_sec > 0 && lt - s[i].rtime > s[i].close_sec)
                                          || (s[i].close_sec == 1)))
                {
                    if (s[i].timeout && s[i].timeout(&s[i]))
                        sockets_del(i);
                    if (!s[i].timeout)
                        sockets_del(i);
                }
            stream_timeouts();
        }
    }
    LOG("The main loop ended, run_loop = %d", run_loop);
    return 0;
}