コード例 #1
0
ファイル: ts_log.c プロジェクト: divby00/tslua
EXPORT int tl_log_set_active(TS_Lua *ls)
{
	if (ls!=NULL) {
		ts_log_set_active((schar)ts_lua_tonumber(ls,1));
		return 0;
	}
	else {
		ts_debug(_("Invalid Lua handler"),TS_FL);
		return 0;
	}
}
コード例 #2
0
ファイル: ts_log.c プロジェクト: divby00/tslua
EXPORT int tl_log(TS_Lua *ls)
{
	if (ls!=NULL) {
		ts_log((char *)ts_lua_tostring(ls,1));
		return 0;
	}
	else {
		ts_debug(_("Invalid Lua handler"),TS_FL);
		return 0;
	}
}
コード例 #3
0
ファイル: plugin.c プロジェクト: niximor/prebot
/**
 * Socketpool callback indicating that client sent some data that we need
 * to receive.
 * @param socket Socketpool socket
 */
void telnet_socket_client_receive(Socket socket) {
	unsigned char ch;

	TelnetClient client = (TelnetClient)socket->customData;
	TelnetSocketData socketdata = (TelnetSocketData)client->socketdata;

	enum {
		ESC_CODE = 0,
		ESC_PARAM1 = 1,
		ESC_PARAM2 = 2
	} escState = ESC_CODE;
	unsigned long int escParam1 = 0;
	unsigned long int escParam2 = 0;
	char escCode = 0;

	while (read(socketdata->socketfd, &ch, 1) > 0) {
		// After each enter, 0 is send, which we don't need.
		if (ch == 0) continue;

		ts_debug("%d %x (%c) ", ch, ch, (ch >= 32 && ch < 127)?ch:' ');

		switch (socketdata->state) {
			// Normal state, receiving user input
			case TS_NORMAL:
				switch (ch) {
					case TS_IAC:
						ts_debug("IAC\n");
						socketdata->state = TS_IAC;
						continue;

					case TS_ESC:
						ts_debug("ESC\n");
						socketdata->state = TS_ESC;
						escState = ESC_CODE;
						escParam1 = 0;
						escParam2 = 0;
						escCode = 0;
						continue;

					// No special char was entered, proceed normal processing
					// by telnet.
					default:
						break;
				}
				break;

			case TS_ESC: {
				bool doContinue = true;
				switch (escState) {
					// Awaiting [ char
					case ESC_CODE: {
						if (ch == '[') {
							escState = ESC_PARAM1;
						} else {
							doContinue = false;
						}
						break;
					}

					// Awaiting number or char
					case ESC_PARAM1: {
						if (ch >= '0' && ch <= '9') {
							// Is digit, so it is parameter
							escParam1 *= 10;
							escParam1 += ch - '0';
						} else if (ch == ';') {
							escState = ESC_PARAM2;
						} else {
							// It is not digit, it is end of command
							escCode = ch;
						}
						break;
					}

					case ESC_PARAM2: {
						if (ch >= '0' && ch <= '9') {
							// It is digit
							escParam2 *= 10;
							escParam2 += ch - '0';
						} else {
							// Not digit, must be escape code
							escCode = ch;
						}
					}
				}

				if (escCode > 0) {
					switch (escCode) {
						case 'A':
							telnet_received(client, KEY_UP);
							break;

						case 'B':
							telnet_received(client, KEY_DOWN);
							break;

						case 'C':
							telnet_received(client, KEY_RIGHT);
							break;

						case 'D':
							telnet_received(client, KEY_LEFT);
							break;



						// Unknown code
						default:
							break;
					}
				}

				if (doContinue) {
					continue;
				} else {
					socketdata->state = TS_NORMAL;
					break;
				}
			}

			case TS_IAC:
				switch (ch) {
					case TS_SB:
						ts_debug("SB\n");
						socketdata->state = TS_SB;
						break;

					case TS_WILL:
						ts_debug("WILL\n");
						socketdata->state = TS_WILL;
						break;

					case TS_WONT:
						ts_debug("WONT\n");
						socketdata->state = TS_WONT;
						break;

					case TS_DO:
						ts_debug("DO\n");
						socketdata->state = TS_DO;
						break;

					case TS_DONT:
						ts_debug("DONT\n");
						socketdata->state = TS_DONT;
						break;
				}
				continue;

			// IAC DO
			case TS_DO:
				switch (ch) {
					case TS_ECHO: {
						// Client accepted our local echo request, and will
						// not do local echo.
						ts_debug("ECHO\n");
						client->opts |= TC_ECHO;
						break;
					}

					case TS_GOAHEAD: {
						ts_debug("GOAHEAD\n");
						client->opts |= TC_UNBUFFERED;
						break;
					}

					default:
						ts_debug("IGNORE\n");
						break;
				}
				socketdata->state = TS_NORMAL;
				continue;

			// IAC DONT
			case TS_DONT:
				ts_debug("IGNORE\n");
				socketdata->state = TS_NORMAL;
				continue;

			// IAC WILL
			case TS_WILL:
				switch (ch) {
					case TS_NAWS: {
						// Client will send window size
						ts_debug("NAWS\n");
						break;
					}

					case TS_TERMTYPE: {
						// Client allowes us to send terminal type
						ts_debug("TERMTYPE\n");

						// Send VT100 terminal type
						char termtype[11] = { TS_IAC, TS_SB, TS_TERMTYPE, 0,
							'V', 'T', '1', '0', '0', TS_IAC, TS_SE };
						socketpool_send(socket->pool, socket->socketfd,
							termtype, 11);
						socketdata->hasTerm = true;
						break;
					}

					default: {
						ts_debug("IGNORE\n");
						break;
					}
				}
				socketdata->state = TS_NORMAL;
				continue;

			// IAC WONT
			case TS_WONT:
				ts_debug("IGNORE\n");
				socketdata->state = TS_NORMAL;
				continue;

			// IAC SB - Subnegotiation of parameters
			case TS_SB:
				socketdata->state = TS_IGNORE_TILL_SE;

				switch (ch) {
					case TS_NAWS:
						ts_debug("NAWS\n");
						client->windowWidth = 0;
						client->windowHeight = 0;
						socketdata->state = TS_NAWS_WIDTH_LSB;
						break;

					default:
						break;
				}
				continue;

			case TS_NAWS_WIDTH_MSB:
				client->windowWidth = 0xFF * ch;
				socketdata->state = TS_NAWS_WIDTH_LSB;
				continue;

			case TS_NAWS_WIDTH_LSB:
				client->windowWidth += ch;
				socketdata->state = TS_NAWS_HEIGHT_LSB;
				continue;

			case TS_NAWS_HEIGHT_MSB:
				client->windowHeight = 0xFF * ch;
				socketdata->state = TS_NAWS_HEIGHT_LSB;
				continue;

			case TS_NAWS_HEIGHT_LSB:
				client->windowHeight += ch;
				client->opts |= TC_WINDOWSIZE;
				socketdata->state = TS_IGNORE_TILL_SE;
				continue;

			case TS_IGNORE:
				ts_debug("IGNORE\n");
				socketdata->state = TS_NORMAL;
				continue;

			case TS_IGNORE_TILL_SE:
				switch (ch) {
					case TS_SE:
						ts_debug("SE\n");
						socketdata->state = TS_NORMAL;
						break;

					default:
						ts_debug("IGNORE TILL SE\n");
						break;
				}
				continue;

			case TS_KEYCODE1:
				if (ch == '[') {
					ts_debug("CONTROL\n");
					socketdata->keycode = ch << 8;
					socketdata->state = TS_KEYCODE2;
				} else {
					ts_debug("NORMAL\n");
				}
				continue;

			case TS_KEYCODE2:
				ts_debug("KEYCODE2\n");
				socketdata->keycode |= ch;

				// 0x5b3* has 3 bytes (??)
				if ((socketdata->keycode & 0x7ff0) == 0x5b30) {
					socketdata->keycode = socketdata->keycode << 8;
					socketdata->state = TS_KEYCODE3;
				} else {
					//telnet_socket_keycode(client);
					socketdata->state = TS_NORMAL;
				}
				continue;

			case TS_KEYCODE3:
				ts_debug("KEYCODE3\n");
				socketdata->keycode |= ch;
				//telnet_socket_keycode(client);
				socketdata->state = TS_NORMAL;
				continue;

			default:
				// Nothing special, unknown state...
				socketdata->state = TS_NORMAL;
				break;
		}

		if (ch == 127) {
			telnet_received(client, KEY_BACKSPACE);
		} else if (ch == TS_ESC) {
			telnet_received(client, KEY_ESC);
		} else {
			telnet_received(client, ch);

			// Don't read any more data, if command was completed.
			if (ch == KEY_ENTER) {
				break;
			}
		}
	}

	// If we are inside escape sequence, cancel it and treat this as escape
	// key. And don't care about sockets marked for closing, because they
	// should not receive any more data.
	if (!socket->shouldBeClosed) {
		if (socketdata->state == TS_ESC) {
			if (escState == ESC_CODE) {
				telnet_received(client, KEY_ESC);
			}
			socketdata->state = TS_NORMAL;
		}
	}
} // telnet_client_receive
コード例 #4
0
ファイル: comp_scaled_rtp_ts.c プロジェクト: biddyweb/rohc
/**
 * @brief Store the new TS, calculate new values and update the state
 *
 * @param ts_sc        The ts_sc_comp object
 * @param ts           The timestamp to add
 * @param sn           The sequence number of the RTP packet
 */
