int ServerCore::AddTimer(const wchar_t * callback, int timeout, int param) { int i; for(i = 0; i < MAX_TIMERS; i++) { if(scripttimers[i].timeout <= 0) break; } wcscpy(scripttimers[i].callback, callback); scripttimers[i].param = param; scripttimers[i].timeout = timeout; scripttimers[i].time = msec_time() + timeout; return i; }
void ServerCore::Tick(void) { conscreen.CheckUserInput(); nm.Tick(); gametime.tickcount++; curtime = time(0); if (gametime.tickcount == gametime.ticksperminute) { gametime.tickcount = 0; this->IncrementGameTime(); this->UpdateCaption(); } if(curtime - lastcheck >= 30000) { lastcheck = curtime; nm.CheckClients(); } if (!lan) { if (curtime - lastmasterservercheck >= 3600000) { lastmasterservercheck = curtime; if (!msm.RegisterServer(port, hostname, gamemodename, L"World", maxplayers, password)) { Log::Warning(L"Unable to register server."); } } } long curmtime = msec_time(); for(int i = 0; i < MAX_TIMERS; i++) { if(scripttimers[i].timeout > 0) { if(curmtime >= scripttimers[i].time) { if(!vmm.CallSomeCallback(scripttimers[i].callback, scripttimers[i].param)) { KillTimer(i); } else scripttimers[i].time = curmtime + scripttimers[i].timeout; } } } Sleep(sleepcount); }
/* Return DTP41_COMS_FAIL on failure to establish communications */ static inst_code dtp41_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { dtp41 *p = (dtp41 *)pp; static char buf[MAX_MES_SIZE]; baud_rate brt[9] = { baud_9600, baud_19200, baud_38400, baud_57600, baud_4800, baud_2400, baud_1200, baud_600, baud_300 }; char *brc[9] = { "9600BR\r", "19200BR\r", "38400BR\r", "57600BR\r", "4800BR\r", "2400BR\r", "1200BR\r", "600BR\r", "300BR\r" }; char *fcc; unsigned int etime; int ci, bi, i, se; inst_code ev = inst_ok; a1logd(p->log, 2, "dtp41_init_coms: About to init Serial I/O\n"); /* Deal with flow control setting */ if (fc == fc_nc) fc = DEFFC; if (fc == fc_XonXOff) { fcc = "0304CF\r"; } else if (fc == fc_Hardware) { fcc = "0104CF\r"; } else { fc = fc_none; fcc = "0004CF\r"; } /* Figure DTP41 baud rate being asked for */ for (bi = 0; bi < 9; bi++) { if (brt[bi] == br) break; } if (bi >= 9) bi = 0; /* Figure current icoms baud rate */ for (ci = 0; ci < 9; ci++) { if (brt[ci] == p->icom->br) break; } if (ci >= 9) ci = bi; /* The tick to give up on */ etime = msec_time() + (long)(1000.0 * tout + 0.5); while (msec_time() < etime) { /* Until we time out, find the correct baud rate */ for (i = ci; msec_time() < etime;) { if ((se = p->icom->set_ser_port(p->icom, fc_none, brt[i], parity_none, stop_1, length_8)) != ICOM_OK) { a1logd(p->log, 1, "dtp41_init_coms: set_ser_port failed ICOM err 0x%x\n",se); return dtp41_interp_code((inst *)p, icoms2dtp41_err(se)); } if (((ev = dtp41_command(p, "\r", buf, MAX_MES_SIZE, 0.5)) & inst_mask) != inst_coms_fail) break; /* We've got coms */ /* Check for user abort */ if (p->uicallback != NULL) { inst_code ev; if ((ev = p->uicallback(p->uic_cntx, inst_negcoms)) == inst_user_abort) { a1logd(p->log, 1, "dtp41_init_coms: user aborted\n"); return inst_user_abort; } } if (++i >= 9) i = 0; } break; /* Got coms */ } if (msec_time() >= etime) { /* We haven't established comms */ return inst_coms_fail; } /* set the protocol to RCI */ if ((ev = dtp41_command(p, "0012CF\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok) return ev; /* Set the handshaking (cope with coms breakdown) */ if ((se = p->icom->write_read(p->icom, fcc, 0, buf, MAX_MES_SIZE, NULL, ">", 1, 1.5)) != 0) { if (extract_ec(buf) != DTP41_OK) return inst_coms_fail; } /* Change the baud rate to the rate we've been told (cope with coms breakdown) */ if ((se = p->icom->write_read(p->icom, brc[bi], 0, buf, MAX_MES_SIZE, NULL, ">", 1, 1.5)) != 0) { if (extract_ec(buf) != DTP41_OK) return inst_coms_fail; } /* Configure our baud rate and handshaking as well */ if ((se = p->icom->set_ser_port(p->icom, fc, brt[bi], parity_none, stop_1, length_8)) != ICOM_OK) { a1logd(p->log, 1, "dtp41_init_coms: set_ser_port failed ICOM err 0x%x\n",se); return dtp41_interp_code((inst *)p, icoms2dtp41_err(se)); } /* Loose a character (not sure why) */ p->icom->write_read(p->icom, "\r", 0, buf, MAX_MES_SIZE, NULL, ">", 1, 0.5); /* Check instrument is responding */ if ((ev = dtp41_command(p, "\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok) { a1logd(p->log, 1, "dtp41_init_coms: instrument failed to respond\n"); return inst_coms_fail; } a1logd(p->log, 2, "dtp41_init_coms: init coms has suceeded\n"); p->gotcoms = 1; return inst_ok; }
/* a serial connection, and instUnknown not serial. */ static instType ser_inst_type( icoms *p, int port /* Enumerated port number, 1..n */ ) { instType rv = instUnknown; char buf[100]; baud_rate brt[] = { baud_9600, baud_19200, baud_4800, baud_2400, baud_1200, baud_38400, baud_57600, baud_115200, baud_600, baud_300, baud_110, baud_nc }; long etime; int bi, i; int se, len; int xrite = 0; int ss = 0; int so = 0; if (p->paths == NULL) p->get_paths(p); if (port <= 0 || port > p->npaths) return instUnknown; #ifdef ENABLE_USB if (p->paths[port-1]->dev != NULL || p->paths[port-1]->hev != NULL) return instUnknown; #endif /* ENABLE_USB */ if (p->debug) fprintf(stderr,"instType: About to init Serial I/O\n"); bi = 0; /* The tick to give up on */ etime = msec_time() + (long)(1000.0 * 20.0 + 0.5); if (p->debug) fprintf(stderr,"instType: Trying different baud rates (%lu msec to go)\n",etime - msec_time()); /* Until we time out, find the correct baud rate */ for (i = bi; msec_time() < etime; i++) { if (brt[i] == baud_nc) i = 0; p->set_ser_port(p, port, fc_none, brt[i], parity_none, stop_1, length_8); //printf("~1 brt = %d\n",brt[i]); if ((se = p->write_read(p, ";D024\r\n", buf, 100, '\r', 1, 0.5)) != 0) { if ((se & ICOM_USERM) == ICOM_USER) { if (p->debug) fprintf(stderr,"instType: User aborted\n"); return instUnknown; } } len = strlen(buf); //printf("~1 len = %d\n",len); if (len < 4) continue; /* Is this an X-Rite error value such as "<01>" ? */ if (buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>') { //printf("~1 xrite\n"); xrite = 1; break; } /* Is this a Spectrolino error resonse ? */ if (len >= 5 && strncmp(buf, ":26", 3) == 0) { //printf("~1 spectrolino\n"); so = 1; break; } /* Is this a SpectroScan response ? */ if (len >= 7 && strncmp(buf, ":D183", 5) == 0) { //printf("~1 spectroscan\n"); ss = 1; break; } } if (msec_time() >= etime) { /* We haven't established comms */ if (p->debug) fprintf(stderr,"instType: Failed to establish coms\n"); return instUnknown; } if (p->debug) fprintf(stderr,"instType: Got coms with instrument\n"); /* Spectrolino */ if (so) { rv = instSpectrolino; } /* SpectroScan */ if (ss) { rv = instSpectroScan; if ((se = p->write_read(p, ";D030\r\n", buf, 100, '\n', 1, 1.5)) == 0) { if (strlen(buf) >= 41) { hex2bin(&buf[5], 12); //printf("~1 type = '%s'\n",buf); if (strncmp(buf, ":D190SpectroScanT", 17) == 0) rv = instSpectroScanT; } } } if (xrite) { /* Get the X-Rite model and version number */ if ((se = p->write_read(p, "SV\r\n", buf, 100, '>', 1, 2.5)) != 0) return instUnknown; if (strlen(buf) >= 12) { if (strncmp(buf,"X-Rite DTP22",12) == 0) rv = instDTP22; if (strncmp(buf,"X-Rite DTP41",12) == 0) rv = instDTP41; if (strncmp(buf,"X-Rite DTP42",12) == 0) rv = instDTP41; if (strncmp(buf,"X-Rite DTP51",12) == 0) rv = instDTP51; if (strncmp(buf,"X-Rite DTP52",12) == 0) rv = instDTP51; if (strncmp(buf,"X-Rite DTP92",12) == 0) rv = instDTP92; if (strncmp(buf,"X-Rite DTP94",12) == 0) rv = instDTP94; } } if (p->debug) fprintf(stderr,"instType: Instrument type is '%s'\n", inst_name(rv)); return rv; }
/* inst_license, inst_licensenc or inst_tamper on licening problem */ static int ccwin_set_color( dispwin *p, double r, double g, double b /* Color values 0.0 - 1.0 */ ) { chws *ws = (chws *)p->pcntx; int j; double orgb[3]; /* Previous RGB value */ double kr, kf; int update_delay = 0; debugr2((errout, "ccwin_set_color called with %f %f %f\n",r,g,b)); if (p->nowin) { debugr2((errout,"ccwin_set_color: nowin - give up\n")); return 1; } orgb[0] = p->rgb[0]; p->rgb[0] = r; orgb[1] = p->rgb[1]; p->rgb[1] = g; orgb[2] = p->rgb[2]; p->rgb[2] = b; for (j = 0; j < 3; j++) { if (p->rgb[j] < 0.0) p->rgb[j] = 0.0; else if (p->rgb[j] > 1.0) p->rgb[j] = 1.0; p->r_rgb[j] = p->s_rgb[j] = p->rgb[j]; if (p->out_tvenc) { p->r_rgb[j] = p->s_rgb[j] = ((235.0 - 16.0) * p->s_rgb[j] + 16.0)/255.0; /* For video encoding the extra bits of precision are created by bit shifting */ /* rather than scaling, so we need to scale the fp value to account for this. */ if (p->pdepth > 8) p->r_rgb[j] = (p->s_rgb[j] * 255 * (1 << (p->pdepth - 8))) /((1 << p->pdepth) - 1.0); } } /* This is probably not actually thread safe... */ p->ncix++; #if DDITHER != 1 # pragma message("############################# ccwin.c DDITHER != 1 ##") #endif /* Turn the color into a png file */ { /* We want a raster of IWIDTH x IHEIGHT pixels for web server, */ /* or p->w x p->h for PNG direct. */ render2d *rr; prim2d *rct; depth2d depth = bpc8_2d; #if DDITHER == 1 int dither = 0x8002; /* 0x8002 = error diffuse FG only */ #elif DDITHER == 2 int dither = 0x4000; /* 0x4000 = no dither but don't average pixels */ /* so as to allow pattern to come through. */ #else int dither = 0; /* Don't dither in renderer */ #endif double hres = 1.0; /* Resoltion in pix/mm */ double vres = 1.0; /* Resoltion in pix/mm */ double iw, ih; /* Size of page in mm (pixels) */ color2d c; unsigned char *ibuf; /* Memory image of .png file */ size_t ilen; int rv; #ifdef DO_TIMING int stime; #endif if (ws->direct) { iw = ws->w; /* Requested size */ ih = ws->h; } else { iw = IWIDTH; ih = IHEIGHT; /* Size of page in mm */ } /* Full screen background: */ if (p->fullscreen) { if (p->bge == dw_bg_grey) { ws->bg[0] = 0.2; ws->bg[1] = 0.2; ws->bg[2] = 0.2; } else if (p->bge == dw_bg_cvideo) { ws->bg[0] = p->area * (1.0 - r)/(1.0 - p->area); ws->bg[1] = p->area * (1.0 - g)/(1.0 - p->area); ws->bg[2] = p->area * (1.0 - b)/(1.0 - p->area); } else if (p->bge == dw_bg_clight) { double gamma = 2.3; ws->bg[0] = pow(p->area * (1.0 - pow(r, gamma))/(1.0 - p->area), 1.0/gamma); ws->bg[1] = pow(p->area * (1.0 - pow(g, gamma))/(1.0 - p->area), 1.0/gamma); ws->bg[2] = pow(p->area * (1.0 - pow(b, gamma))/(1.0 - p->area), 1.0/gamma); } else { /* Assume dw_bg_black */ ws->bg[0] = 0.0; ws->bg[1] = 0.0; ws->bg[2] = 0.0; } /* Use default dark gray background */ } else { ws->bg[0] = 0.2; ws->bg[1] = 0.2; ws->bg[2] = 0.2; } debugr2((errout, "ccwin_set_color iw %f ih %f\n",iw,ih)); if ((rr = new_render2d(iw, ih, NULL, hres, vres, rgb_2d, 0, depth, dither, #if DDITHER == 1 ccastQuant, NULL, 3.0/255.0 #else NULL, NULL, 0.0 #endif )) == NULL) { a1loge(g_log, 1,"ccwin: new_render2d() failed\n"); return 1; } /* Set the background color */ c[0] = ws->bg[0]; c[1] = ws->bg[1]; c[2] = ws->bg[2]; rr->set_defc(rr, c); c[0] = p->r_rgb[0]; c[1] = p->r_rgb[1]; c[2] = p->r_rgb[2]; if (ws->direct) rr->add(rr, rct = new_rect2d(rr, 0.0, 0.0, ws->w, ws->h, c)); else rr->add(rr, rct = new_rect2d(rr, ws->x, ws->y, ws->w, ws->h, c)); #if DDITHER == 2 /* Use dither pattern */ { double rgb[3]; double dpat[CCDITHSIZE][CCDITHSIZE][3]; double (*cpat)[MXPATSIZE][MXPATSIZE][TOTC2D]; int i, j; /* Get a chrome cast dither pattern to match target color */ for (i = 0; i < 3; i++) rgb[i] = p->r_rgb[i] * 255.0; get_ccast_dith(dpat, rgb); if ((cpat = malloc(sizeof(double) * MXPATSIZE * MXPATSIZE * TOTC2D)) == NULL) { a1loge(g_log, 1, "ccwin: malloc of dither pattern failed\n"); return 1; } for (i = 0; i < CCDITHSIZE; i++) { for (j = 0; j < CCDITHSIZE; j++) { int k = (((int)IHEIGHT-2) - j) % CCDITHSIZE; /* Flip to origin bot left */ (*cpat)[i][k][0] = dpat[i][j][0]/255.0; /* (HEIGHT-2 is correct!) */ (*cpat)[i][k][1] = dpat[i][j][1]/255.0; (*cpat)[i][k][2] = dpat[i][j][2]/255.0; } } set_rect2d_dpat((rect2d *)rct, cpat, CCDITHSIZE, CCDITHSIZE); } #endif /* DDITHER == 2 */ #ifdef CCTEST_PATTERN #pragma message("############################# ccwin.c TEST_PATTERN defined ! ##") if (getenv("ARGYLL_CCAST_TEST_PATTERN") != NULL) { verbose(0, "Writing test pattern to '%s'\n","testpattern.png"); if (r->write(r, "testpattern.png", 1, NULL, NULL, png_file)) { a1loge(g_log, 1, "ccwin: render->write failed\n"); return 1; } } #else /* !CCTEST_PATTERN */ # ifdef WRITE_PNG /* Write it to a file so that we can look at it */ # pragma message("############################# spectro/ccwin.c WRITE_PNG is enabled ######") if (r->write(rr, "ccwin.png", 1, NULL, NULL, png_file)) { a1loge(g_log, 1, "ccwin: render->write failed\n"); return 1; } # endif /* WRITE_PNG */ #endif /* !CCTEST_PATTERN */ #ifdef DO_TIMING stime = msec_time(); #endif rv = rr->write(rr, "MemoryBuf", 1, &ibuf, &ilen, png_mem); if (rv) { a1loge(g_log, 1, "ccwin: render->write failed\n"); return 1; } rr->del(rr); #ifdef DO_TIMING stime = msec_time() - stime; printf("render->write took %d msec\n",stime); #endif if (ws->update(ws, ibuf, ilen, ws->bg)) { a1loge(g_log, 1, "ccwin: color update failed\n"); return 1; } p->ccix = p->ncix; } /* If update is notified asyncronously ... */ while(p->ncix != p->ccix) { msec_sleep(50); } //printf("#################################################################\n"); //printf("################# RGB update notified ################\n"); //printf("#################################################################\n"); /* Allow for display update & instrument delays */ update_delay = dispwin_compute_delay(p, orgb); debugr2((errout, "ccwin_set_color delaying %d msec\n",update_delay)); msec_sleep(update_delay); return 0; }
/* Return DTP_COMS_FAIL on failure to establish communications */ static inst_code dtp51_init_coms(inst *pp, int port, baud_rate br, flow_control fc, double tout) { dtp51 *p = (dtp51 *)pp; static char buf[MAX_MES_SIZE]; baud_rate brt[5] = { baud_9600, baud_19200, baud_4800, baud_2400, baud_1200 }; char *brc[5] = { "30BR\r", "60BR\r", "18BR\r", "0CBR\r", "06BR\r" }; char *fcc; long etime; int ci, bi, i, rv; inst_code ev = inst_ok; if (p->debug) p->icom->debug = p->debug; /* Turn on debugging */ /* Deal with flow control setting */ if (fc == fc_nc) fc = DEFFC; if (fc == fc_XonXOff) { fcc = "0304CF\r"; } else if (fc == fc_Hardware) { fcc = "0104CF\r"; } else { fc = fc_none; fcc = "0004CF\r"; } /* Figure DTP51 baud rate being asked for */ for (bi = 0; bi < 5; bi++) { if (brt[bi] == br) break; } if (bi >= 5) bi = 0; /* Figure current icoms baud rate */ for (ci = 0; ci < 5; ci++) { if (brt[ci] == p->icom->br) break; } if (ci >= 5) ci = bi; /* The tick to give up on */ etime = msec_time() + (long)(1000.0 * tout + 0.5); while (msec_time() < etime) { /* Until we time out, find the correct baud rate */ for (i = ci; msec_time() < etime;) { p->icom->set_ser_port(p->icom, port, fc_none, brt[i], parity_none, stop_1, length_8); if (((ev = dtp51_command(p, "\r", buf, MAX_MES_SIZE, 0.5)) & inst_mask) != inst_coms_fail) break; /* We've got coms or user abort */ if (++i >= 5) i = 0; } if ((ev & inst_mask) == inst_user_abort) return ev; break; /* Got coms */ } if (msec_time() >= etime) { /* We haven't established comms */ return inst_coms_fail; } /* Set the handshaking */ if ((ev = dtp51_command(p, fcc, buf, MAX_MES_SIZE, 1.5)) != inst_ok) return ev; /* Change the baud rate to the rate we've been told */ if ((rv = p->icom->write_read(p->icom, brc[bi], buf, MAX_MES_SIZE, '>', 1, 1.5)) != 0) { if (extract_ec(buf) != DTP51_OK) return inst_coms_fail; } /* Configure our baud rate and handshaking as well */ p->icom->set_ser_port(p->icom, port, fc, brt[bi], parity_none, stop_1, length_8); /* Loose a character (not sure why) */ p->icom->write_read(p->icom, "\r", buf, MAX_MES_SIZE, '>', 1, 0.5); /* Check instrument is responding */ if ((ev = dtp51_command(p, "\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok) return inst_coms_fail; if (p->verb) { int i, j; if ((ev = dtp51_command(p, "GI\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok && (ev & inst_imask) != DTP51_BAD_COMMAND) return ev; if ((ev & inst_imask) == DTP51_BAD_COMMAND) { /* Some fimware doesn't support GI */ printf("Firware doesn't support GI command\n"); } else { for (j = i = 0; ;i++) { if (buf[i] == '<' || buf[i] == '\000') break; if (buf[i] == '\r') { buf[i] = '\000'; printf(" %s\n",&buf[j]); if (buf[i+1] == '\n') i++; j = i+1; } } } } #ifdef DEBUG printf("Got communications\n"); #endif p->gotcoms = 1; return inst_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; }