Ejemplo n.º 1
0
static int get_socket (struct sockaddr *sa, socklen_t socklen_in, int domain)
{
    int s;
    const int one = 1;
    int bind_rc, rc_ok = 0;


    errno = 0;
    s = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));

    if (s != -1)
    {
        errno = 0;
        bind_rc = bind(s, sa, socklen_in);
        if (!bind_rc)
        {
            rc_ok = 1;
        }
        else
        {
            trace_warn("Cannot bind to indexnode listener socket: %s\n", strerror(errno));
        }
    }
    else
    {
        trace_warn("Cannot create indexnode listener socket: %s\n", strerror(errno));
    }


    return rc_ok ? s : -1;
}
Ejemplo n.º 2
0
static void print_network_interfaces (void)
{
    struct ifaddrs *ifaddr, *ifa;
    int family, s;


    /* TODO: make this a config option */
    trace_info("Listening on all addresses:\n");

    errno = 0;
    if (getifaddrs(&ifaddr) == -1)
    {
        trace_warn("Cannot get interface addresses: %s\n", strerror(errno));
    }

    for (ifa = ifaddr; ifa; ifa = ifa->ifa_next)
    {
        char host[NI_MAXHOST];

        family = ifa->ifa_addr->sa_family;

        /* For an AF_INET* interface address, display the address, interface and
         * address family */
        if (family == AF_INET || family == AF_INET6)
        {
            s = getnameinfo(ifa->ifa_addr,
                    (family == AF_INET) ? sizeof(struct sockaddr_in) :
                    sizeof(struct sockaddr_in6),
                    host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST
                );

            if (s)
            {
                trace_warn("Cannot getnameinfo(): %s\n", gai_strerror(s));
            }

            trace_info("\t%s (%s, %s)\n",
                       host,
                       ifa->ifa_name,
                       (family == AF_INET)   ? "AF_INET" :
                       (family == AF_INET6)  ? "AF_INET6" :
                       ""
                      );
        }
    }
    trace_info("\n");

    freeifaddrs(ifaddr);
}
Ejemplo n.º 3
0
static void *alarm_thread_main( void *ctxt )
{
    alarm_t *alarm = (alarm_t *)ctxt;
    struct timeval tv;
    fd_set r_fds;
    int exiting = 0;
    int select_rc;
    alarm_control_codes_t msg = alarm_control_codes_NOT_USED;


    FD_ZERO(&r_fds);


    while( !exiting )
    {
        FD_SET( alarm->pipe_read, &r_fds );

        /* man 2 select: "consider tv undefined after select returns */
        bzero( &tv, sizeof(tv) );
        tv.tv_sec = alarm->interval;

        /* TODO: pselect */
        errno = 0;
        select_rc = select( alarm->pipe_read + 1, &r_fds, NULL, NULL, &tv );

        switch( select_rc )
        {
            case -1:
                trace_warn("Error waiting for alarm timeout / control signal: %s\n", strerror(errno));
                break;
            case 0:
                /* No fds active == timeout */
                alarm->cb( alarm->cb_data );
                break;
            case 1:
                if( FD_ISSET(alarm->pipe_read, &r_fds) )
                {
                    assert( read( alarm->pipe_read, &msg, sizeof(msg) ) == sizeof(msg) );
                    assert( msg == alarm_control_codes_STOP );

                    exiting = 1;
                }
                else
                {
                    assert( 0 );
                }
                break;
            default:
                assert( 0 );
        }
    }


    return NULL;
}
Ejemplo n.º 4
0
static void listener_thread_event_loop (int s4, int s6, int control_fd, new_indexnode_event_t packet_received_cb, void *packet_received_ctxt)
{
    fd_set r_fds;
    int select_rc;
    int exiting = 0;
    listener_control_codes_t msg = listener_control_codes_NOT_USED;


    FD_ZERO(&r_fds);
    assert(control_fd != -1);

    while (!exiting)
    {
        if (s4 != -1) FD_SET(s4, &r_fds);
        if (s6 != -1) FD_SET(s6, &r_fds);
        FD_SET(control_fd, &r_fds);

        errno = 0;
        /* TODO: use pselect to block all signals to this thread so select
         * doesn't wake randomly. Assert no EAGAIN (shouldn't see it). */
        select_rc = select(MAX(s4, MAX(s6, control_fd)) + 1, &r_fds, NULL, NULL, NULL);

        switch (select_rc)
        {
            case -1:
                trace_warn("Error waiting for indexnode broadcast: %s\n", strerror(errno));
                break;
            case 0:
                /* No fds active == timeout */
                assert(0);
                break;
            default:
                if ((s4 != -1) && FD_ISSET(s4, &r_fds))
                {
                    struct sockaddr_in sa;
                    receive_advert(s4, (struct sockaddr *)&sa, sizeof(sa), &(sa.sin_addr), INET_ADDRSTRLEN, packet_received_cb, packet_received_ctxt);
                }
                if ((s6 != -1) && FD_ISSET(s6, &r_fds))
                {
                    struct sockaddr_in6 sa;
                    receive_advert(s6, (struct sockaddr *)&sa, sizeof(sa), &(sa.sin6_addr), INET6_ADDRSTRLEN, packet_received_cb, packet_received_ctxt);
                }
                if (FD_ISSET(control_fd, &r_fds))
                {
                    assert(read(control_fd, &msg, sizeof(msg)) == sizeof(msg));
                    assert(msg == listener_control_codes_STOP);

                    exiting = 1;
                }

                break;
        }
    }
}
Ejemplo n.º 5
0
static void receive_advert(
    const int socket,
    struct sockaddr *sa,
    const socklen_t socklen_in,
    void * const addr_src,
    const size_t host_len,
    new_indexnode_event_t packet_received_cb,
    void *packet_received_ctxt
)
{
    char host[host_len];
    char buf[1024];
    char *port, *fs2protocol, *id;
    string_buffer_t *buffer = string_buffer_new();
    int recv_rc;
    socklen_t socklen;


    /* For UDP it is specified that recv*() will return the whole packet in one
     * go. It is not correct to keep calling recv*() to get more of the message;
     * this isn't a stream. If the message is too big for the buffer it's simply
     * truncated. Usually silently, but by passing in MSG_TRUNC one gets the
     * real length of the message back, even if it has to be truncated. This
     * allows us to assert that our buffer is big enough. We've had to take a
     * guess because advert packets are variable length, but it's an assertion
     * because 1024 really should be enough */

    errno = 0;
    recv_rc = recvfrom(socket, buf, sizeof(buf) - 1, MSG_TRUNC, sa, &socklen);
    assert(recv_rc <= (int)sizeof(buf) - 1);

    if (recv_rc >= 0)
    {
        assert(socklen == socklen_in);
        buf[recv_rc] = '\0';
        string_buffer_append(buffer, strdup(buf));

        if (!parse_advert_packet(string_buffer_peek(buffer), &port, &fs2protocol, &id) &&
            inet_ntop(AF_INET, addr_src, host, sizeof(host) - 1))
        {
            packet_received_cb(packet_received_ctxt, strdup(host), port, fs2protocol, id);
        }
    }
    else
    {
        trace_warn("failed to recvfrom() and indexnode advert packet: %s\n", strerror(errno));
    }


    string_buffer_delete(buffer);
}
Ejemplo n.º 6
0
int pid_map_table_apply(struct xmux_pid_map_table *pid_map_data)
{
	int size = sizeof(struct xmux_pid_map_table);

	if (size > sizeof(tmp_pid_map.pid_map)) {
		trace_warn("pid map table struct exceed! check it!");
		return -1;
	}

	tmp_pid_map.cha = CHANNEL_ALL_BITMAP;
	memcpy((unsigned char *)&tmp_pid_map.pid_map, pid_map_data, sizeof(*pid_map_data));

	hfpga_write_pid_map(&tmp_pid_map);

	return 0;
}
Ejemplo n.º 7
0
void manage_add_chair(struct device *d)
{
  int i;
  for( i=0 ; i<array_size(chairs) ; i++ )
  {
    if( chairs[i] == d )
    {
      /* already added */
      return;
    }
    else if( !chairs[i] )
    {
      chairs[i] = d;
      return;
    }
  }

  /* we should not get here.. */
  trace_warn("too many chair devices.");
}
Ejemplo n.º 8
0
struct fp_cmd * front_panel_send_cmd(struct fp_cmd *cmd, int expect_cmd)
{
	int rc;
	struct fp_cmd *resp_cmd = NULL;

