Ejemplo n.º 1
0
/**
 * Try to read message from transport into msg.
 *
 * @returns TRUE if message is fully read.
 */
bool
xmms_ipc_msg_read_transport (xmms_ipc_msg_t *msg,
                             xmms_ipc_transport_t *transport,
                             bool *disconnected)
{
	char buf[512];
	unsigned int ret, len, rlen;

	x_return_val_if_fail (msg, false);
	x_return_val_if_fail (transport, false);

	while (true) {
		len = XMMS_IPC_MSG_HEAD_LEN;

		if (msg->xfered >= XMMS_IPC_MSG_HEAD_LEN) {
			len += xmms_ipc_msg_get_length (msg);

			if (msg->xfered == len) {
				return true;
			}
		}

		x_return_val_if_fail (msg->xfered < len, false);

		rlen = len - msg->xfered;
		if (rlen > sizeof (buf))
			rlen = sizeof (buf);

		ret = xmms_ipc_transport_read (transport, buf, rlen);

		if (ret == SOCKET_ERROR) {
			if (xmms_socket_error_recoverable ()) {
				return false;
			}

			if (disconnected) {
				*disconnected = true;
			}

			return false;
		} else if (ret == 0) {
			if (disconnected) {
				*disconnected = true;
			}

			return false;
		} else {
			xmmsv_bitbuffer_goto (msg->bb, msg->xfered * 8);
			xmmsv_bitbuffer_put_data (msg->bb, (unsigned char *) buf, ret);
			msg->xfered += ret;
			xmmsv_bitbuffer_goto (msg->bb, XMMS_IPC_MSG_HEAD_LEN * 8);
		}
	}
}
Ejemplo n.º 2
0
/**
 * Try to write message to transport. If full message isn't written
 * the message will keep track of the amount of data written and not
 * write already written data next time.
 *
 * @returns TRUE if full message was written, FALSE otherwise.
 *               disconnected is set if transport was disconnected
 */
bool
xmms_ipc_msg_write_transport (xmms_ipc_msg_t *msg,
                              xmms_ipc_transport_t *transport,
                              bool *disconnected)
{
	char *buf;
	unsigned int ret, len;

	x_return_val_if_fail (msg, false);
	x_return_val_if_fail (transport, false);

	xmmsv_bitbuffer_align (msg->bb);

	len = xmmsv_bitbuffer_len (msg->bb) / 8;

	x_return_val_if_fail (len > msg->xfered, true);

	buf = (char *) (xmmsv_bitbuffer_buffer (msg->bb) + msg->xfered);
	ret = xmms_ipc_transport_write (transport, buf, len - msg->xfered);

	if (ret == SOCKET_ERROR) {
		if (xmms_socket_error_recoverable ()) {
			return false;
		}

		if (disconnected) {
			*disconnected = true;
		}

		return false;
	} else if (!ret) {
		if (disconnected) {
			*disconnected = true;
		}
	} else {
		msg->xfered += ret;
	}

	return (len == msg->xfered);
}
Ejemplo n.º 3
0
int
read_do_udp (xmmsc_vis_udp_t *t, xmmsc_visualization_t *v, short *buffer, int drawtime, unsigned int blocking)
{
	int old;
	int ret;
	int i, size;
	xmmsc_vis_udp_data_t packet_d;
	char* packet = packet_init_data (&packet_d);
	xmmsc_vischunk_t data;

	if (blocking) {
		wait_for_socket (t, blocking);
	}

	ret = recv (t->socket[0], packet, packet_d.size, 0);
	if ((ret > 0) && (*packet_d.__unaligned_type == 'V')) {
		uint16_t grace;
		struct timeval rtv;

		XMMSC_VIS_UNALIGNED_READ (data, packet_d.__unaligned_data, xmmsc_vischunk_t);

		/* resync connection */
		XMMSC_VIS_UNALIGNED_READ (grace, packet_d.__unaligned_grace, uint16_t);
		grace = ntohs (grace);
		if (grace < 1000) {
			if (t->grace != 0) {
				t->grace = 0;
				/* use second socket here, so vis packets don't get lost */
				t->timediff = udp_timediff (v->id, t->socket[1]);
			}
		} else {
			t->grace = grace;
		}
		/* include the measured time difference */

		rtv.tv_sec = ntohl (data.timestamp[0]);
		rtv.tv_usec = ntohl (data.timestamp[1]);

		double interim = tv2ts (&rtv);
		interim -= t->timediff;
		ts2net (data.timestamp, interim);
		ret = 1;
	} else {
		if (ret == 1 && *packet_d.__unaligned_type == 'K') {
			ret = -1;
		} else if (ret > -1 || xmms_socket_error_recoverable ()) {
			ret = 0;
		} else {
			ret = -1;
		}
		free (packet);
		return ret;
	}

	old = check_drawtime (net2ts (data.timestamp), drawtime);

	if (!old) {
		size = ntohs (data.size);
		for (i = 0; i < size; ++i) {
			buffer[i] = (int16_t)ntohs (data.data[i]);
		}
	}

	free (packet);

	if (!old) {
		return size;
	}
	return 0;
}