void c_add_ts(struct ts_sc_comp *const ts_sc,
              const uint32_t ts,
              const uint16_t sn)
{
	uint16_t sn_delta;

	assert(ts_sc != NULL);

	ts_debug(ts_sc, "Timestamp = %u", ts);

	/* consider that TS bits are not deducible by default */
	ts_sc->is_deducible = false;

	/* we save the old value */
	ts_sc->old_ts = ts_sc->ts;
	ts_sc->old_sn = ts_sc->sn;

	/* we store the new value */
	ts_sc->ts = ts;
	ts_sc->sn = sn;

	/* if we had no old values, TS_STRIDE cannot be computed yet */
	if(!ts_sc->are_old_val_init)
	{
		assert(ts_sc->state == INIT_TS);
		ts_debug(ts_sc, "TS_STRIDE cannot be computed, stay in INIT_TS state");
		ts_sc->are_old_val_init = true;
		return;
	}

	/* compute the absolute delta between new and old SN */
	/* abs() on unsigned 16-bit values seems to be a problem sometimes */
	if(ts_sc->sn >= ts_sc->old_sn)
	{
		sn_delta = ts_sc->sn - ts_sc->old_sn;
	}
	else
	{
		sn_delta = ts_sc->old_sn - ts_sc->sn;
	}
	ts_debug(ts_sc, "SN delta = %u", sn_delta);

	/* compute the absolute delta between new and old TS */
	/* abs() on unsigned 32-bit values seems to be a problem sometimes */
	if(ts_sc->ts >= ts_sc->old_ts)
	{
		ts_sc->ts_delta = ts_sc->ts - ts_sc->old_ts;
	}
	else
	{
		ts_sc->ts_delta = ts_sc->old_ts - ts_sc->ts;
	}
	ts_debug(ts_sc, "TS delta = %u", ts_sc->ts_delta);

	/* go back to INIT_TS state if TS is constant */
	if(ts_sc->ts_delta == 0)
	{
		ts_debug(ts_sc, "TS is constant, go in INIT_TS state");
		ts_sc->state = INIT_TS;
		return;
	}

	/* go back to INIT_TS state if TS_STRIDE cannot be SDVL-encoded */
	if(!sdvl_can_value_be_encoded(ts_sc->ts_delta))
	{
		/* TS_STRIDE is too large for SDVL encoding */
		ts_debug(ts_sc, "TS_STRIDE is too large for SDVL encoding, "
		         "go in INIT_TS state");
		ts_sc->state = INIT_TS;
		return;
	}

	/* TS_STRIDE can be computed, so leave INIT_TS state */
	if(ts_sc->state == INIT_TS)
	{
		ts_debug(ts_sc, "TS_STRIDE can be computed, go to INIT_STRIDE state");
		ts_sc->state = INIT_STRIDE;
		ts_sc->nr_init_stride_packets = 0;
	}

	if(ts_sc->state == INIT_STRIDE)
	{
		/* TS is changing and TS_STRIDE can be computed but TS_STRIDE was
		 * not transmitted enough times to the decompressor to be used */
		ts_debug(ts_sc, "state INIT_STRIDE");

		/* reset INIT_STRIDE counter if TS_STRIDE/TS_OFFSET changed */
		if(ts_sc->ts_delta != ts_sc->ts_stride ||
		   (ts_sc->ts % ts_sc->ts_delta) != ts_sc->ts_offset)
		{
			ts_debug(ts_sc, "TS_STRIDE and/or TS_OFFSET changed");
			ts_sc->nr_init_stride_packets = 0;
		}

		/* compute TS_STRIDE, TS_OFFSET and TS_SCALED */
		ts_sc->ts_stride = ts_sc->ts_delta;
		ts_debug(ts_sc, "TS_STRIDE = %u", ts_sc->ts_stride);
		assert(ts_sc->ts_stride != 0);
		ts_sc->ts_offset = ts_sc->ts % ts_sc->ts_stride;
		ts_debug(ts_sc, "TS_OFFSET = %u modulo %u = %u",
		         ts_sc->ts, ts_sc->ts_stride, ts_sc->ts_offset);
		assert(ts_sc->ts_stride != 0);
		ts_sc->ts_scaled = (ts_sc->ts - ts_sc->ts_offset) / ts_sc->ts_stride;
		ts_debug(ts_sc, "TS_SCALED = (%u - %u) / %u = %u", ts_sc->ts,
		         ts_sc->ts_offset, ts_sc->ts_stride, ts_sc->ts_scaled);
	}
	else if(ts_sc->state == SEND_SCALED)
	{
		const uint32_t old_scaled = ts_sc->ts_scaled;
		const uint32_t old_offset = ts_sc->ts_offset;

		/* TS is changing, TS_STRIDE can be computed, and TS_STRIDE was
		 * transmitted enough times to the decompressor to be used */
		ts_debug(ts_sc, "state SEND_SCALED");

		/* does TS_STRIDE changed? */
		ts_debug(ts_sc, "TS_STRIDE calculated = %u", ts_sc->ts_delta);
		ts_debug(ts_sc, "previous TS_STRIDE = %u", ts_sc->ts_stride);
		if(ts_sc->ts_delta != ts_sc->ts_stride)
		{
			assert(ts_sc->ts_stride != 0);
			if((ts_sc->ts_delta % ts_sc->ts_stride) != 0)
			{
				/* TS delta changed and is not a multiple of previous TS_STRIDE:
				 * record the new value as TS_STRIDE and transmit it several
				 * times for robustness purposes */
				ts_debug(ts_sc, "/!\\ TS_STRIDE changed and is not a multiple "
				         "of previous TS_STRIDE, so change TS_STRIDE and "
				         "transmit it several times along all TS bits "
				         "(probably a clock resync at source)");
				ts_sc->state = INIT_STRIDE;
				ts_sc->nr_init_stride_packets = 0;
				ts_debug(ts_sc, "state -> INIT_STRIDE");
				ts_sc->ts_stride = ts_sc->ts_delta;
			}
			else if((ts_sc->ts_delta / ts_sc->ts_stride) != sn_delta)
			{
				/* TS delta changed but is a multiple of previous TS_STRIDE:
				 * do not change TS_STRIDE, but transmit all TS bits several
				 * times for robustness purposes */
				ts_debug(ts_sc, "/!\\ TS delta changed but is a multiple of "
				         "previous TS_STRIDE, so do not change TS_STRIDE, but "
				         "retransmit it several times along all TS bits "
				         "(probably a RTP TS jump at source)");
				ts_sc->state = INIT_STRIDE;
				ts_sc->nr_init_stride_packets = 0;
				ts_debug(ts_sc, "state -> INIT_STRIDE");
			}
			else
			{
				/* do not change TS_STRIDE, probably a packet loss */
				ts_debug(ts_sc, "/!\\ TS delta changed, is a multiple of "
				         "previous TS_STRIDE and follows SN changes, so do "
				         "not change TS_STRIDE (probably a packet loss)");
			}
		}
		ts_debug(ts_sc, "TS_STRIDE = %u", ts_sc->ts_stride);

		/* update TS_OFFSET is needed */
		assert(ts_sc->ts_stride != 0);
		ts_sc->ts_offset = ts_sc->ts % ts_sc->ts_stride;
		ts_debug(ts_sc, "TS_OFFSET = %u modulo %u = %u",
		         ts_sc->ts, ts_sc->ts_stride, ts_sc->ts_offset);

		/* compute TS_SCALED */
		assert(ts_sc->ts_stride != 0);
		ts_sc->ts_scaled = (ts_sc->ts - ts_sc->ts_offset) / ts_sc->ts_stride;
		ts_debug(ts_sc, "TS_SCALED = (%u - %u) / %u = %u", ts_sc->ts,
		         ts_sc->ts_offset, ts_sc->ts_stride, ts_sc->ts_scaled);

		/* could TS_SCALED be deduced from SN? */
		if(ts_sc->state != SEND_SCALED)
		{
			ts_sc->is_deducible = false;
		}
		else
		{
			uint32_t ts_scaled_delta;

			/* be cautious with positive and negative deltas */
			if(ts_sc->ts_scaled >= old_scaled)
			{
				ts_scaled_delta = ts_sc->ts_scaled - old_scaled;

				if(ts_sc->sn >= ts_sc->old_sn)
				{
					ts_sc->is_deducible = (ts_scaled_delta == sn_delta);
				}
				else
				{
					ts_sc->is_deducible = false;
				}
			}
			else
			{
				ts_scaled_delta = old_scaled - ts_sc->ts_scaled;

				if(ts_sc->old_sn >= ts_sc->sn)
				{
					ts_sc->is_deducible = (ts_scaled_delta == sn_delta);
				}
				else
				{
					ts_sc->is_deducible = false;
				}
			}
		}
		if(ts_sc->is_deducible)
		{
			ts_debug(ts_sc, "TS can be deducted from SN (old TS_SCALED = %u, "
			         "new TS_SCALED = %u, old SN = %u, new SN = %u)",
			         old_scaled, ts_sc->ts_scaled, ts_sc->old_sn, ts_sc->sn);
		}
		else
		{
			ts_debug(ts_sc, "TS can not be deducted from SN (old TS_SCALED = %u, "
			         "new TS_SCALED = %u, old SN = %u, new SN = %u)",
			         old_scaled, ts_sc->ts_scaled, ts_sc->old_sn, ts_sc->sn);
		}

		/* Wraparound (See RFC 4815 Section 4.4.3) */
		if(ts_sc->ts < ts_sc->old_ts)
		{
			ts_debug(ts_sc, "TS wraparound detected");
			if(old_offset != ts_sc->ts_offset)
			{
				ts_debug(ts_sc, "TS_OFFSET changed, re-initialize TS_STRIDE");
				ts_sc->state = INIT_STRIDE;
				ts_sc->nr_init_stride_packets = 0;
			}
			else
			{
				ts_debug(ts_sc, "TS_OFFSET is unchanged");
			}
		}
	}
	else
	{
		/* invalid state, should not happen */
		ts_debug(ts_sc, "invalid state (%d), should not happen", ts_sc->state);
		assert(0);
		return;
	}
}