Esempio n. 1
0
void extint_w2a(void *param)
{
	int n, i, j;
	conn_t *conn = (conn_t *) param;
	u4_t ka_time = timer_sec();
	
	// initialize extension for this connection
	send_msg_mc(conn->mc, false, "EXT ext_client_init");
	
	nbuf_t *nb = NULL;
	while (TRUE) {
		int rx_chan, ext_rx_chan;
		ext_t *ext;
	
		if (nb) web_to_app_done(conn, nb);
		n = web_to_app(conn, &nb);
				
		if (n) {
			char *cmd = nb->buf;
			cmd[n] = 0;		// okay to do this -- see nbuf.c:nbuf_allocq()
			char id[64];

			ka_time = timer_sec();

			// receive and send a roundtrip keepalive
			i = strcmp(cmd, "SET keepalive");
			if (i == 0) {
				ext_send_msg(conn->ext_rx_chan, false, "EXT keepalive");
				continue;
			}

			ext_rx_chan = conn->ext_rx_chan;
			//printf("extint_w2a: %s CONN%d-%p RX%d-%p %d <%s>\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn, strlen(cmd), cmd);

			// answer from client ext about who they are
			// match against list of known extensions and register msg handler
			char client[32];
			int first_time;
			i = sscanf(cmd, "SET ext_switch_to_client=%s first_time=%d rx_chan=%d", client, &first_time, &rx_chan);
			if (i == 3) {
				for (i=0; i < n_exts; i++) {
					ext = ext_list[i];
					if (strcmp(client, ext->name) == 0) {
						//printf("ext_switch_to_client: found func %p CONN%d-%p for ext %s RX%d\n", ext->receive_msgs, conn->self_idx, conn, client, rx_chan);
						ext_users[rx_chan].ext = ext;
						ext_users[rx_chan].conn = conn;
						conn->ext_rx_chan = rx_chan;
						conn->ext = ext;
						TaskNameS(ext->name);
						break;
					}
				}
				if (i == n_exts) panic("ext_switch_to_client: unknown ext");

				// automatically let extension server-side know the connection has been established and
				// our stream thread is running
				if (first_time)
					ext->receive_msgs((char *) "SET ext_server_init", rx_chan);
				continue;
			}
			
			i = sscanf(cmd, "SET ext_blur=%d", &rx_chan);
			if (i == 1) {
				extint_ext_users_init(rx_chan);
				continue;
			}
			
			i = strcmp(cmd, "SET init");
			if (i == 0) {
				continue;
			}

			i = sscanf(cmd, "SERVER DE CLIENT %s", id);
			if (i == 1) {
				continue;
			}
			
			ext_rx_chan = conn->ext_rx_chan;
			if (ext_rx_chan == -1) {
				printf("### extint_w2a: %s CONN%d-%p ext_rx_chan == -1?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn);
				continue;
			}
			ext = ext_users[ext_rx_chan].ext;
			if (ext == NULL) {
				printf("### extint_w2a: %s CONN%d-%p ext_rx_chan %d ext NULL?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan);
				continue;
			}
			if (ext->receive_msgs) {
				//printf("extint_w2a: %s ext->receive_msgs() %p CONN%d-%p RX%d-%p %d <%s>\n", conn->ext? conn->ext->name:"?", ext->receive_msgs, conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn, strlen(cmd), cmd);
				if (ext->receive_msgs(cmd, ext_rx_chan))
					continue;
			} else {
				printf("### extint_w2a: %s CONN%d-%p RX%d-%p ext->receive_msgs == NULL?\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, ext_rx_chan, (ext_rx_chan == -1)? 0:ext_users[ext_rx_chan].conn);
				continue;
			}
			
			printf("extint_w2a: %s CONN%d-%p unknown command: <%s> ======================================================\n", conn->ext? conn->ext->name:"?", conn->self_idx, conn, cmd);
			continue;
		}
		
		conn->keep_alive = timer_sec() - ka_time;
		bool keepalive_expired = (conn->keep_alive > KEEPALIVE_SEC);
		if (keepalive_expired) {
			ext_rx_chan = conn->ext_rx_chan;
			ext = ext_users[ext_rx_chan].ext;
			printf("EXT KEEP-ALIVE EXPIRED RX%d %s\n", ext_rx_chan, ext? ext->name : "(no ext)");
			if (ext != NULL && ext->close_conn != NULL)
				ext->close_conn(ext_rx_chan);
			extint_ext_users_init(ext_rx_chan);
			rx_server_remove(conn);
			panic("shouldn't return");
		}

		TaskSleep(250000);
	}
}
Esempio n. 2
0
// if this connection is new spawn new receiver channel with sound/waterfall tasks
conn_t *rx_server_websocket(struct mg_connection *mc)
{
	int i;
	conn_t *c;
	stream_t *st;
	
	assert(mc->remote_port != 0);
	
	c = (conn_t*) mc->connection_param;
	if (c) {
		// existing connection
		if (c->magic != CN_MAGIC) printf("for: %s:%d %s\n", mc->remote_ip, mc->remote_port, mc->uri);
		assert(c->magic == CN_MAGIC);
		assert(c->mc == mc);
		assert(c->remote_port == mc->remote_port);
		return c;
	}

	const char *uri = mc->uri;
	if (uri[0] == '/') uri++;
	//printf("#### new connection: %s:%d %s ", mc->remote_ip, mc->remote_port, uri);
	
	for (i=0; streams[i].uri; i++) {
		st = &streams[i];
		
		if (strcmp(uri, st->uri) == 0)
			break;
	}
	
	if (!streams[i].uri) {
		lprintf("**** unknown stream type <%s>\n", uri);
		return NULL;
	}

	printf("LOOKING for free conn for type=%d (%s)\n", st->type, st->uri);
	for (c=conns; c<&conns[RX_CHANS*2]; c++) {
		if ((c->remote_port == 0) && (c->type == st->type))
			break;
		printf("BUSY conn rx=%d, remote_port=%d, type=%d (%s)\n", c->rx_channel, c->remote_port, c->type, streams[c->type].uri);
	}
	
	if (c == &conns[RX_CHANS*2]) {
		printf("(too many rx channels open for %s)\n", st->uri);
		if (st->type == STREAM_WATERFALL) send_msg_mc(mc, "MSG too_busy=%d", RX_CHANS);
		return NULL;
	}

	printf("FREE conn rx=%d, remote_port=%d, type=%d (%s)\n", c->rx_channel, c->remote_port, c->type, streams[c->type].uri);

	if (down) {
		//printf("(down for devl)\n");
		if (st->type == STREAM_WATERFALL) send_msg_mc(mc, "MSG down");
		return NULL;
	}
	
	if (!do_wrx) {
		if (do_gps && (st->type == STREAM_WATERFALL)) {
			// display GPS data in waterfall
			send_msg_mc(mc, "MSG gps");
		} else
		if (do_fft && (st->type == STREAM_WATERFALL)) {
			send_msg_mc(mc, "MSG fft");
		} else
		if (do_fft && (st->type == STREAM_SOUND)) {
			;	// start sound task to process sound UI controls
		} else
		{
			//printf("(no wrx)\n");
			return NULL;
		}
	}

	// NB: c->type & c->rx_channel are preset
	c->magic = CN_MAGIC;
	c->mc = mc;
	c->remote_port = mc->remote_port;
	memcpy(c->remote_ip, mc->remote_ip, NRIP);
	c->a2w.mc = c->w2a.mc = mc;
	lock_init(&c->a2w.lock);
	lock_init(&c->w2a.lock);
	mc->connection_param = c;
	c->ui = find_ui(mc->local_port);
	assert(c->ui);
	//printf("NEW channel %d\n", c->rx_channel);

	if (st->f != NULL) {
		int id = _CreateTaskP(st->f, st->uri, st->priority, c);
		c->task = id;
	}
	
	return c;
}