	if (wu_swait_is_alive(&fp_swait)) {
		trace_warn("busy! ignore this send cmd request!");
		return NULL;
	}
	rc = write(fd, cmd, FP_CMD_SIZE(cmd));
	if (rc < FP_CMD_SIZE(cmd)) {
		trace_err("wirte cmd failed!");
		return NULL;
	}
	fp_expect_cmd = expect_cmd;
	resp_cmd = wu_swait_timedwait(&fp_swait, 2000000);
	fp_expect_cmd = -1;

	return resp_cmd;
}
Ejemplo n.º 9
0
/*
 * @return: 1 the @cmd is response cmd
 */
int front_panel_check_recv_cmd(struct fp_cmd *recv_cmd)
{
	int cmd = SWAP_U16(recv_cmd->header.seq) & 0x7FFF;
	int is_read = SWAP_U16(recv_cmd->header.seq) & 0x8000;
	bool check_enter_fp = true;

	/*
	 * check force enter to fp management mode
	 */
	if (cmd == FP_CMD_SYS) {
		uint16_t sys_cmd = READ_U16_BE(recv_cmd->data);
		if (sys_cmd == FP_SYS_CMD_READ_TS_STATUS ||
			sys_cmd == FP_SYS_CMD_ENTER_FP_MANAGEMENT_MODE ||
			sys_cmd == FP_SYS_CMD_LEAVE_FP_MANAGEMENT_MODE) {
			check_enter_fp = false;
		}
	} else if (cmd == FP_CMD_OUT_RATE && is_read) {
		check_enter_fp = false;
	}
	if (check_enter_fp && (management_mode != MANAGEMENT_MODE_FP)) {
		trace_warn("recv cmd in none fp mode! force switch!");
		enter_fp_management_mode();
	}

	if (cmd == fp_expect_cmd) {
		static char buf[1024];
		struct fp_cmd *resp_cmd = (struct fp_cmd *)buf;
		fp_cmd_copy(resp_cmd, recv_cmd);
		if (wu_swait_wakeup(&fp_swait, resp_cmd)) {
			trace_err("recv respone cmd %d, but maybe had timeouted!", cmd);
		}
		return 1;
	}

	return 0;
}
Ejemplo n.º 10
0
static int do_parse_channel(PROG_INFO_T *chan_prog_info, uint8_t * p_chan_prog_cnt, uint8_t chan_idx)
{
	int i, j, k;
	uint8_t prog_cnt = 0;
	PROG_INFO_T *prog_info;
	int rc = 0;
	uint16_t pids[PROGRAM_PID_MAX_NUM];
	int nr_pids;

	pmt.p_descr = pmt_descr;
	for (i = 0; i < 5; i++) {
		pmt_descr[i].p_data = p_pmt_data[i];
	}

	for (i = 0; i < PROGRAM_MAX_NUM; i++) {
		es[i].p_descr = es_descr[i];
		stream[i].p_descr = stream_descr[i];
		serv[i].p_descr = serv_descr[i];
		for (j = 0; j < 5; j++) {
			es_descr[i][j].p_data = p_es_data[i][j];
			stream_descr[i][j].p_data = p_stream_data[i][j];
			serv_descr[i][j].p_data = p_serv_data[i][j];
		}
	}

	hfpga_dev.cha = chan_idx;
	dvbSI_Start(&hfpga_dev);

	trace_info("decode PAT ...");
	sg_si_param.tbl_type = EUV_TBL_PAT;
	psi_parse_timer_start(5);
	rc = dvbSI_Dec_PAT(&pat, pid_data, &pid_num);
	psi_parse_timer_stop();
	if (rc) {
		trace_err("pat parse failed! rc %d\n", rc);
		goto channel_analyse_done;
	}
	trace_info("PAT decode done, TS id %#x, pmt pid num %d",
		pat.i_tran_stream_id, pid_num);
	for (i = 0; i < pid_num; i++) {
		trace_info("  program #%d: program number %#x, PMT %#x",
			i, pid_data[i].i_pg_num, pid_data[i].i_pid);
	}

	trace_info("decode PMT ...");
#if CHANNEL_MAX_NUM == 1
	sg_si_param.type = EUV_BOTH;
#endif
	sg_si_param.tbl_type = EUV_TBL_PMT;
	for (i = 0; i < pid_num; i++) {
		if (pid_data[i].i_pg_num != 0x00) {
			prog_info = chan_prog_info + prog_cnt;
			prog_cnt++;
			prog_info->info.pmt.in = pid_data[i].i_pid;
			prog_info->info.pmt.out =
				pid_map_rule_map_psi_pid(chan_idx, prog_cnt - 1,
					DSW_PID_PMT, pid_data[i].i_pid, NULL, 0);
			prog_info->info.prog_num = pid_data[i].i_pg_num;

			trace_info("decode program_number %d, PMT %#x ...",
				pid_data[i].i_pg_num, pid_data[i].i_pid);
			pmt.i_pg_num = pid_data[i].i_pg_num;
			pmt.i_pmt_pid = pid_data[i].i_pid;
#if CHANNEL_MAX_NUM == 1
			memset(g_input_pmt_sec[prog_cnt - 1], 0, 2);
			sg_si_param.cur_cnt = 0;
			sg_si_param.sec[0] = g_input_pmt_sec[prog_cnt - 1];
#endif
			psi_parse_timer_start(5);
			rc = dvbSI_Dec_PMT(&pmt, es, &es_num);
			psi_parse_timer_stop();
			if (rc) {
				trace_err("pmt parse #%d failed! rc %d\n", i, rc);
				goto channel_analyse_done;
			}

#if CHANNEL_MAX_NUM == 1
			/*
			 * pmt descriptors
			 * if we found CA_Descriptor, then it's scrambled!
			 */
			for (j = 0; j < pmt.i_descr_num; j++) {
				trace_info("PMT desc #%d, tag %#x, len %d, data:",
					j, pmt.p_descr[j].i_tag, pmt.p_descr[j].i_length);
				if (pmt.p_descr[j].i_tag == CA_DR_TAG) {
					trace_info("found CA_Descriptor!");
					prog_info->status |= FP_STATUS_SCRAMBLED;
				}
			}
#endif

			/*
			 * clip max es number
			 */
			if (es_num > PROGRAM_DATA_PID_MAX_NUM)
				es_num = PROGRAM_DATA_PID_MAX_NUM;

			/*
			 * scan PCR and data PIDs and we'll use them do pid remap
			 */
			nr_pids = scan_program_pids(&pmt, &es, es_num, pids);

			prog_info->info.pcr.type = PID_TYPE_PCR;
			prog_info->info.pcr.in = pmt.i_pcr_pid;
			prog_info->info.pcr.out =
				pid_map_rule_map_psi_pid(chan_idx, prog_cnt - 1,
					DSW_PID_PCR, pmt.i_pcr_pid, pids, nr_pids);
			trace_info("PCR %#x, %d descrs",
					pmt.i_pcr_pid, pmt.i_descr_num);

			for (j = 0; j < pmt.i_descr_num; j++) {
				trace_info("desc %d, tag %#x, len %d",	
					 j, pmt.p_descr[j].i_tag, pmt.p_descr[j].i_length);
				hex_dump("desc", pmt.p_descr[j].p_data,
					pmt.p_descr[j].i_length);
			}
			for (j = 0; j < es_num; j++) {
				trace_info("es %d, type %#x, pid %#x",
					j, es[j].i_type, es[j].i_pid);

				prog_info->info.data[j].type = es[j].i_type;
				if (es[j].i_pid != pmt.i_pcr_pid) {
					prog_info->info.data[j].in = es[j].i_pid;
					prog_info->info.data[j].out =
						pid_map_rule_map_psi_pid(chan_idx, prog_cnt - 1,
							DSW_PID_VIDEO, es[j].i_pid, pids, nr_pids);
				} else {
					prog_info->info.data[j].in = es[j].i_pid;
					prog_info->info.data[j].out = prog_info->info.pcr.out;
					/* correct pcr type */
					if (es_is_video(es[j].i_type))
						prog_info->info.pcr.type = PID_TYPE_PCR_VIDEO;
					else
						prog_info->info.pcr.type = PID_TYPE_PCR_AUDIO;
				}

				for (k = 0; k < es[j].i_descr_num; k++) {
					trace_info("es descriptor %d, tag %#x, len %d",
						 k, es[j].p_descr[k].i_tag, es[j].p_descr[k].i_length);
					hex_dump("desc", es[j].p_descr[k].p_data,
							  es[j].p_descr[k].i_length);
				}
			}
		}
	}
	*p_chan_prog_cnt = prog_cnt;

	trace_info("decode SDT ...");
	sg_si_param.type = EUV_DEFAULT;
	sg_si_param.tbl_type = EUV_TBL_SDT;
	psi_parse_timer_start(20);
	rc = parse_sdt_section_and_decode(chan_idx, &sdt, serv, &serv_num);
	psi_parse_timer_stop();
	if (rc) {
		trace_err("sdt parse failed! rc %d\n", rc);
		goto channel_analyse_done;
	}
	trace_info("there are total %d services", serv_num);
	for (j = 0; j < serv_num; j++) {
		for (i = 0; i < prog_cnt; i++) {
			prog_info = chan_prog_info + i;
			if (serv[j].i_serv_id == prog_info->info.prog_num) {
				trace_info("service #%d: service_id %#x",
					j, serv[j].i_serv_id);
				extract_program_name(serv[j].p_descr->p_data,
						(unsigned char *)prog_info->info.prog_name);
				/* set default output program name same with original */
				memcpy(prog_info->info.prog_name[1],
					prog_info->info.prog_name[0], PROGRAM_NAME_SIZE);
				break;
			}
		}
		if (i == prog_cnt) {
			trace_warn("service #%d: service_id %#x, no owner program!",
				j, serv[j].i_serv_id);
		}
	}

channel_analyse_done:
	dvbSI_Stop();

	return rc;
}
Ejemplo n.º 11
0
static int cmd_reg(struct cmd *cmd)
{
  int a=0;

  char *p;
  struct device *d;
  struct db_device *dd;
  char sum[64];
  unsigned int n;
  int type;
  char *pass;
  int port;
  char *bcast;

  int did = cmd->device_id;

  char buf[CMD_MAX];

  NEXT_ARG(p);
  type = atoi(p);

  NEXT_ARG(p);
  pass = p;

  NEXT_ARG(p);
  port = atoi(p);

  NEXT_ARG(p);
  bcast = p;

  /* authenticate the passwd based on id and type */
  n = (unsigned int)cmd->device_id ^ (unsigned int)type;
  cksum(&n, sizeof n, sum);
  if (strcmp(pass, sum) != 0)
  {
    trace_warn("authenticate fail\n");
    return 1;
  }

  if (port <= 0)
    return 1;

  dd = md_find_device(did);
  if( dd )
  {
    /* mark it online even if it's disabled.
     * needed for the manager to identify online devs. */
    dd->online = 1;

    if( !dd->enabled )
    {
      return ERR_DEV_DISABLED;
    }
  }

  d = get_device(did);

  if( !d )
  {
    d = dev_create(did);
  }

  d->type = type;

  d->addr = *cmd->saddr;
  d->addr.sin_port = htons(port);

  d->fileaddr = d->addr;
  d->fileaddr.sin_port = htons(port+1);

  if (strcmp("none", bcast) == 0)
    d->bcast.sin_addr.s_addr = 0;
  else
  {
    d->bcast.sin_addr.s_addr = inet_addr(bcast);
    d->bcast.sin_port = htons(BRCAST_PORT);
  }

  dev_update_data(d);

  if (dev_register(d) != 0)
  {
    /* existing dev ok */
  }

  dev_activate(d);

  if( is_ptc(d) )
  {
    /* re-set ptc if it's restarted. */
    ptc_go_current();
  }

  if( d->type == DEVTYPE_CHAIR )
  {
    manage_notify_chair(d);
  }

  get_client_info(buf, d);

  REP_ADD(cmd, "OK");
  REP_ADD(cmd, buf);
  REP_END(cmd);

  return 0;
}