/* Return a DTP41 error code */ static int dtp41_fcommand( dtp41 *p, char *in, /* In string */ char *out, /* Out string buffer */ int bsize, /* Out buffer size */ char *tc, /* Terminating characters */ int ntc, /* Number of terminating characters */ double to) { /* Timout in seconts */ int rv, se; if ((se = p->icom->write_read(p->icom, in, 0, out, bsize, NULL, tc, ntc, to)) != 0) { a1logd(p->log, 1, "dtp41_fcommand: serial i/o failure 0x%x on write_read '%s'\n",se,icoms_fix(in)); return icoms2dtp41_err(se); } rv = DTP41_OK; if (tc[0] == '>' && ntc == 1) { rv = extract_ec(out); if (rv > 0) { rv &= inst_imask; if (rv != DTP41_OK) { /* Clear the error */ char buf[MAX_MES_SIZE]; p->icom->write_read(p->icom, "CE\r", 0, buf, MAX_MES_SIZE, NULL, ">", 1, 0.5); } } } a1logd(p->log, 4, "dtp41_fcommand: command '%s' returned '%s', value 0x%x\n", icoms_fix(in), icoms_fix(out),rv); return rv; }
/* Return a DTP51 error code */ static int dtp51_fcommand( struct _dtp51 *p, char *in, /* In string */ char *out, /* Out string buffer */ int bsize, /* Out buffer size */ char tc, /* Terminating character */ int ntc, /* Number of terminating characters */ double to) { /* Timout in seconts */ int rv, se; if ((se = p->icom->write_read(p->icom, in, out, bsize, tc, ntc, to)) != 0) { #ifdef DEBUG printf("dtp51 fcommand: serial i/o failure on write_read '%s'\n",icoms_fix(in)); #endif return icoms2dtp51_err(se); } rv = DTP51_OK; if (tc == '>' && ntc == 1) { rv = extract_ec(out); if (rv > 0) { rv &= inst_imask; if (rv != DTP51_OK) { /* Clear the error */ char buf[MAX_MES_SIZE]; p->icom->write_read(p->icom, "CE\r", buf, MAX_MES_SIZE, '>', 1, 0.5); } } } #ifdef DEBUG printf("command '%s'",icoms_fix(in)); printf(" returned '%s', value 0x%x\n",icoms_fix(out),rv); #endif return rv; }
/* Return the dtp error code */ static inst_code hcfr_command( hcfr *p, char *in, /* In string */ char *out, /* Out string */ int bsize, /* Out buffer size */ double to /* Timeout in seconds */ ) { int rv, se; if ((se = p->icom->write_read(p->icom, in, out, bsize, '\n', 1, to)) != 0) { int ec; #ifdef DEBUG printf("hcfr fcommand: serial i/o failure on write_read '%s'\n",icoms_fix(in)); #endif return hcfr_interp_code((inst *)p, icoms2hcfr_err(se)); } #ifdef DEBUG printf("command '%s'",icoms_fix(in)); printf(" returned '%s', value 0x%x\n",icoms_fix(out),HCFR_OK); #endif return hcfr_interp_code((inst *)p, HCFR_OK); }
/* return icom error */ static int icoms_ser_read( icoms *p, char *rbuf, /* Buffer to store characters read */ int bsize, /* Buffer size */ int *pbread, /* Bytes read (not including forced '\000') */ char *tc, /* Terminating characers, NULL for none or char count mode */ int ntc, /* Number of terminating characters or char count needed, if 0 use bsize */ double tout /* Time out in seconds */ ) { int j, rbytes; long ttop, top; /* Total timeout period, timeout period */ unsigned int stime, etime; /* Start and end times of USB operation */ struct pollfd pa[1]; /* Poll array to monitor serial read and stdin */ int nfd = 1; /* Number of fd's to poll */ struct termios origs, news; char *rrbuf = rbuf; /* Start of return buffer */ int bread = 0; int retrv = ICOM_OK; int nreads; /* Number of reads performed */ if (!p->is_open) { a1loge(p->log, ICOM_SYS, "icoms_ser_read: device not initialised\n"); p->lserr = ICOM_SYS; return p->lserr; } if (bsize < 3) { a1loge(p->log, ICOM_SYS, "icoms_ser_read: given too small a buffer\n"); p->lserr = ICOM_SYS; return p->lserr; } for (j = 0; j < bsize; j++) rbuf[j] = 0; ttop = (int)(tout * 1000.0 + 0.5); /* Total timeout period in msecs */ a1logd(p->log, 8, "\nicoms_ser_read: bytes %d, ttop %d, ntc %d\n", bsize, ttop, ntc); /* Wait for serial input to have data */ pa[0].fd = p->fd; pa[0].events = POLLIN | POLLPRI; pa[0].revents = 0; bsize -=1; /* Allow space for forced null */ /* Until data is all read, we time out, or the user aborts */ etime = stime = msec_time(); j = (tc == NULL && ntc <= 0) ? -1 : 0; /* Until data is all read or we time out */ for (top = ttop, nreads = 0; top > 0 && bsize > 0 && j < ntc ;) { if (poll_x(pa, nfd, top) > 0) { if (pa[0].revents != 0) { int btr; if (pa[0].revents != POLLIN && pa[0].revents != POLLPRI) { a1loge(p->log, ICOM_SYS, "icoms_ser_read: poll on serin returned " "unexpected value 0x%x",pa[0].revents); p->lserr = ICOM_SYS; return p->lserr; } /* We have data to read from input */ rbytes = read(p->fd, rbuf, bsize); if (rbytes < 0) { a1logd(p->log, 8, "icoms_ser_read: read failed with %d, rbuf = '%s'\n",rbytes,icoms_fix(rrbuf)); retrv |= ICOM_SERR; break; } else if (rbytes > 0) { a1logd(p->log, 8, "icoms_ser_read: read %d bytes, rbuf = '%s'\n",rbytes,icoms_fix(rrbuf)); bsize -= rbytes; if (tc != NULL) { while(rbytes--) { /* Count termination characters */ char ch = *rbuf++, *tcp = tc; while(*tcp != '\000') { if (ch == *tcp) j++; tcp++; } } a1logd(p->log, 8, "icoms_ser_read: tc count %d\n",j); } else { if (ntc > 0) j += rbytes; rbuf += rbytes; } } } } etime = msec_time(); top = ttop - (etime - stime); /* Remaining time */ } *rbuf = '\000'; a1logd(p->log, 8, "icoms_ser_read: read %d total bytes with %d reads\n",rbuf - rrbuf, nreads); if (pbread != NULL) *pbread = (rbuf - rrbuf); /* If ran out of time and not completed */ a1logd(p->log, 8, "icoms_ser_read: took %d msec\n",etime - stime); if (top <= 0 && bsize > 0 && j < ntc) { a1logd(p->log, 8, "icoms_ser_read: timeout, took %d msec out of %d\n",etime - stime,ttop); retrv |= ICOM_TO; } a1logd(p->log, 8, "icoms_ser_read: took %d msec, returning '%s' ICOM err 0x%x\n", etime - stime, tc == NULL && ntc > 0 ? icoms_tohex((unsigned char *)rrbuf, rbuf - rrbuf) : icoms_fix(rrbuf), retrv); p->lserr = retrv; return p->lserr; }
/* Set the icoms lserr value */ static int icoms_ser_write( icoms *p, char *wbuf, /* null terminated unless nwch > 0 */ int nwch, /* if > 0, number of characters to write */ double tout ) { int len, wbytes; long ttop, top; /* Total timeout period, timeout period */ unsigned int stime, etime; /* Start and end times of USB operation */ struct pollfd pa[1]; /* Poll array to monitor serial write and stdin */ int nfd = 1; /* Number of fd's to poll */ struct termios origs, news; int retrv = ICOM_OK; a1logd(p->log, 8, "\nicoms_ser_write: writing '%s'\n", nwch > 0 ? icoms_tohex((unsigned char *)wbuf, nwch) : icoms_fix(wbuf)); if (!p->is_open) { a1loge(p->log, ICOM_SYS, "icoms_ser_write: device not initialised\n"); p->lserr = ICOM_SYS; return p->lserr; } /* Setup to wait for serial output not block */ pa[0].fd = p->fd; pa[0].events = POLLOUT; pa[0].revents = 0; if (nwch != 0) len = nwch; else len = strlen(wbuf); ttop = (int)(tout * 1000.0 + 0.5); /* Total timeout period in msecs */ a1logd(p->log, 8, "\nicoms_ser_write: ep 0x%x, bytes %d, ttop %d, quant %d\n", p->rd_ep, len, ttop, p->rd_qa); etime = stime = msec_time(); /* Until data is all written or we time out */ for (top = ttop; top > 0 && len > 0;) { if (poll_x(pa, nfd, top) > 0) { /* Wait for something */ if (pa[0].revents != 0) { if (pa[0].revents != POLLOUT) { a1loge(p->log, ICOM_SYS, "icoms_ser_write: poll returned " "unexpected value 0x%x",pa[0].revents); p->lserr = ICOM_SYS; return p->lserr; } /* We can write it without blocking */ wbytes = write(p->fd, wbuf, len); if (wbytes < 0) { a1logd(p->log, 8, "icoms_ser_write: write failed with %d\n",wbytes); retrv |= ICOM_SERW; break; } else if (wbytes > 0) { a1logd(p->log, 8, "icoms_ser_write: wrote %d bytes\n",wbytes); len -= wbytes; wbuf += wbytes; } } } etime = msec_time(); top = ttop - (etime - stime); /* Remaining time */ } if (top <= 0) { /* Must have timed out */ a1logd(p->log, 8, "icoms_ser_write: timeout, took %d msec out of %d\n",etime - stime,ttop); retrv |= ICOM_TO; } a1logd(p->log, 8, "icoms_ser_write: took %d msec, returning ICOM err 0x%x\n",etime - stime,retrv); p->lserr = retrv; return p->lserr; }