1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 5 #include "modem.h" 6 7 int 8 faxsend(Modem *m, int argc, char *argv[]) 9 { 10 int c, count, r; 11 char buf[128]; 12 13 verbose("faxsend"); 14 if((r = initfaxmodem(m)) != Eok) 15 return r; 16 17 /* telco just does the dialing */ 18 r = response(m, 120); 19 switch(r){ 20 case Rok: 21 break; 22 default: 23 r = seterror(m, Enoanswer); 24 return r; 25 26 } 27 28 m->pageno = 1; 29 while(argc--){ 30 if(m->pageno != 1) 31 sleep(1000); /* let the paper catch up */ 32 33 m->valid &= ~(Vfhng|Vfet|Vfpts|Vftsi|Vfdcs); 34 if((r = openfaxfile(m, *argv)) != Eok) 35 return r; 36 37 sprint(buf, "AT+FDT=%d,%d,%d,%d", m->df, m->vr, m->wd, m->ln); 38 if(command(m, buf) != Eok) 39 goto buggery; 40 if(response(m, 20) != Rconnect){ 41 r = seterror(m, Eincompatible); 42 goto buggery; 43 } 44 45 /* wait for first ^S */ 46 getmchar(m, buf, 5); 47 48 /* 49 * Write the data, stuffing DLE's. 50 * After each bufferfull check if the remote 51 * sent us anything, e.g. CAN to abort. 52 * This also flushes out the ^S/^Q characters 53 * which the driver insists on sending us. 54 * (Could fix the driver, of course...). 55 */ 56 for(;;){ 57 count = 0; 58 c = 0; 59 while(count < sizeof(buf)-1){ 60 if((c = BGETC(m->bp)) < 0) 61 break; 62 buf[count++] = c; 63 if(c == '\020') 64 buf[count++] = c; 65 } 66 if(count && write(m->fd, buf, count) < 0){ 67 r = seterror(m, Esys); 68 goto buggery; 69 } 70 if(c < 0) 71 break; 72 73 while((r = rawmchar(m, buf)) == Eok){ 74 if(buf[0] == '\030'){ 75 verbose("%c", buf[0]); 76 if(write(m->fd, "\020\003", 2) < 0){ 77 r = seterror(m, Esys); 78 goto buggery; 79 } 80 goto okexit; 81 } 82 if(buf[0] != '\021' && buf[0] != '\023' && buf[0] != '\n'){ 83 verbose("%c", buf[0]); 84 r = seterror(m, Eproto); 85 goto buggery; 86 } 87 } 88 } 89 90 /* 91 * End of page, send DLE+ETX, 92 * get OK in response. 93 */ 94 if(write(m->fd, "\020\003", 2) < 0){ 95 r = seterror(m, Esys); 96 goto buggery; 97 } 98 if(response(m, 20) != Rok){ 99 r = seterror(m, Enoresponse); 100 goto buggery; 101 } 102 103 /* 104 * Did you hear me? - IT'S THE END OF THE PAGE. 105 * Argument is 0 if more pages to follow. 106 * Should get back an FPTS with an indication 107 * as to whether the page was successfully 108 * transmitted or not. 109 */ 110 sprint(buf, "AT+FET=%d", argc == 0? 2: 0); 111 if(command(m, buf) != Eok) 112 goto buggery; 113 switch(response(m, 20)){ 114 case Rok: 115 break; 116 case Rhangup: 117 if(m->fhng == 0 && argc == 0) 118 break; 119 r = seterror(m, Eproto); 120 goto buggery; 121 default: 122 r = seterror(m, Enoresponse); 123 goto buggery; 124 } 125 126 if((m->valid & Vfpts) == 0 || m->fpts[0] != 1){ 127 r = seterror(m, Eproto); 128 goto buggery; 129 } 130 131 Bterm(m->bp); 132 m->pageno++; 133 argv++; 134 } 135 okexit: 136 return Eok; 137 138 buggery: 139 Bterm(m->bp); 140 command(m, "AT+FK"); 141 response(m, 5); 142 return r; 143 } 144