diff options
Diffstat (limited to 'spectro/icoms.c')
-rw-r--r-- | spectro/icoms.c | 481 |
1 files changed, 396 insertions, 85 deletions
diff --git a/spectro/icoms.c b/spectro/icoms.c index b69b72a..eadecc9 100644 --- a/spectro/icoms.c +++ b/spectro/icoms.c @@ -1,5 +1,5 @@ - /* General instrument + serial I/O support */ +/* General instrument + serial I/O support */ /* * Argyll Color Correction System @@ -71,29 +71,35 @@ static void icompath_del(icompath *p) { free(p); } -/* Delete the last path */ +/* Delete the last combined path */ +/* (Assume this is before icompaths_make_dslists() has been called) */ static void icompaths_del_last_path( icompaths *p ) { - if (p->npaths == 0) + icom_dtix ix = dtix_combined; + + if (p->ndpaths[ix] == 0) return; - icompath_del(p->paths[p->npaths-1]); - p->paths[p->npaths-1] = NULL; - p->npaths--; + icompath_del(p->dpaths[ix][p->ndpaths[ix]-1]); + p->dpaths[ix][p->ndpaths[ix]-1] = NULL; + p->ndpaths[ix]--; } -/* Return the last path */ +/* Return the last combined path */ +/* (Assume this is before icompaths_make_dslists() has been called) */ static icompath *icompaths_get_last_path( icompaths *p ) { - if (p->npaths == 0) + icom_dtix ix = dtix_combined; + + if (p->ndpaths[ix] == 0) return NULL; - return p->paths[p->npaths-1]; + return p->dpaths[ix][p->ndpaths[ix]-1]; } -/* Return the path corresponding to the port number, or NULL if out of range */ +/* Return the instrument path corresponding to the port number, or NULL if out of range */ static icompath *icompaths_get_path( icompaths *p, int port /* Enumerated port number, 1..n */ @@ -103,80 +109,188 @@ static icompath *icompaths_get_path( - if (port <= 0 || port > p->npaths) + if (port <= 0 || port > p->ndpaths[dtix_inst]) + return NULL; + + return p->dpaths[dtix_inst][port-1]; +} + +/* Return the device path corresponding to the port number, or NULL if out of range */ +static icompath *icompaths_get_path_sel( + icompaths *p, + icom_type dctype, /* Device type list */ + int port /* Enumerated port number, 1..n */ +) { + /* Check it is an enumeration */ + if (dctype != dtix_combined + && dctype != dtix_inst + && dctype != dtix_3dlut + && dctype != dtix_vtpg + && dctype != dtix_printer) + return NULL; + + if (dctype == dtix_inst) + return icompaths_get_path(p, port); + + if (port <= 0 || port > p->ndpaths[dctype]) return NULL; - return p->paths[port-1]; + return p->dpaths[dctype][port-1]; } -static void icompaths_clear(icompaths *p) { +/* Clear a single device paths list */ +static void icompaths_clear(icompaths *p, icom_dtix ix) { - /* Free any old list */ - if (p != NULL && p->paths != NULL) { + if (p->dpaths[ix] != NULL) { int i; - for (i = 0; i < p->npaths; i++) { - icompath_del(p->paths[i]); + /* If underlying owner of icompaths */ + if (ix == dtix_combined) { + for (i = 0; i < p->ndpaths[ix]; i++) { + icompath_del(p->dpaths[ix][i]); + } + } + free(p->dpaths[ix]); + p->dpaths[ix] = NULL; + p->ndpaths[ix] = 0; + + /* Clear instrument alias */ + if (ix == dtix_inst) { + p->npaths = 0; + p->paths = NULL; } - free(p->paths); - p->npaths = 0; - p->paths = NULL; } } -/* Add an empty new path. */ +/* Clear all device paths */ +static void icompaths_clear_all(icompaths *p) { + + if (p == NULL) + return; + + /* Free any old instrument list */ + icompaths_clear(p, dtix_inst); + icompaths_clear(p, dtix_3dlut); + icompaths_clear(p, dtix_vtpg); + icompaths_clear(p, dtix_printer); + icompaths_clear(p, dtix_combined); +} + +/* Add the give path to the given list. */ +/* If the path is NULL, allocat an empty */ +/* one and add it to the combined list */ /* Return icom error */ -static int icompaths_add_path(icompaths *p) { - if (p->paths == NULL) { - if ((p->paths = (icompath **)calloc(sizeof(icompath *), 1 + 1)) == NULL) { +static int icompaths_add_path(icompaths *p, int ix, icompath *xp) { + if (xp == NULL) + ix = dtix_combined; + if (p->dpaths[ix] == NULL) { + if ((p->dpaths[ix] = (icompath **)calloc(sizeof(icompath *), 1 + 1)) == NULL) { a1loge(p->log, ICOM_SYS, "icompaths: calloc failed!\n"); return ICOM_SYS; } } else { icompath **npaths; - if ((npaths = (icompath **)realloc(p->paths, - sizeof(icompath *) * (p->npaths + 2))) == NULL) { + if ((npaths = (icompath **)realloc(p->dpaths[ix], + sizeof(icompath *) * (p->ndpaths[ix] + 2))) == NULL) { a1loge(p->log, ICOM_SYS, "icompaths: realloc failed!\n"); return ICOM_SYS; } - p->paths = npaths; - p->paths[p->npaths+1] = NULL; + p->dpaths[ix] = npaths; + p->dpaths[ix][p->ndpaths[ix]+1] = NULL; } - if ((p->paths[p->npaths] = calloc(sizeof(icompath), 1)) == NULL) { - a1loge(p->log, ICOM_SYS, "icompaths: malloc failed!\n"); - return ICOM_SYS; + if (xp == NULL) { + if ((xp = calloc(sizeof(icompath), 1)) == NULL) { + a1loge(p->log, ICOM_SYS, "icompaths: malloc failed!\n"); + return ICOM_SYS; + } + } + p->dpaths[ix][p->ndpaths[ix]] = xp; + p->ndpaths[ix]++; + p->dpaths[ix][p->ndpaths[ix]] = NULL; + return ICOM_OK; +} + +/* Based on each icompath's dctype, create aliase lists for everything */ +/* on the combined path based on each device type. */ +/* (We are only called after clearing all lists) */ +int icompaths_make_dslists(icompaths *p) { + int rv, i; + + for (i = 0; i < p->ndpaths[dtix_combined]; i++) { + icompath *xp = p->dpaths[dtix_combined][i]; + + if (xp == NULL) + break; + + a1logd(g_log, 8, "icompaths_make_dslists '%s' dctype 0x%x\n",xp->name,xp->dctype); + + if (xp->dctype & icomt_instrument) { + if ((rv = icompaths_add_path(p, dtix_inst, xp)) != ICOM_OK) + return rv; + } + if (xp->dctype & icomt_3dlut) { + if ((rv = icompaths_add_path(p, dtix_3dlut, xp)) != ICOM_OK) + return rv; + } + if (xp->dctype & icomt_vtpg) { + if ((rv = icompaths_add_path(p, dtix_vtpg, xp)) != ICOM_OK) + return rv; + } + if (xp->dctype & icomt_printer) { + if ((rv = icompaths_add_path(p, dtix_printer, xp)) != ICOM_OK) + return rv; + } } - p->npaths++; - p->paths[p->npaths] = NULL; + + /* Maintain backwards compatible instrument list alias */ + p->npaths = p->ndpaths[dtix_inst]; + p->paths = p->dpaths[dtix_inst]; + return ICOM_OK; } #if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) -/* Add a serial path */ +/* Add a serial path. */ /* return icom error */ -static int icompaths_add_serial(icompaths *p, char *name, char *spath, icom_ser_attr sattr) { +static int icompaths_add_serial(icompaths *p, char *name, char *spath, icom_type dctype) { + icom_dtix ix = dtix_combined; + icompath *xp; int rv; - if ((rv = icompaths_add_path(p)) != ICOM_OK) + if ((rv = icompaths_add_path(p, ix, NULL)) != ICOM_OK) return rv; - - if ((p->paths[p->npaths-1]->name = strdup(name)) == NULL) { + + xp = p->dpaths[ix][p->ndpaths[ix]-1]; + + a1logd(g_log, 8, "icompaths_add_serial got '%s' dctype 0x%x\n",name,dctype); + + /* Type of port, port attributes, device category */ + xp->dctype |= icomt_cat_any; /* Assume any for now */ + xp->dctype |= icomt_serial; + xp->dctype |= icomt_seriallike; + xp->dctype |= dctype; + + if ((xp->name = strdup(name)) == NULL) { a1loge(p->log, ICOM_SYS, "icompaths: strdup failed!\n"); return ICOM_SYS; } - if ((p->paths[p->npaths-1]->spath = strdup(spath)) == NULL) { + if ((xp->spath = strdup(spath)) == NULL) { a1loge(p->log, ICOM_SYS, "icompaths: strdup failed!\n"); return ICOM_SYS; } - p->paths[p->npaths-1]->sattr = sattr; + + a1logd(g_log, 8, "icompaths_add_serial returning '%s' dctype 0x%x\n",xp->name,xp->dctype); return ICOM_OK; } -/* Modify a serial path to add the instrument type */ -int icompaths_set_serial_itype(icompath *p, instType itype) { +/* Modify a serial path to add the device type */ +int icompaths_set_serial_itype(icompath *p, devType itype) { char pname[400], *cp; + /* Convert device type to category */ + p->dctype = (p->dctype & ~icomt_cat_mask) | inst_category(itype); + p->itype = itype; /* Strip any existing description in brackets */ @@ -190,6 +304,9 @@ int icompaths_set_serial_itype(icompath *p, instType itype) { return ICOM_SYS; } free(cp); + + a1logd(g_log, 8, "icompaths_set_serial_itype '%s' returning dctype 0x%x\n",p->name,p->dctype); + return ICOM_OK; } @@ -197,60 +314,81 @@ int icompaths_set_serial_itype(icompath *p, instType itype) { #ifdef ENABLE_USB -/* Set an icompath details */ +/* Set an icompath details. */ /* return icom error */ static int icompath_set_usb(a1log *log, icompath *p, char *name, unsigned int vid, unsigned int pid, - int nep, struct usb_idevice *usbd, instType itype) { + int nep, struct usb_idevice *usbd, devType itype) { int rv; + if ((p->name = strdup(name)) == NULL) { a1loge(log, ICOM_SYS, "icompath: strdup failed!\n"); return ICOM_SYS; } + a1logd(g_log, 8, "icompath_set_usb '%s' got dctype 0x%x\n",p->name,p->dctype); + + p->dctype |= icomt_usb; + p->dctype = (p->dctype & ~icomt_cat_mask) | inst_category(itype); + p->nep = nep; p->vid = vid; p->pid = pid; p->usbd = usbd; p->itype = itype; + a1logd(g_log, 8, "icompath_set_usb '%s' returning dctype 0x%x\n",p->name,p->dctype); + return ICOM_OK; } /* Add a usb path. usbd is taken, others are copied. */ /* return icom error */ static int icompaths_add_usb(icompaths *p, char *name, unsigned int vid, unsigned int pid, - int nep, struct usb_idevice *usbd, instType itype) { + int nep, struct usb_idevice *usbd, devType itype) { + icom_dtix ix = dtix_combined; + icompath *xp; int rv; - if ((rv = icompaths_add_path(p)) != ICOM_OK) + if ((rv = icompaths_add_path(p, 0, NULL)) != ICOM_OK) return rv; - return icompath_set_usb(p->log, p->paths[p->npaths-1], name, vid, pid, nep, usbd, itype); + xp = p->dpaths[ix][p->ndpaths[ix]-1]; - return ICOM_OK; + return icompath_set_usb(p->log, xp, name, vid, pid, nep, usbd, itype); } /* Add an hid path. hidd is taken, others are copied. */ /* return icom error */ static int icompaths_add_hid(icompaths *p, char *name, unsigned int vid, unsigned int pid, - int nep, struct hid_idevice *hidd, instType itype) { + int nep, struct hid_idevice *hidd, devType itype) { + icom_dtix ix = dtix_combined; + icompath *xp; int rv; - if ((rv = icompaths_add_path(p)) != ICOM_OK) + if ((rv = icompaths_add_path(p, 0, NULL)) != ICOM_OK) return rv; - if ((p->paths[p->npaths-1]->name = strdup(name)) == NULL) { + xp = p->dpaths[ix][p->ndpaths[ix]-1]; + + a1logd(g_log, 8, "icompaths_add_hid '%s' got dctype 0x%x\n",xp->name,xp->dctype); + + xp->dctype |= icomt_hid; + xp->dctype = (xp->dctype & ~icomt_cat_mask) | inst_category(itype); + + if ((xp->name = strdup(name)) == NULL) { a1loge(p->log, ICOM_SYS, "icompaths: strdup failed!\n"); return ICOM_SYS; } - p->paths[p->npaths-1]->nep = nep; - p->paths[p->npaths-1]->vid = vid; - p->paths[p->npaths-1]->pid = pid; - p->paths[p->npaths-1]->hidd = hidd; - p->paths[p->npaths-1]->itype = itype; + xp->nep = nep; + xp->vid = vid; + xp->pid = pid; + xp->hidd = hidd; + xp->itype = itype; + + a1logd(g_log, 8, "icompath_set_usb '%s' returning dctype 0x%x\n",xp->name,xp->dctype); return ICOM_OK; } @@ -258,18 +396,115 @@ static int icompaths_add_hid(icompaths *p, char *name, unsigned int vid, unsigne static void icompaths_del(icompaths *p) { if (p != NULL) { - icompaths_clear(p); + icompaths_clear_all(p); p->log = del_a1log(p->log); /* Unreference it and set to NULL */ free(p); } } -int icompaths_refresh_paths(icompaths *p); /* Defined in platform specific */ +/* Create and return a list of available serial ports or USB devices for this system. */ +/* We look at the registry key "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM" */ +/* to determine serial ports, and use libusb to discover USB devices. */ +/* return icom error */ +int icompaths_refresh_paths_sel(icompaths *p, icom_type mask) { + int rv, usbend = 0; + int i, j; + + a1logd(p->log, 7, "icoms_refresh_paths: called with mask = %d\n",mask); + + /* Clear any existing device paths */ + p->clear(p); + +#ifdef ENABLE_USB + if (mask & icomt_hid) { + a1logd(p->log, 6, "icoms_refresh_paths: looking for HID device\n"); + if ((rv = hid_get_paths(p)) != ICOM_OK) + return rv; + } + if (mask & icomt_usb) { + a1logd(p->log, 6, "icoms_refresh_paths: looking for USB device\n"); + if ((rv = usb_get_paths(p)) != ICOM_OK) + return rv; + } + usbend = p->ndpaths[dtix_combined]; + a1logd(p->log, 6, "icoms_refresh_paths: now got %d paths\n",usbend); +#endif /* ENABLE_USB */ + +#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) + + if (mask & (icomt_serial | icomt_fastserial | icomt_btserial)) { + a1logd(p->log, 6, "icoms_refresh_paths: looking for serial ports\n"); + if ((rv = serial_get_paths(p, mask)) != ICOM_OK) + return rv; + + } +#endif /* ENABLE_SERIAL || ENABLE_FAST_SERIAL */ + + /* Sort the COM keys so people don't get confused... */ + /* Sort identified instruments ahead of unknown serial ports */ + a1logd(p->log, 6, "icoms_refresh_paths: we now have %d devices and are about to sort them\n",p->ndpaths[dtix_combined]); + + { + icompath **pl = p->dpaths[dtix_combined]; + int np = p->ndpaths[dtix_combined]; + + for (i = usbend; i < (np-1); i++) { + for (j = i+1; j < np; j++) { + if ((pl[i]->itype == instUnknown && pl[j]->itype != instUnknown) + || (((pl[i]->itype == instUnknown && pl[j]->itype == instUnknown) + || (pl[i]->itype != instUnknown && pl[j]->itype != instUnknown)) + && strcmp(pl[i]->name, pl[j]->name) > 0)) { + icompath *tt = pl[i]; + pl[i] = pl[j]; + pl[j] = tt; + } + } + } + } + + /* Create the device specific lists */ + if ((rv = icompaths_make_dslists(p)) != ICOM_OK) { + a1logd(p->log, 1, "icoms_refresh_paths: icompaths_make_dslists failed with %d\n",rv); + return rv; + } + + a1logd(p->log, 8, "icoms_refresh_paths: returning %d paths and ICOM_OK\n",p->ndpaths[dtix_combined]); + + return ICOM_OK; +} + +/* (In implementation specific) */ +int serial_is_open(icoms *p); +void serial_close_port(icoms *p); + +/* Close the port */ +static void icoms_close_port(icoms *p) { + if (p->is_open) { +#ifdef ENABLE_USB + if (p->usbd) { + usb_close_port(p); + } else if (p->hidd) { + hid_close_port(p); + } +#endif +#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) + if (serial_is_open(p)) { + serial_close_port(p); + } +#endif /* ENABLE_SERIAL */ + p->is_open = 0; + } +} + +int icompaths_refresh_paths(icompaths *p) { + return icompaths_refresh_paths_sel(p, icomt_instrument | icomt_portattr_all); +} /* Allocate an icom paths and set it to the list of available devices */ +/* that match the icom_type mask. */ /* Return NULL on error */ -icompaths *new_icompaths(a1log *log) { +icompaths *new_icompaths_sel(a1log *log, icom_type mask) { icompaths *p; if ((p = (icompaths *)calloc(sizeof(icompaths), 1)) == NULL) { a1loge(log, ICOM_SYS, "new_icompath: calloc failed!\n"); @@ -278,11 +513,14 @@ icompaths *new_icompaths(a1log *log) { p->log = new_a1log_d(log); - p->clear = icompaths_clear; + p->clear = icompaths_clear_all; p->refresh = icompaths_refresh_paths; - p->del_last_path = icompaths_del_last_path; - p->get_last_path = icompaths_get_last_path; + p->refresh_sel = icompaths_refresh_paths_sel; p->get_path = icompaths_get_path; + p->get_path_sel = icompaths_get_path_sel; + p->del = icompaths_del; + + /* ====== internal implementation ======= */ #if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) p->add_serial = icompaths_add_serial; #endif /* ENABLE_SERIAL */ @@ -290,9 +528,11 @@ icompaths *new_icompaths(a1log *log) { p->add_usb = icompaths_add_usb; p->add_hid = icompaths_add_hid; #endif /* ENABLE_USB */ - p->del = icompaths_del; + p->del_last_path = icompaths_del_last_path; + p->get_last_path = icompaths_get_last_path; + /* ====================================== */ - if (icompaths_refresh_paths(p)) { + if (icompaths_refresh_paths_sel(p, mask)) { a1loge(log, ICOM_SYS, "new_icompaths: icompaths_refresh_paths failed!\n"); free(p); return NULL; @@ -301,6 +541,12 @@ icompaths *new_icompaths(a1log *log) { return p; } +/* Allocate an icom paths and set it to the list of available instruments */ +/* Return NULL on error */ +icompaths *new_icompaths(a1log *log) { + return new_icompaths_sel(log, icomt_instrument | icomt_portattr_all); +} + /* ----------------------------------------------------- */ @@ -321,7 +567,6 @@ static int icom_copy_path_to_icom(icoms *p, icompath *pp) { a1loge(p->log, ICOM_SYS, "copy_path_to_icom: malloc spath failed\n"); return ICOM_SYS; } - p->sattr = pp->sattr; } else { p->spath = NULL; } @@ -335,24 +580,36 @@ static int icom_copy_path_to_icom(icoms *p, icompath *pp) { if ((rv = hid_copy_hid_idevice(p, pp)) != ICOM_OK) return rv; #endif + p->dctype = pp->dctype; p->itype = pp->itype; + a1logd(g_log, 8, "icom_copy_path_to_icom '%s' returning dctype 0x%x\n",p->name,p->dctype); + return ICOM_OK; } -/* Return the port type */ -static icom_type icoms_port_type( +/* Return the device category */ +/* (Returns bit flags) */ +static icom_type icoms_cat_type( icoms *p ) { + return p->dctype & icomt_cat_mask; +} -#ifdef ENABLE_USB - if (p->hidd != NULL) - return icomt_hid; - if (p->usbd != NULL) - return icomt_usb; -#endif +/* Return the communication port type */ +/* (Can use equality tests on return value) */ +static icom_type icoms_port_type( +icoms *p +) { + return p->dctype & icomt_port_mask; +} - return icomt_serial; +/* Return the communication port attributes */ +/* (Returns bit flags) */ +static icom_type icoms_port_attr( +icoms *p +) { + return p->dctype & icomt_attr_mask; } /* ----------------------------------------------------- */ @@ -365,10 +622,10 @@ icoms *p # include "icoms_ux.c" #endif -/* write and read convenience function */ +/* write and read convenience function with read flush */ /* return icom error */ static int -icoms_write_read( +icoms_write_read_ex( icoms *p, char *wbuf, /* Write puffer */ int nwch, /* if > 0, number of characters to write, else nul terminated */ @@ -377,27 +634,33 @@ int bsize, /* Buffer size */ int *bread, /* Bytes read (not including forced '\000') */ char *tc, /* Terminating characers, NULL for none or char count mode */ int ntc, /* Number of terminating characters needed, or char count needed */ -double tout /* Timeout for write and then read (i.e. max = 2 x tout) */ +double tout, /* Timeout for write and then read (i.e. max = 2 x tout) */ +int frbw /* nz to Flush Read Before Write */ ) { int rv = ICOM_OK; a1logd(p->log, 8, "icoms_write_read: called\n"); if (p->write == NULL || p->read == NULL) { /* Neither serial nor USB ? */ - a1loge(p->log, ICOM_NOTS, "icoms_write_read: Neither serial nor USB device!\n"); + a1loge(p->log, ICOM_NOTS, "icoms_write_read: No write and read functions set!\n"); return ICOM_NOTS; } #if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) - /* Flush any stray chars if serial ?? */ - if (0 && p->usbd == NULL && p->hidd == NULL) { - char tbuf[100]; + /* Flush any stray chars if serial */ + if (frbw && (p->dctype & icomt_serial)) { + char tbuf[500]; int debug = p->log->debug; + int bread; if (debug < 8) p->log->debug = 0; - for (; rv == ICOM_OK;) /* Until we get a timeout */ - rv = p->read(p, tbuf, 100, NULL, NULL, 100, 0.01); + for (;;) { + bread = 0; + p->read(p, tbuf, 500, &bread, NULL, 500, 0.02); + if (bread == 0) + break; + } p->log->debug = debug; rv = ICOM_OK; } @@ -420,6 +683,23 @@ double tout /* Timeout for write and then read (i.e. max = 2 x tout) */ return rv; } +/* write and read convenience function */ +/* return icom error */ +static int +icoms_write_read( +icoms *p, +char *wbuf, /* Write puffer */ +int nwch, /* if > 0, number of characters to write, else nul terminated */ +char *rbuf, /* Read buffer */ +int bsize, /* Buffer size */ +int *bread, /* Bytes read (not including forced '\000') */ +char *tc, /* Terminating characers, NULL for none or char count mode */ +int ntc, /* Number of terminating characters needed, or char count needed */ +double tout /* Timeout for write and then read (i.e. max = 2 x tout) */ +) { + return icoms_write_read_ex(p, wbuf, nwch, rbuf, bsize, bread, tc, ntc, tout, 0); +} + /* Optional callback to client from device */ /* Default implementation is a NOOP */ static int icoms_interrupt(icoms *p, @@ -428,6 +708,29 @@ static int icoms_interrupt(icoms *p, return ICOM_OK; } +/* Destroy ourselves */ +static void +icoms_del(icoms *p) { + a1logd(p->log, 8, "icoms_del: called\n"); + if (p->is_open) { + a1logd(p->log, 8, "icoms_del: closing port\n"); + p->close_port(p); + } +#ifdef ENABLE_USB + usb_del_usb(p); + hid_del_hid(p); +#endif +#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) + if (p->spath != NULL) + free(p->spath); +#endif + p->log = del_a1log(p->log); + if (p->name != NULL) + free(p->name); + p->log = del_a1log(p->log); /* unref */ + free (p); +} + /* icoms Constructor */ /* Return NULL on error */ icoms *new_icoms( @@ -435,6 +738,9 @@ icoms *new_icoms( a1log *log /* log to take reference from, NULL for default */ ) { icoms *p; + + a1logd(log, 2, "new_icoms '%s' itype '%s' dctype 0x%x\n",ipath->name,inst_sname(ipath->itype),ipath->dctype); + if ((p = (icoms *)calloc(sizeof(icoms), 1)) == NULL) { a1loge(log, ICOM_SYS, "new_icoms: calloc failed!\n"); return NULL; @@ -475,14 +781,19 @@ icoms *new_icoms( p->close_port = icoms_close_port; + p->dev_cat = icoms_cat_type; p->port_type = icoms_port_type; + p->port_attr = icoms_port_attr; + #if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) + p->set_ser_port_ex = icoms_set_ser_port_ex; p->set_ser_port = icoms_set_ser_port; #endif /* ENABLE_SERIAL */ p->write = NULL; /* Serial open or set_methods will set */ p->read = NULL; p->write_read = icoms_write_read; + p->write_read_ex = icoms_write_read_ex; p->interrupt = icoms_interrupt; p->del = icoms_del; @@ -512,9 +823,9 @@ void good_beep() { /* Emit a "bad" double beep */ void bad_beep() { - /* 0msec delay, 800Hz for 200 msec */ + /* 0 msec delay, 800Hz for 200 msec */ msec_beep(0, 800, 200); - /* 500msec delay, 800Hz for 200 msec */ + /* 350 msec delay, 800Hz for 200 msec */ msec_beep(350, 800, 200); } |