irdaspray.c

来自「linux操作系统下的红外驱动的测试程序」· C语言 代码 · 共 902 行 · 第 1/2 页

C
902
字号
		       sizeof(ias_query))) 	  {	    printf("Can't remove <Device><Owner> in IAS\n");	    perror("setsockopt");	  }	/* Delete the last string in IAS */	if (echo)		strcpy(ias_query.irda_class_name, "IrECHO");	else		strcpy(ias_query.irda_class_name, "IrDISCARD");	strcpy(ias_query.irda_attrib_name, "App-Name");	if (setsockopt(fd, SOL_IRLMP, IRLMP_IAS_DEL, &ias_query, 		       sizeof(ias_query))) 	  {	    printf("Can't remove <IrECHO><App-Name> in IAS\n");	  }	/* Delete the other integer in IAS */	strcpy(ias_query.irda_class_name, "");	strcpy(ias_query.irda_attrib_name, "App-Version");	if (setsockopt(fd, SOL_IRLMP, IRLMP_IAS_DEL, &ias_query, 		       sizeof(ias_query))) 	  {	    printf("Can't remove <><App-Version> in IAS\n");	    perror("setsockopt");	  }	/* Try to delete a kernel attribute (should fail) */	strcpy(ias_query.irda_class_name, "Device");	strcpy(ias_query.irda_attrib_name, "DeviceName");	if (setsockopt(fd, SOL_IRLMP, IRLMP_IAS_DEL, &ias_query, 		       sizeof(ias_query))) 	  {	    printf("Can't remove <Device><DeviceName> in IAS\n");	    perror("setsockopt");	  }	/* Try to delete a non-existing attribute (should fail) */	strcpy(ias_query.irda_class_name, "None");	strcpy(ias_query.irda_attrib_name, "None");	if (setsockopt(fd, SOL_IRLMP, IRLMP_IAS_DEL, &ias_query, 		       sizeof(ias_query))) 	  {	    printf("Can't remove <None><None> in IAS\n");	    perror("setsockopt");	  }}/* * Function irdaspray_connect_request (self) * *    Try to connect to remote device * */static int irdaspray_connect_request(int fd){	struct sockaddr_irda peer;	struct sockaddr_irda self;	char *service_name;	int len = sizeof(int);	int daddr;#if AUTOCONNECT	int err;#endif	/* Set the service name */	if (echo)		service_name = "IrECHO";	else		service_name = "IrDISCARD";#if WAITFORDEVICE	/* Wait until a device is in range */	if(irdaspray_waitfor_device(fd))		return -1;#endif#if AUTOCONNECT	/*	 * First, we try the auto-connect, which in 99% of the case	 * should be good enough...	 *	 * Auto connect lookup devices in range and query them about the	 * service we want. If there is only one device that support	 * this service, we are magically connected to it...	 */	peer.sir_family = AF_IRDA;	strncpy(peer.sir_name, service_name, 25);	peer.sir_addr = 0x0;	/* Maybe DEV_ADDR_ANY is better ? */		err = connect(fd, (struct sockaddr*) &peer, 		      sizeof(struct sockaddr_irda));	/* Check what has happened */	if(err == 0) {		printf("Auto-connect did found exactly one device !\n");		return 0;	}	if(errno == EADDRNOTAVAIL) {		printf("Auto-connect could not find anything...\n");		return -1;	}	if(errno != ENOTUNIQ)		printf("Auto-connect failed...\n");	else		printf("Auto-connect has found more than one device...\n");#endif	/*	 * At this point, if we don't have any user interface or if we	 * don't want to bother with that, we could just tell the user	 * to aim its device closer to the target and just quit...	 * (or we could pretend that we have seen nothing, which will	 * end up with the same result on the user)	 * However, for the purpose of the exercise, let's pretend that	 * the user doesn't want to move his device and has plenty of UI...	 */	/* Make a proper discovery, display device and ask user to choose */	daddr = irdaspray_discover_devices(fd, service_name);	if (daddr == -1)		return -1;	/* Now we can try again to connect using the address selected */	peer.sir_family = AF_IRDA;	strncpy(peer.sir_name, service_name, 25);	peer.sir_addr = daddr;		if (connect(fd, (struct sockaddr*) &peer, 		    sizeof(struct sockaddr_irda))) {		perror("connect");		return -1;	}#if GETSOCKNAME	/* Get out info about our socket (local, not remote) */	len = sizeof(struct sockaddr_irda);	if (getsockname(fd, (struct sockaddr*) &self, &len)) {		perror("getsockname");		return -1;	}	printf("We have been assigned Address 0x%X and LSAP 0x%02X...\n",	       self.sir_addr, self.sir_lsap_sel);	/* Note : getsockname return a valid lsap after a connect or a bind,	 * but return a valid addr only after an accept, and with my patch	 * also after a connect.	 */#endif	printf("Connected!\n");	/* Test if IR-IAS is happy */#if SETIAS	irias_play(fd);#endif#if DELIAS	irias_remove(fd);#endif	return 0;}int irdaspray_transmit(int fd){	int total = 0;	int actual;	int i;	/* Transmit frames */	for (i=0; i<frame_number; i++) {		actual = send(fd, buf, frame_size, 0);		total += actual;	}	return total;}int irdaspray_receive(int fd){	int total = 0;	int actual;	int i;	/* Receive frames */	for (i=0; i<frame_number; i++) {		actual = recv(fd, buf, sizeof(buf), 0);		total += actual;	}	return total;}/* * Function ir_client () * *    Implements IrDA Echo or Discard client * */int ir_client(void){	int fd;		/* The most important : the socket !!! */	struct timeval start, end;	int total;	double time;	int status;	int ret;	int pid = 0;		/* Sender/Receiver */	int tpid = 0;		/* First/second instance */	/* Create socket */	fd = socket(AF_IRDA, SOCK_SEQPACKET, 0);	if (fd < 0) {		perror("socket");		exit(-1);        }	/* Try connect */	ret = irdaspray_connect_request(fd);	if (ret) {		return -1;	}		gettimeofday(&start, (struct timezone*) 0);	/* Check if we need to have two clients going on */	if(two) {		/* Spawn second instances */		tpid = fork();		/* If in parent */		if(tpid) {			/* Close socket */			close(fd);			/* Open a new socket */			fd = socket(AF_IRDA, SOCK_SEQPACKET, 0);			if (fd < 0) {				perror("socket");				exit(-1);			}			/* Connect the new socket */			ret = irdaspray_connect_request(fd);			if (ret) {				return -1;			}		}	}	if (echo) {		/* Fork off transmitter */		pid = fork();				if (pid) {	/* parent */			total = irdaspray_receive(fd);		} else {	/* child */			total = irdaspray_transmit(fd);		}	} else			/* single */		total = irdaspray_transmit(fd);	/* pid==0: single-thread(discard-tx) or child(echo-tx)	 * pid!=0: parent(echo-rx)	 */	gettimeofday(&end, (struct timezone*) 0);	time = (double) (end.tv_sec - start.tv_sec) + (double)		((double) (end.tv_usec - start.tv_usec) / 1000000.0);	if (pid) {	/* parent */		wait(&status);		printf("Received %d bytes in %f seconds (%0.3f kbytes/s)\n",		       total, time, (double) (total / time) / 1024); 	}	else {		/* child or single-thread */		printf("Transmitted %d bytes in %f seconds (%0.3f kbytes/s)\n",		       total, time, (double) (total / time) / 1024);	}	return 0;}/* * Function ir_server () * *    Implements IrDA Echo or Discard server * */int ir_server(void){	struct sockaddr_irda peer, self;	int addrlen;	int actual;	int fd, conn_fd;	int pid = 0;	/* Check personality */	if (echo)		printf("IrDA Echo server starting ...\n");	else		printf("IrDA Discard server starting ...\n");	/* Create socket */	fd = socket(AF_IRDA, SOCK_SEQPACKET, 0);	if (fd < 0) {		perror("socket");		exit(-1);        }	/* Init self */	self.sir_family = AF_IRDA;	if (echo)		strncpy(self.sir_name, "IrECHO", 25);	else		strncpy(self.sir_name, "IrDISCARD", 25);	self.sir_lsap_sel = LSAP_ANY;		if (bind(fd, (struct sockaddr*) &self, sizeof(struct sockaddr_irda))) {		perror("bind");		return -1;	}	/* Test if IR-IAS is happy */#if SETIAS	irias_play(fd);#endif#if DELIAS	irias_remove(fd);#endif	if (listen(fd, 8)) {		perror("listen");		return -1;	}	for (;;) {		addrlen = sizeof(struct sockaddr_irda);		printf("Waiting for connection!\n");		/* collect old server zombies */		while (waitpid(-1, NULL, WNOHANG) > 0)			;		conn_fd = accept(fd, (struct sockaddr *) &peer, &addrlen);		if (conn_fd < 0) {			perror("accept");			return -1;		}		/* Fork off receiver, so that we can accept multiple		 * simultaneous connections */		pid = fork();		/* If in children, receive, in parent, listen */		if(!pid) {			printf("Connected!\n");					do {				actual = recv(conn_fd, &buf, sizeof(buf), 0);				if (actual <= 0) 					break;				printf("Got %d bytes\n", actual);							if (echo) {					actual = send(conn_fd, &buf, actual, 0);					printf("Sent %d bytes\n", actual);				}			} while (actual > 0);			close(conn_fd);			printf("Disconnected!\n");			/* Quit the child */			return(0);		}	}	return 0;}static void usage(char *argv[]){	fprintf(stderr, "usage: %s [-s] [-c] [-d] [-e] [-h] [-b frame-size] [-n frames] \n", argv[0]);	fprintf(stderr, "      -s act as a server\n");	fprintf(stderr, "      -c act as a client (default)\n");	fprintf(stderr, "      -d use discard service for unidirection transfer\n");	fprintf(stderr, "      -e use echo service for bidirection transfer (default)\n");	fprintf(stderr, "      -t open two concurent client sockets\n");	fprintf(stderr, "      -h print this message ;-)\n");	fprintf(stderr, "      -b frame-size in bytes (default 1024, max 8192)\n");	fprintf(stderr, "      -n number of frames (default 100)\n");	exit(1);}/* * Function main (argc, ) * *     * */int main(int argc, char *argv[]){	int c;	while ((c = getopt(argc, argv, "vscdethb:m:n:f:")) != -1) {		switch (c) {			 		case 's':			server = 1; /* Act as a server */ 			break;			 		case 'c':			server = 0; /* Act as a client */ 			break;			 		case 'd': 			echo = 0; /* Use discard service instead of echo */ 			break;			 		case 'e': 			echo = 1; /* Use echo service instead of discard */ 			break;			 		case 't':			two = 1; /* Open two client sockets */ 			break;					case 'h':			usage(argv);			break;					case 'n':			frame_number = atoi(optarg);			break;					case 'b':			frame_size = atoi(optarg);			break;		default:			usage(argv);			break;		}	}	/* Start client or server as needed */	if(server)		return(ir_server());	else		return(ir_client());}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?