Example #1
0
static double
udp_timediff (int32_t id, int socket) {
	int i;
	double lag;
	struct timeval time;
	double diff = 0.0;
	int diffc = 0;
	xmmsc_vis_udp_timing_t packet_d;
	char* packet = packet_init_timing (&packet_d);

	gettimeofday (&time, NULL);
	XMMSC_VIS_UNALIGNED_WRITE (packet_d.__unaligned_id, (int32_t)htonl (id), int32_t);
	XMMSC_VIS_UNALIGNED_WRITE (&packet_d.__unaligned_clientstamp[0],
	                           (int32_t)htonl (time.tv_sec), int32_t);
	XMMSC_VIS_UNALIGNED_WRITE (&packet_d.__unaligned_clientstamp[1],
	                           (int32_t)htonl (time.tv_usec), int32_t);

	/* TODO: handle lost packages! */
	for (i = 0; i < 10; ++i) {
		send (socket, packet, packet_d.size, 0);
	}
	printf ("Syncing ");
	do {
		if ((recv (socket, packet, packet_d.size, 0) == packet_d.size) && (*packet_d.__unaligned_type == 'T')) {
			struct timeval rtv;
			gettimeofday (&time, NULL);
			XMMSC_VIS_UNALIGNED_READ (rtv.tv_sec, &packet_d.__unaligned_clientstamp[0], int32_t);
			XMMSC_VIS_UNALIGNED_READ (rtv.tv_usec, &packet_d.__unaligned_clientstamp[1], int32_t);
			rtv.tv_sec = ntohl (rtv.tv_sec);
			rtv.tv_usec = ntohl (rtv.tv_usec);

			lag = (tv2ts (&time) - tv2ts (&rtv)) / 2.0;
			diffc++;

			XMMSC_VIS_UNALIGNED_READ (rtv.tv_sec, &packet_d.__unaligned_serverstamp[0], int32_t);
			XMMSC_VIS_UNALIGNED_READ (rtv.tv_usec, &packet_d.__unaligned_serverstamp[1], int32_t);
			rtv.tv_sec = ntohl (rtv.tv_sec);
			rtv.tv_usec = ntohl (rtv.tv_usec);

			diff += tv2ts (&rtv) - lag;
			/* debug output
			printf("server diff: %f \t old timestamp: %f, new timestamp %f\n",
			       net2ts (packet_d.serverstamp), net2ts (packet_d.clientstamp), tv2ts (&time));
			 end of debug */
			putchar('.');
		}
	} while (diffc < 10);
	free (packet);

	puts (" done.");
	return diff / (double)diffc;
}
Example #2
0
File: udp.c Project: theefer/xmms2
static gboolean
udpwatcher (GIOChannel *src, GIOCondition cond, xmms_visualization_t *vis)
{
	struct sockaddr_storage from;
	socklen_t sl = sizeof (from);
	xmmsc_vis_udp_timing_t packet_d;
	char* packet = packet_init_timing (&packet_d);
	if ((recvfrom (vis->socket, packet, packet_d.size, 0, (struct sockaddr *)&from, &sl)) > 0) {
		if (*packet_d.__unaligned_type == 'H') {
			xmms_vis_client_t *c;
			int32_t id;

			XMMSC_VIS_UNALIGNED_READ (id, packet_d.__unaligned_id, int32_t);
			id = ntohl (id);

			/* debug code starts
			char adrb[INET6_ADDRSTRLEN];
			struct sockaddr_in6 *a = (struct sockaddr_in6 *)&from;
			printf ("Client address: %s:%d, %d\n", inet_ntop (AF_INET6, &a->sin6_addr,
					adrb, INET6_ADDRSTRLEN), a->sin6_port, id);
			 debug code ends */
			g_mutex_lock (vis->clientlock);
			c = get_client (id);
			if (!c || c->type != VIS_UDP) {
				g_mutex_unlock (vis->clientlock);
				return TRUE;
			}
			/* save client address according to id */
			memcpy (&c->transport.udp.addr, &from, sizeof (from));
			c->transport.udp.socket[0] = 1;
			c->transport.udp.grace = 2000;
			g_mutex_unlock (vis->clientlock);
		} else if (*packet_d.__unaligned_type == 'T') {
			struct timeval time;
			xmms_vis_client_t *c;
			int32_t id;

			XMMSC_VIS_UNALIGNED_READ (id, packet_d.__unaligned_id, int32_t);
			id = ntohl (id);

			g_mutex_lock (vis->clientlock);
			c = get_client (id);
			if (!c || c->type != VIS_UDP) {
				g_mutex_unlock (vis->clientlock);
				free (packet);
				return TRUE;
			}
			c->transport.udp.grace = 2000;
			g_mutex_unlock (vis->clientlock);

			/* give pong */
			gettimeofday (&time, NULL);

			struct timeval cts, sts;

			XMMSC_VIS_UNALIGNED_READ (cts.tv_sec, &packet_d.__unaligned_clientstamp[0], int32_t);
			XMMSC_VIS_UNALIGNED_READ (cts.tv_usec, &packet_d.__unaligned_clientstamp[1], int32_t);
			cts.tv_sec = ntohl (cts.tv_sec);
			cts.tv_usec = ntohl (cts.tv_usec);

			sts.tv_sec = time.tv_sec - cts.tv_sec;
			sts.tv_usec = time.tv_usec - cts.tv_usec;
			if (sts.tv_usec < 0) {
				sts.tv_sec--;
				sts.tv_usec += 1000000;
			}

			XMMSC_VIS_UNALIGNED_WRITE (&packet_d.__unaligned_serverstamp[0],
			                           (int32_t)htonl (sts.tv_sec), int32_t);
			XMMSC_VIS_UNALIGNED_WRITE (&packet_d.__unaligned_serverstamp[1],
			                           (int32_t)htonl (sts.tv_usec), int32_t);

			sendto (vis->socket, packet, packet_d.size, 0, (struct sockaddr *)&from, sl);

			/* new debug:
			printf ("Timings: local %f, remote %f, diff %f\n", tv2ts (&time), net2ts (packet_d.clientstamp), net2ts (packet_d.clientstamp) - tv2ts (&time));
			 ends */
		} else {
			xmms_log_error ("Received invalid UDP package!");
		}
	}
	free (packet);
	return TRUE;
}