diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/fax/fax2send.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/fax/fax2send.c')
-rwxr-xr-x | sys/src/cmd/fax/fax2send.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/sys/src/cmd/fax/fax2send.c b/sys/src/cmd/fax/fax2send.c new file mode 100755 index 000000000..af97f33a3 --- /dev/null +++ b/sys/src/cmd/fax/fax2send.c @@ -0,0 +1,171 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "modem.h" + +int +faxsend(Modem *m, int argc, char *argv[]) +{ + int c, count, r, flow; + char buf[128]; + + verbose("faxsend"); + if((r = initfaxmodem(m)) != Eok) + return r; + + /* telco just does the dialing */ + r = response(m, 120); + switch(r){ + case Rok: + break; + default: + r = seterror(m, Enoanswer); + return r; + + } + + xonoff(m, 1); + verbose("sending"); + m->pageno = 1; + while(argc--){ + if(m->pageno != 1) + sleep(1000); /* let the paper catch up */ + + m->valid &= ~(Vfhng|Vfet|Vfpts|Vftsi|Vfdcs); + if((r = openfaxfile(m, *argv)) != Eok) + return r; + + verbose("sending geometry"); + sprint(buf, "AT+FDT=%ld,%ld,%ld,%ld", m->df, m->vr, m->wd, m->ln); + if(command(m, buf) != Eok) + goto buggery; + if(response(m, 20) != Rconnect){ + r = seterror(m, Eincompatible); + goto buggery; + } + + /* + * Write the data, stuffing DLE's. + * After each bufferfull check if the remote + * sent us anything, e.g. CAN to abort. + * This also flushes out the ^S/^Q characters + * which the driver insists on sending us. + * (Could fix the driver, of course...). + */ + verbose("sending data"); + for(;;){ + flow = 0; + count = 0; + c = 0; + while(count < sizeof(buf)-1){ + if((c = Bgetc(m->bp)) < 0) + break; + buf[count++] = c; + if(c == '\020') + buf[count++] = c; + } + verbose("sending %d bytes", count); + if(count && write(m->fd, buf, count) < 0){ + verbose("write failed: %r"); + r = seterror(m, Esys); + goto buggery; + } + /* + * this does really rough flow control since the + * avanstar is even worse + */ + verbose("flow control"); + while((r = rawmchar(m, buf)) == Eok || flow){ + if(r != Eok){ + if(flow-- == 0) + break; + sleep(250); + continue; + } + switch(buf[0]){ + case '\030': + verbose("%c", buf[0]); + if(write(m->fd, "\020\003", 2) < 0){ + r = seterror(m, Esys); + goto buggery; + } + goto okexit; + case '\021': + flow = 0; + break; + case '\023': + flow = 4; + break; + case '\n': + break; + default: + verbose("%c", buf[0]); + r = seterror(m, Eproto); + goto buggery; + + } + } + if(c < 0) + break; + } + + + /* + * End of page, send DLE+ETX, + * get OK in response. + */ + verbose("sending end of page"); + if(write(m->fd, "\020\003", 2) < 0){ + r = seterror(m, Esys); + goto buggery; + } + verbose("waiting for OK"); + if(response(m, 120) != Rok){ + r = seterror(m, Enoresponse); + goto buggery; + } + + /* + * Did you hear me? - IT'S THE END OF THE PAGE. + * Argument is 0 if more pages to follow. + * Should get back an FPTS with an indication + * as to whether the page was successfully + * transmitted or not. + */ + sprint(buf, "AT+FET=%d", argc == 0? 2: 0); + if(command(m, buf) != Eok) + goto buggery; + switch(response(m, 20)){ + case Rok: + break; + case Rhangup: + if(m->fhng == 0 && argc == 0) + break; + r = seterror(m, Eproto); + goto buggery; + default: + r = seterror(m, Enoresponse); + goto buggery; + } + + if((m->valid & Vfpts) == 0 || m->fpts[0] != 1){ + r = seterror(m, Eproto); + goto buggery; + } + + Bterm(m->bp); + m->pageno++; + argv++; + } +okexit: + xonoff(m, 0); + return Eok; + +buggery: + xonoff(m, 0); + Bterm(m->bp); + command(m, "AT+FK"); + response(m, 5); + return r; +} |