irpsion5.c
来自「linux操作系统下的红外驱动的测试程序」· C语言 代码 · 共 688 行 · 第 1/2 页
C
688 行
"file size changed: initial: %lu, actual: %d\n", s.st_size, cnt); } /* Check for close on the other side */ rc = read(fd,buf,buflen); if (rc > 0) { fprintf(stderr, "Strange: the other side responded.\n"); fprintf(stderr, "rc=%d, data:%s\n", rc, buf); exit(1); } if (rc == 0) { fprintf(stderr, "Received end of file.\n"); } if (rc == -1) { if (errno == EPERM) { /* Strange error code to get in this case */ DEBUG(1, "Other side closed connection, OK\n"); } else { perror("last read"); exit(1); } } if (verbose) { t = time(NULL); if (t == t0) t++; /* white lie for fast transfers */ printf("\r%79s\r",""); /* Cleanup the progress line */ printf("Sent %s, %d bytes in %d sec. %g KBytes/sec\n", filename, cnt, t - t0, cnt / 1000.0 / (t - t0)); } close(fd); return 0;}int handle_client(int cfd) { int buflen; char* buf; int rc; /* fields of file transfer header */ unsigned int fsize; unsigned int fmode; unsigned int fdate1; unsigned int fdate2; char* fname; unsigned int fdate; unsigned long long int fdatell; FILE* f; int cnt; int t0, tx, t; buflen = irttp_get_mtu(cfd); DEBUG(1, "mtu=%d\n", buflen); if (buflen != 2045 && buflen != 2044) { fprintf(stderr, "Expecting mtu to be 2045, investigate!\n"); } DEBUG(1, "Setting mtu to 2044\n"); buflen = 2044; if (!(buf = malloc(buflen))) { perror("malloc"); exit(1); } if (!(buf = malloc(buflen))) { fprintf(stderr, "malloc buf failed\n"); exit(1); } /* Wait for the other side to send a header */ /* Sample headers received: DATA 185 FILE 55175 32 14689800 2691219200 Data size mode datehi datelo name */ /* This version only sends and receives files. It is possible to extend this to other data types the Psion can send and receive. */ rc = read(cfd, buf, buflen); if (rc < 0) { perror("1st read"); exit(1); } if (rc == 0) { perror("1st read 0"); exit(1); } assert(rc < buflen); buf[rc] = 0; DEBUG(1, "%s\n", buf); fsize = 0; fdate = 0; if (0 == strncmp(buf, "FILE ", 5)) { cnt = 0; /* to be safe */ rc = sscanf(buf, "FILE %u %u %u %u %n", &fsize, &fmode, &fdate1, &fdate2, &cnt); if (!(rc == 4 || rc == 5)) { /* grumble */ fprintf(stderr, "sscanf \"%s\" rc=%d\n", buf, rc); exit(1); } assert(cnt < buflen); fname = strdup(buf+cnt); fdatell = ((unsigned long long int) fdate1 << 32) + fdate2; fdate = ( fdatell - 62168263200000000ULL) / 1000000 ; DEBUG(1, "filename: %s\n", fname); DEBUG(1, "filesize: %d\n", fsize); DEBUG(1, "Filemode: %d", fmode); DEBUG(1, "%s", (fmode & 1 ? ", Readonly" : "")); DEBUG(1, "%s", (fmode & 2 ? ", Hidden" : "")); DEBUG(1, "%s", (fmode & 32 ? ", Modified" : "")); DEBUG(1, "%s", (fmode & ~35 ? ", Unknown" : "")); DEBUG(1, "\n"); DEBUG(1, "fdate1: %u = 0x%x\n", fdate1, fdate1); DEBUG(1, "fdate2: %u = 0x%x\n", fdate2, fdate2); DEBUG(1, "filedate: %Ld\n", fdatell); DEBUG(1, "filedate: %d = %s", fdate, asctime(gmtime((time_t*)&fdate))); if (!(f = fopen(fname,"wb"))) { perror(fname); exit(1); } } else if (0 == strncmp(buf, "DATA ", 5)) { rc = sscanf(buf, "DATA %d", &fsize); if (rc != 1) { fprintf(stderr, "sscanf rc=%d\n", rc); exit(1); } fname = strdup("/tmp/psion5-data"); if (!(f = fopen(fname,"wb"))) { perror(fname); exit(1); } } else { fprintf(stderr, "Unknown data type: %s\n", buf); exit(1); } rc = write(cfd,"ACK Y",5); if (rc != 5) { perror("1st write"); fprintf(stderr,"1st write rc = %d\n", rc); exit(1); } cnt = 0; t0 = tx = t = time(NULL); while (cnt < fsize) { int wrc; rc = read(cfd,buf,buflen); if (rc < 0) { perror("data read"); /* EPERM on disconnect ? */ exit(1); } if (rc == 0) { perror("data read 0"); exit(1); } wrc = fwrite(buf,rc,1,f); if (wrc != 1) { perror("fwrite"); exit(1); } cnt += rc; if (verbose) { /* progress indication */ t = time(NULL); if (t - t0 == 0 || cnt == 0 || tx == t) /* avoid division errors */ /* only once per second */ continue; tx = t; printf("got %d/%u bytes=%g%% in %d sec," " %g Kbytes/s, to go %i sec \r", cnt, fsize, 100.0 * cnt / fsize, t - t0, cnt / 1000.0 / (t - t0), ( fsize - cnt ) * (t - t0) / cnt); fflush(stdout); } } if (cnt != fsize) { printf("Warning: " "file size changed: initial: %u, actual: %d\n", fsize, cnt); } if (verbose) { if (t == t0) t++; /* white lie for fast transfers */ printf("\r%79s\r",""); /* Cleanup the progress line */ printf("Received %s, %d bytes in %d sec. %g KBytes/sec\n", fname, cnt, t - t0, cnt / 1000.0 / (t - t0)); } rc = fclose(f); if (rc != 0) { perror("fclose"); exit(1); } if (fdate) { struct utimbuf utb; utb.actime = fdate; utb.modtime = fdate; rc = utime(fname,&utb); if (rc != 0) { perror(fname); } } free(fname); close(cfd); return 0;}int receivefile(int mode){ /* The Psion 5 tries the following connections: Epoc32:EikonIr:v1.0 IrDA:TinyTP:LsapSel IrDA:IrCOMM Parameters IrLPT IrDA:IrLMP:LsapSel connect on 2 Warning: discovery reply after 101ms */ int addrlen = sizeof(struct sockaddr_irda); int fd; struct sockaddr_irda peer; int cfd; /* Create socket */ fd = socket(AF_IRDA, SOCK_STREAM, 0); if (fd < 0) { perror("socket"); exit(-1); } /* Bind local service */ peer.sir_family = AF_IRDA; strcpy(peer.sir_name, "Epoc32:EikonIr:v1.0"); peer.sir_lsap_sel = LSAP_ANY; if (bind(fd, (struct sockaddr*)&peer, sizeof(struct sockaddr_irda))) { perror("bind"); return -1; } if (listen(fd, 2)) { perror("listen"); return -1; } /* FIXME: allow more simultaneous clients */ for (;;) { cfd = accept(fd, (struct sockaddr *) &peer, &addrlen); if (cfd < 0) { perror("accept"); return -1; } if (handle_client(cfd)) break; if (mode == 1) break; } /* sleep(1); */ close(fd); return 0;}intmain(int argc, char* argv[]) { char* argv0 = argv[0]; if (argc <= 1) { fprintf(stderr, "Usage: %s [-S ms] [-D n] [-v] [-q] " "[-s file] [-r] [-b]\n", argv0); fprintf(stderr, "\t-s file\tSend file to the Psion\n"); fprintf(stderr, "\t-r\tReceive a file from the Psion\n"); fprintf(stderr, "\t-b\tReceive multiple files (batch mode)\n"); fprintf(stderr, "\t-v\tVerbose mode, progress indication\n"); fprintf(stderr, "\t-q\tquiet mode, no progress indication\n"); fprintf(stderr, "\t-S ms\tSet discovery slot timeout,"); fprintf(stderr, " standard 80ms, default 120ms\n"); fprintf(stderr, "\t-D n\tDebug level\n"); exit(1); } /* skip program name */ argv++; argc--; for ( ; argc>0 && argv[0] ; argc-- , argv++) { if (0 == strcmp(argv[0],"-s")) { /* FIXME: sending multiple files does not work yet. We need to wait for the user to select receive again on the psion */ if (argv[1] && 0 == strcmp(argv[1],"--")) { /* Allow the user to send ANY filename */ argv++; argv++; for ( ; argv[1] ; argv++ , argc--) { sendfile(argv[1]); } } else { /* Send files upto next switch */ while (argv[1] && *argv[1] != '-') { sendfile(argv[1]); argv++; argc--; } } } else if (argv[0] && 0 == strcmp(argv[0],"-D")) { debug_level = atoi(argv[1]); argv++; argc--; } else if (argv[0] && 0 == strcmp(argv[0],"-S")) { slot_timeout = atoi(argv[1]); argv++; argc--; } else if (argv[0] && 0 == strcmp(argv[0],"-r")) { receivefile(1); } else if (argv[0] && 0 == strcmp(argv[0],"-b")) { receivefile(0); } else if (argv[0] && 0 == strcmp(argv[0],"-v")) { verbose = 1; } else if (argv[0] && 0 == strcmp(argv[0],"-q")) { verbose = 0; } else { fprintf(stderr,"Error: unknown switch %s\n", argv[0]); fprintf(stderr,"Call without args for usage: %s\n", argv0); exit(1); } } return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?