?? irdaspray.c
字號:
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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -