Exemplo n.º 1
0
static gboolean received_data(GIOChannel *channel, GIOCondition cond,
				gpointer data)
{
	unsigned char *buf;
	GRilIO *io = data;
	GIOStatus status;
	gsize rbytes;
	gsize toread;
	gsize total_read = 0;
	guint read_count = 0;

	if (cond & G_IO_NVAL)
		return FALSE;

	/* Regardless of condition, try to read all the data available */
	do {
		toread = ring_buffer_avail_no_wrap(io->buf);

		if (toread == 0)
			break;

		rbytes = 0;
		buf = ring_buffer_write_ptr(io->buf, 0);

		status = g_io_channel_read_chars(channel, (char *) buf,
							toread, &rbytes, NULL);

		g_ril_util_debug_hexdump(TRUE, buf, rbytes,
						io->debugf, io->debug_data);

		read_count++;

		total_read += rbytes;

		if (rbytes > 0)
			ring_buffer_write_advance(io->buf, rbytes);

	} while (status == G_IO_STATUS_NORMAL && rbytes > 0 &&
					read_count < io->max_read_attempts);

	if (total_read > 0 && io->read_handler)
		io->read_handler(io->buf, io->read_data);

	if (cond & (G_IO_HUP | G_IO_ERR))
		return FALSE;

	if (read_count > 0 && rbytes == 0 && status != G_IO_STATUS_AGAIN)
		return FALSE;

	/* We're overflowing the buffer, shutdown the socket */
	if (ring_buffer_avail(io->buf) == 0)
		return FALSE;

	return TRUE;
}
Exemplo n.º 2
0
gboolean g_at_hdlc_send(GAtHDLC *hdlc, const unsigned char *data, gsize size)
{
	unsigned int avail = ring_buffer_avail(hdlc->write_buffer);
	unsigned int wrap = ring_buffer_avail_no_wrap(hdlc->write_buffer);
	unsigned char *buf = ring_buffer_write_ptr(hdlc->write_buffer, 0);
	unsigned char tail[2];
	unsigned int i = 0;
	guint16 fcs = HDLC_INITFCS;
	gboolean escape = FALSE;
	gsize pos = 0;

	if (avail < size)
		return FALSE;

	i = 0;

	while (pos < avail && i < size) {
		if (escape == TRUE) {
			fcs = HDLC_FCS(fcs, data[i]);
			*buf = data[i++] ^ HDLC_TRANS;
			escape = FALSE;
		} else if (NEED_ESCAPE(hdlc->xmit_accm, data[i])) {
			*buf = HDLC_ESCAPE;
			escape = TRUE;
		} else {
			fcs = HDLC_FCS(fcs, data[i]);
			*buf = data[i++];
		}

		buf++;
		pos++;

		if (pos == wrap)
			buf = ring_buffer_write_ptr(hdlc->write_buffer, pos);
	}

	if (i < size)
		return FALSE;

	fcs ^= HDLC_INITFCS;
	tail[0] = fcs & 0xff;
	tail[1] = fcs >> 8;

	i = 0;

	while (pos < avail && i < sizeof(tail)) {
		if (escape == TRUE) {
			*buf = tail[i++] ^ HDLC_TRANS;
			escape = FALSE;
		} else if (NEED_ESCAPE(hdlc->xmit_accm, tail[i])) {
			*buf = HDLC_ESCAPE;
			escape = TRUE;
		} else {
			*buf = tail[i++];
		}

		buf++;
		pos++;

		if (pos == wrap)
			buf = ring_buffer_write_ptr(hdlc->write_buffer, pos);
	}

	if (i < sizeof(tail))
		return FALSE;

	if (pos + 1 > avail)
		return FALSE;

	*buf = HDLC_FLAG;
	pos++;

	ring_buffer_write_advance(hdlc->write_buffer, pos);

	g_at_io_set_write_handler(hdlc->io, can_write_data, hdlc);

	return TRUE;
}