From 82e6b0217e63d5a77e7f673bc2a7c3712c84b7e6 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Wed, 3 Oct 2007 16:46:13 +0000 Subject: New xpp release: r4786: * New firmware protocol version: 2.9 . * fpga_load: initial clean-ups before interface split. * genzaptelconf: Don't leave an empty directory behind (4784) * Increase xpp poll_timeout to 1000ms - useful for CentOS 4 (r4781). * Fix initialization anoyance: if AB don't answer to polls, don't waitfor_xpds, and show no waiting XPDs (r4725). * Disable dtmf_detect by default once again (r4712). * Don't check twice for asterisk to stop. The second test was done while Asterisk was still stopping (r4708). * Support building the kernel with M= instead of with SUBDIRS= , as used in some newer build systems (r4677). git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3105 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/utils/Makefile | 2 +- xpp/utils/fpga_load.c | 404 +++++++++++++++++++++++++++++------------- xpp/utils/genzaptelconf | 31 ++-- xpp/utils/hexfile.c | 316 +++++++++++++++++++++++---------- xpp/utils/hexfile.h | 7 +- xpp/utils/zapconf | 22 ++- xpp/utils/zaptel_hardware | 3 +- xpp/utils/zconf/Zaptel/Xpp.pm | 6 + xpp/utils/zt_registration | 4 +- 9 files changed, 545 insertions(+), 250 deletions(-) (limited to 'xpp/utils') diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile index 9ae1124..7955b27 100644 --- a/xpp/utils/Makefile +++ b/xpp/utils/Makefile @@ -31,7 +31,7 @@ PERL_MODS := $(shell cd zconf; echo $(PERL_MODS_PAT)) XPD_FIRMWARE = $(wildcard ../firmwares/*.hex) XPD_INIT_DATA = $(XPD_FIRMWARE) init_fxo_modes XPD_INIT = $(wildcard ../init_card_?_*) ../calibrate_slics xpp_fxloader -XPD_INIT_PERL = ../init_card_6_28 ../init_card_7_28 ../init_card_9_28 +XPD_INIT_PERL = ../init_card_6_29 ../init_card_7_29 ../init_card_9_29 # Variables that should be defined above, but need sane defaults: # FIXME: Are those values really sane? diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c index cc9cf81..c7ce907 100644 --- a/xpp/utils/fpga_load.c +++ b/xpp/utils/fpga_load.c @@ -29,7 +29,7 @@ static const char rcsid[] = "$Id$"; static int verbose = LOG_WARNING; static char *progname; -#define MAX_HEX_LINES 2000 +#define MAX_HEX_LINES 10000 #define PACKET_SIZE 512 #define EEPROM_SIZE 16 #define SERIAL_SIZE 8 @@ -89,9 +89,13 @@ enum fpga_load_status { struct my_usb_device { struct usb_device *dev; usb_dev_handle *handle; + int my_interface_num; + int my_ep_out; + int my_ep_in; char iManufacturer[BUFSIZ]; char iProduct[BUFSIZ]; char iSerialNumber[BUFSIZ]; + char iInterface[BUFSIZ]; int is_usb2; struct myeeprom eeprom; }; @@ -188,32 +192,58 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h } /* My device parameters */ -#define MY_CONFIG 1 -#define MY_INTERFACE 0 -#define MY_ENDPOINTS 4 - #define MY_EP_OUT 0x04 #define MY_EP_IN 0x88 #define FPGA_EP_OUT 0x02 #define FPGA_EP_IN 0x86 -#define TIMEOUT 5000 +/* USB firmware types */ +#define USB_11xx 0 +#define USB_FIRMWARE_II 1 + +#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \ + [t] = { \ + .type_code = (t), \ + .num_interfaces = (ni), \ + .my_interface_num = (n), \ + .num_endpoints = (ne), \ + .my_ep_in = (in), \ + .my_ep_out = (out), \ + .name = #t, \ + .endpoints = { __VA_ARGS__ }, \ + } -static const int my_endpoints[MY_ENDPOINTS] = { - FPGA_EP_OUT, - MY_EP_OUT, - FPGA_EP_IN, - MY_EP_IN +static const struct astribank_type { + int type_code; + int num_interfaces; + int my_interface_num; + int num_endpoints; + int my_ep_out; + int my_ep_in; + char *name; + int endpoints[4]; /* for matching */ +} astribank_types[] = { + TYPE_ENTRY(USB_11xx, 1, 0, 4, MY_EP_OUT, MY_EP_IN, + FPGA_EP_OUT, + MY_EP_OUT, + FPGA_EP_IN, + MY_EP_IN), + TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MY_EP_OUT, MY_EP_IN, + MY_EP_OUT, + MY_EP_IN), }; +#undef TYPE_ENTRY -void my_usb_device_cleanup(struct my_usb_device *mydev) +#define TIMEOUT 5000 + +void my_usb_device_cleanup(struct my_usb_device *mydev, const struct astribank_type *abtype) { assert(mydev != NULL); if(!mydev->handle) { return; /* Nothing to do */ } - if(usb_release_interface(mydev->handle, MY_INTERFACE) != 0) { + if(usb_release_interface(mydev->handle, abtype->my_interface_num) != 0) { ERR("Releasing interface: usb: %s\n", usb_strerror()); } if(usb_close(mydev->handle) != 0) { @@ -224,11 +254,12 @@ void my_usb_device_cleanup(struct my_usb_device *mydev) static void show_device_info(const struct my_usb_device *mydev) { const struct myeeprom *eeprom; - const uint8_t *data = eeprom->serial; + uint8_t data[SERIAL_SIZE + 1]; assert(mydev != NULL); eeprom = &mydev->eeprom; - data = eeprom->serial; + memset(data, 0, SERIAL_SIZE + 1); + memcpy(data, eeprom->serial, SERIAL_SIZE); printf("USB iManufacturer: [%s]\n", mydev->iManufacturer); printf("USB iProduct: [%s]\n", mydev->iProduct); printf("USB iSerialNumber: [%s]\n", mydev->iSerialNumber); @@ -236,9 +267,9 @@ static void show_device_info(const struct my_usb_device *mydev) printf("EEPROM Vendor: 0x%04X\n", eeprom->vendor); printf("EEPROM Product: 0x%04X\n", eeprom->product); printf("EEPROM Release: %d.%03d\n", eeprom->release_major, eeprom->release_minor); - printf("EEPROM Serial: 0x[%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X]\n", + printf("EEPROM Serial: HEX(%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X) [%s]\n", data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7]); + data[4], data[5], data[6], data[7], data); } void dump_packet(const char *msg, const char *buf, int len) @@ -249,38 +280,45 @@ void dump_packet(const char *msg, const char *buf, int len) INFO("%s: %2d> 0x%02X\n", msg, i, (uint8_t)buf[i]); } -int send_usb(const char *msg, struct my_usb_device *mydev, int endpoint, struct fpga_packet_header *phead, int len, int timeout) +int send_usb(const char *msg, struct my_usb_device *mydev, struct fpga_packet_header *phead, int len, int timeout) { char *p = (char *)phead; int ret; if(verbose >= LOG_DEBUG) dump_packet(msg, p, len); - ret = usb_bulk_write(mydev->handle, endpoint, p, len, timeout); + if(mydev->my_ep_out & USB_ENDPOINT_IN) { + ERR("send_usb called with an input endpoint 0x%x\n", mydev->my_ep_out); + return -EINVAL; + } + ret = usb_bulk_write(mydev->handle, mydev->my_ep_out, p, len, timeout); if(ret < 0) { - ERR("bulk_write failed: %s\n", usb_strerror()); + ERR("bulk_write to endpoint 0x%x failed: %s\n", mydev->my_ep_out, usb_strerror()); dump_packet("send_usb[ERR]", p, len); return ret; } else if(ret != len) { - ERR("bulk_write short write: %s\n", usb_strerror()); + ERR("bulk_write to endpoint 0x%x short write: %s\n", mydev->my_ep_out, usb_strerror()); dump_packet("send_usb[ERR]", p, len); return -EFAULT; } return ret; } -int recv_usb(const char *msg, struct my_usb_device *mydev, int endpoint, char *buf, size_t len, int timeout) +int recv_usb(const char *msg, struct my_usb_device *mydev, char *buf, size_t len, int timeout) { int ret; - if(verbose >= LOG_DEBUG) - dump_packet(msg, buf, len); - ret = usb_bulk_read(mydev->handle, endpoint, buf, len, timeout); + if(mydev->my_ep_in & USB_ENDPOINT_OUT) { + ERR("recv_usb called with an output endpoint 0x%x\n", mydev->my_ep_in); + return -EINVAL; + } + ret = usb_bulk_read(mydev->handle, mydev->my_ep_in, buf, len, timeout); if(ret < 0) { - ERR("bulk_read failed: %s\n", usb_strerror()); - dump_packet("recv_usb[ERR]", buf, len); + ERR("bulk_read from endpoint 0x%x failed: %s\n", mydev->my_ep_in, usb_strerror()); return ret; } + if(verbose >= LOG_DEBUG) + dump_packet(msg, buf, ret); return ret; } @@ -297,10 +335,10 @@ int eeprom_set(struct my_usb_device *mydev, const struct myeeprom *eeprom) phead->header.op = PT_EEPROM_SET; memcpy(&phead->d.eeprom_set.data, eeprom, EEPROM_SIZE); len = sizeof(phead->d.eeprom_set) + sizeof(phead->header.op); - ret = send_usb("eeprom_set[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT); + ret = send_usb("eeprom_set[W]", mydev, phead, len, TIMEOUT); if(ret < 0) return ret; - ret = recv_usb("eeprom_set[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + ret = recv_usb("eeprom_set[R]", mydev, buf, sizeof(buf), TIMEOUT); if(ret <= 0) return ret; phead = (struct fpga_packet_header *)buf; @@ -328,10 +366,10 @@ int eeprom_get(struct my_usb_device *mydev) DBG("%s Start...\n", __FUNCTION__); phead->header.op = PT_EEPROM_GET; len = sizeof(phead->header.op); /* warning: sending small packet */ - ret = send_usb("eeprom_get[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT); + ret = send_usb("eeprom_get[W]", mydev, phead, len, TIMEOUT); if(ret < 0) return ret; - ret = recv_usb("eeprom_get[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + ret = recv_usb("eeprom_get[R]", mydev, buf, sizeof(buf), TIMEOUT); if(ret <= 0) return ret; phead = (struct fpga_packet_header *)buf; @@ -357,22 +395,22 @@ int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq) assert(mydev != NULL); assert(hexline != NULL); - len = hexline->d.content.header.ll; /* don't send checksum */ - data = hexline->d.content.tt_data.data; if(hexline->d.content.header.tt != TT_DATA) { - ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt); - return -EINVAL; + DBG("Non data record %d type = %d\n", seq, hexline->d.content.header.tt); + return 0; } + len = hexline->d.content.header.ll; /* don't send checksum */ + data = hexline->d.content.tt_data.data; phead->header.op = PT_DATA_PACKET; phead->d.data_packet.seq = seq; phead->d.data_packet.reserved = 0x00; memcpy(phead->d.data_packet.data, data, len); len += sizeof(hexline->d.content.header); DBG("%04d+\r", seq); - ret = send_usb("hexline[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT); + ret = send_usb("hexline[W]", mydev, phead, len, TIMEOUT); if(ret < 0) return ret; - ret = recv_usb("hexline[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT); + ret = recv_usb("hexline[R]", mydev, buf, sizeof(buf), TIMEOUT); if(ret <= 0) return ret; DBG("%04d-\r", seq); @@ -427,7 +465,7 @@ int send_splited_hexline(struct my_usb_device *mydev, struct hexline *hexline, i ERR("Not enough memory for spliting the lines\n" ); return -EINVAL; } - memset( extraline, 0, allocsize ); + memset(extraline, 0, allocsize); extraline->d.content.header.ll = this_line; extraline->d.content.header.offset = hexline->d.content.header.offset + extra_offset; extraline->d.content.header.tt = hexline->d.content.header.tt; @@ -444,7 +482,53 @@ int send_splited_hexline(struct my_usb_device *mydev, struct hexline *hexline, i return linessent; } -int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) +int match_usb_device_identity(const struct usb_config_descriptor *config_desc, + const struct astribank_type *ab) +{ + struct usb_interface *interface; + struct usb_interface_descriptor *iface_desc; + + if(config_desc->bNumInterfaces <= ab->my_interface_num) + return 0; + interface = &config_desc->interface[ab->my_interface_num]; + iface_desc = interface->altsetting; + + return iface_desc->bInterfaceClass == 0xFF && + iface_desc->bInterfaceNumber == ab->my_interface_num && + iface_desc->bNumEndpoints == ab->num_endpoints; +} + +const struct astribank_type *my_usb_device_identify(const char devpath[], struct my_usb_device *mydev) +{ + struct usb_device_descriptor *dev_desc; + struct usb_config_descriptor *config_desc; + int i; + + assert(mydev != NULL); + usb_init(); + usb_find_busses(); + usb_find_devices(); + mydev->dev = dev_of_path(devpath); + if(!mydev->dev) { + ERR("Bailing out\n"); + return 0; + } + dev_desc = &mydev->dev->descriptor; + config_desc = mydev->dev->config; + for(i = 0; i < sizeof(astribank_types)/sizeof(astribank_types[0]); i++) { + if(match_usb_device_identity(config_desc, &astribank_types[i])) { + DBG("Identified[%d]: interfaces=%d endpoints=%d: \"%s\"\n", + i, + astribank_types[i].num_interfaces, + astribank_types[i].num_endpoints, + astribank_types[i].name); + return &astribank_types[i]; + } + } + return NULL; +} + +int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const struct astribank_type *abtype) { struct usb_device_descriptor *dev_desc; struct usb_config_descriptor *config_desc; @@ -468,44 +552,23 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) ERR("Failed to open usb device '%s/%s': %s\n", mydev->dev->bus->dirname, mydev->dev->filename, usb_strerror()); return 0; } - if(usb_set_configuration(mydev->handle, MY_CONFIG) != 0) { - ERR("usb: %s\n", usb_strerror()); - return 0; - } - if(usb_claim_interface(mydev->handle, MY_INTERFACE) != 0) { - ERR("usb: %s\n", usb_strerror()); + if(usb_claim_interface(mydev->handle, abtype->my_interface_num) != 0) { + ERR("usb_claim_interface: %s\n", usb_strerror()); return 0; } if(usb_reset(mydev->handle) != 0) { - ERR("Reseting device: usb: %s\n", usb_strerror()); + ERR("usb_reset: %s\n", usb_strerror()); return 0; } dev_desc = &mydev->dev->descriptor; config_desc = mydev->dev->config; - interface = &config_desc->interface[MY_INTERFACE]; + interface = &config_desc->interface[abtype->my_interface_num]; iface_desc = interface->altsetting; - INFO("Vendor:Product=%04X:%04X Class=%d (endpoints=%d)\n", - dev_desc->idVendor, - dev_desc->idProduct, - dev_desc->bDeviceClass, - iface_desc->bNumEndpoints); - if(iface_desc->bInterfaceClass != 0xFF) { - ERR("Wrong Interface class %d\n", iface_desc->bInterfaceClass); - return 0; - } - if(iface_desc->bInterfaceNumber != MY_INTERFACE) { - ERR("Wrong Interface number %d\n", iface_desc->bInterfaceNumber); - return 0; - } - if(iface_desc->bNumEndpoints != MY_ENDPOINTS) { - ERR("Wrong number of endpoints: %d\n", iface_desc->bNumEndpoints); - return 0; - } endpoint = iface_desc->endpoint; mydev->is_usb2 = (endpoint->wMaxPacketSize == 512); for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { - if(endpoint->bEndpointAddress != my_endpoints[i]) { - ERR("Wrong endpoint %d: address = 0x%X\n", i, endpoint->bEndpointAddress); + if(endpoint->bEndpointAddress != abtype->endpoints[i]) { + ERR("Wrong endpoint 0x%X (at index %d)\n", endpoint->bEndpointAddress, i); return 0; } if(endpoint->bEndpointAddress == MY_EP_OUT || endpoint->bEndpointAddress == MY_EP_IN) { @@ -515,17 +578,27 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev) } } } - if(usb_resetep(mydev->handle, MY_EP_OUT) != 0) { + mydev->my_ep_in = abtype->my_ep_in; + mydev->my_ep_out = abtype->my_ep_out; + ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle); + ret = get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle); + ret = get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle); + ret = get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle); + INFO("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n", + dev_desc->idVendor, + dev_desc->idProduct, + mydev->iManufacturer, + mydev->iProduct, + mydev->iSerialNumber, + mydev->iInterface); + if(usb_resetep(mydev->handle, mydev->my_ep_out) != 0) { ERR("Failed to reset usb output endpoint: %s\n", usb_strerror()); return 0; } - if(usb_resetep(mydev->handle, MY_EP_IN) != 0) { + if(usb_resetep(mydev->handle, mydev->my_ep_in) != 0) { ERR("Failed to reset usb input endpoint: %s\n", usb_strerror()); return 0; } - ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle); - ret = get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle); - ret = get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle); return 1; } @@ -538,7 +611,7 @@ int renumerate_device(struct my_usb_device *mydev, enum fpga_load_packet_types p assert(mydev != NULL); DBG("Renumerating with 0x%X\n", pt); phead->header.op = pt; - ret = send_usb("renumerate[W]", mydev, MY_EP_OUT, phead, 1, TIMEOUT); + ret = send_usb("renumerate[W]", mydev, phead, 1, TIMEOUT); if(ret < 0) return ret; return 0; @@ -604,8 +677,10 @@ void usage() fprintf(stderr, "\t\t[-r] # Reset the device\n"); fprintf(stderr, "\t\t[-b ] # Output to \n"); fprintf(stderr, "\t\t[-I ] # Input from \n"); + fprintf(stderr, "\t\t[-H ] # Output to ('-' is stdout)\n"); fprintf(stderr, "\t\t[-i] # Show hexfile information\n"); fprintf(stderr, "\t\t[-g] # Get eeprom from device\n"); + fprintf(stderr, "\t\t[-v] # Increase verbosity\n"); #ifdef XORCOM_INTERNAL fprintf(stderr, "\t\t[-C srC byte] # Set Address sourCe (default: C0)\n"); fprintf(stderr, "\t\t[-V vendorid] # Set Vendor id on device\n"); @@ -626,28 +701,63 @@ static void parse_report_func(int level, const char *msg, ...) va_end(ap); } +#ifdef XORCOM_INTERNAL +static void eeprom_fill(struct myeeprom *myeeprom, + const char vendor[], + const char product[], + const char release[], + const char serial[], + const char source[]) +{ + // FF: address source is from device. C0: from eeprom + if (source) + myeeprom->source = strtoul(source, NULL, 0); + else + myeeprom->source = 0xC0; + if(vendor) + myeeprom->vendor = strtoul(vendor, NULL, 0); + if(product) + myeeprom->product = strtoul(product, NULL, 0); + if(release) { + int release_major = 0; + int release_minor = 0; + + sscanf(release, "%d.%d", &release_major, &release_minor); + myeeprom->release_major = release_major; + myeeprom->release_minor = release_minor; + } + if(serial) { + /* padding */ + memset(myeeprom->serial, 0, SERIAL_SIZE); + memcpy(myeeprom->serial, serial, strlen(serial)); + } +} +#endif + int main(int argc, char *argv[]) { + const struct astribank_type *abtype; struct my_usb_device mydev; const char *devpath = NULL; const char *binfile = NULL; - const char *hexfile = NULL; + const char *inhexfile = NULL; + const char *outhexfile = NULL; struct hexdata *hexdata = NULL; int opt_reset = 0; int opt_info = 0; int opt_read_eeprom = 0; + int opt_output_width = 0; + int output_is_set = 0; #ifdef XORCOM_INTERNAL int opt_write_eeprom = 0; char *vendor = NULL; char *source = NULL; - int is_source_given = 0; char *product = NULL; char *release = NULL; char *serial = NULL; - uint8_t serial_buf[SERIAL_SIZE]; - const char options[] = "rib:C:D:ghI:vV:P:R:S:"; + const char options[] = "rib:D:ghH:I:vw:C:V:P:R:S:"; #else - const char options[] = "rib:D:ghI:v"; + const char options[] = "rib:D:ghH:I:vw:"; #endif int ret = 0; @@ -664,6 +774,10 @@ int main(int argc, char *argv[]) switch (c) { case 'D': devpath = optarg; + if(output_is_set++) { + ERR("Cannot set -D. Another output option is already selected\n"); + return 1; + } break; case 'r': opt_reset = 1; @@ -673,12 +787,23 @@ int main(int argc, char *argv[]) break; case 'b': binfile = optarg; + if(output_is_set++) { + ERR("Cannot set -b. Another output option is already selected\n"); + return 1; + } break; case 'g': opt_read_eeprom = 1; break; + case 'H': + outhexfile = optarg; + if(output_is_set++) { + ERR("Cannot set -H. Another output option is already selected\n"); + return 1; + } + break; case 'I': - hexfile = optarg; + inhexfile = optarg; break; #ifdef XORCOM_INTERNAL case 'V': @@ -686,7 +811,6 @@ int main(int argc, char *argv[]) break; case 'C': source = optarg; - is_source_given = 1; break; case 'P': product = optarg; @@ -697,28 +821,28 @@ int main(int argc, char *argv[]) case 'S': serial = optarg; { - int i; - char *p; - unsigned long val; - - p = strtok(serial, ","); - for(i = 0; i < SERIAL_SIZE && p; i++) { - val = strtoul(p, NULL, 0); - if(val > 0xFF) { - ERR("Value #%d for -S option is too large (%lu)\n", i+1, val); - usage(); - } - serial_buf[i] = val; - p = strtok(NULL, ","); + const char GOOD_CHARS[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-_."; + int len = strlen(serial); + int goodlen = strspn(serial, GOOD_CHARS); + + if(len > SERIAL_SIZE) { + ERR("Serial number too long (%d > %d)\n", len, SERIAL_SIZE); + usage(); } - if(i < SERIAL_SIZE) { - ERR("got only %d values for -S option. Need %d\n", i, SERIAL_SIZE); + if(goodlen != len) { + ERR("Bad character in serial number (pos=%d)\n", goodlen); usage(); } } - break; #endif + case 'w': + opt_output_width = strtoul(optarg, NULL, 0); + break; case 'v': verbose++; break; @@ -732,34 +856,66 @@ int main(int argc, char *argv[]) if (optind != argc) { usage(); } - if(hexfile) { + if(inhexfile) { +#ifdef XORCOM_INTERNAL + if(vendor || product || release || serial || source ) { + ERR("The -I option is exclusive of -[VPRSC]\n"); + return 1; + } +#endif parse_hexfile_set_reporting(parse_report_func); - hexdata = parse_hexfile(hexfile, MAX_HEX_LINES); + hexdata = parse_hexfile(inhexfile, MAX_HEX_LINES); if(!hexdata) { ERR("Bailing out\n"); exit(1); } if(opt_info) { printf("%s: Version=%s Checksum=%d\n", - hexfile, hexdata->version_info, - calc_checksum(hexdata)); + inhexfile, hexdata->version_info, + bsd_checksum(hexdata)); } - if(binfile) + if(binfile) { dump_binary(hexdata, binfile); - if(!devpath) return 0; + } + if(outhexfile) { + if(opt_output_width) + dump_hexfile2(hexdata, outhexfile, opt_output_width); + else + dump_hexfile(hexdata, outhexfile); + return 0; + } + } +#ifdef XORCOM_INTERNAL + else if(vendor || product || release || serial || source ) { + if(outhexfile) { + FILE *fp; + + if(strcmp(outhexfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outhexfile, "w")) == NULL) { + perror(outhexfile); + return 1; + } + memset(&mydev.eeprom, 0, sizeof(struct myeeprom)); + eeprom_fill(&mydev.eeprom, vendor, product, release, serial, source); + gen_hexline((uint8_t *)&mydev.eeprom, 0, sizeof(mydev.eeprom), fp); + gen_hexline(NULL, 0, 0, fp); /* EOF */ + return 0; + } } +#endif if(!devpath) { ERR("Missing device path\n"); usage(); } -#ifdef XORCOM_INTERNAL - if(vendor || product || release || serial || source ) - opt_read_eeprom = opt_write_eeprom = 1; -#endif DBG("Startup %s\n", devpath); - - if(!my_usb_device_init(devpath, &mydev)) { + if((abtype = my_usb_device_identify(devpath, &mydev)) == NULL) { + ERR("Bad device. Does not match our types.\n"); + usage(); + } + INFO("FIRMWARE: %s (type=%d)\n", abtype->name, abtype->type_code); + if(!my_usb_device_init(devpath, &mydev, abtype)) { ERR("Failed to initialize USB device '%s'\n", devpath); ret = -ENODEV; goto dev_err; @@ -769,6 +925,13 @@ int main(int argc, char *argv[]) ERR("Failed reading eeprom\n"); goto dev_err; } +#ifdef XORCOM_INTERNAL + if(vendor || product || release || serial || source ) { + eeprom_fill(&mydev.eeprom, vendor, product, release, serial, source); + opt_write_eeprom = 1; + opt_read_eeprom = 1; + } +#endif if(opt_read_eeprom) { show_device_info(&mydev); } @@ -787,26 +950,11 @@ int main(int argc, char *argv[]) } } #ifdef XORCOM_INTERNAL - if(opt_write_eeprom) { - // FF: address source is from device. C0: from eeprom - if (is_source_given) - mydev.eeprom.source = strtoul(source, NULL, 0); - else - mydev.eeprom.source = 0xC0; - if(vendor) - mydev.eeprom.vendor = strtoul(vendor, NULL, 0); - if(product) - mydev.eeprom.product = strtoul(product, NULL, 0); - if(release) { - int release_major = 0; - int release_minor = 0; - - sscanf(release, "%d.%d", &release_major, &release_minor); - mydev.eeprom.release_major = release_major; - mydev.eeprom.release_minor = release_minor; - } - if(serial) { - memcpy(&mydev.eeprom.serial, serial_buf, SERIAL_SIZE); + else if(opt_write_eeprom) { + if(abtype->type_code == USB_FIRMWARE_II) { + ERR("No EEPROM burning command in %s. Use fxload for that\n", + abtype->name); + goto dev_err; } ret = eeprom_set(&mydev, &mydev.eeprom); if(ret < 0) { @@ -827,6 +975,6 @@ int main(int argc, char *argv[]) } DBG("Exiting\n"); dev_err: - my_usb_device_cleanup(&mydev); + my_usb_device_cleanup(&mydev, abtype); return ret; } diff --git a/xpp/utils/genzaptelconf b/xpp/utils/genzaptelconf index 93d7f6e..d5ce1b9 100755 --- a/xpp/utils/genzaptelconf +++ b/xpp/utils/genzaptelconf @@ -115,7 +115,7 @@ if [ ! -x "$ZTCFG" ]; then ZTCFG=/usr/sbin/ztcfg else echo >&2 "ztcfg is not on found, do you have zaptel properly installed?" - exit 1; + exit_cleanup 1 fi fi @@ -143,14 +143,13 @@ bri) ZAPBRI_NET=bri_net; ZAPBRI_CPE=bri_cpe ;; pri) ZAPBRI_NET=pri_net; ZAPBRI_CPE=pri_cpe ;; bri_ptmp) ZAPBRI_NET=bri_net_ptmp; ZAPBRI_CPE=bri_cpe_ptmp ;; *) - echo >&2 "Incorrect value for ZAPBRI_SIGNALLING ($ZAPBRI_SIGNALLING). Abortring" - exit 1 + die "Incorrect value for ZAPBRI_SIGNALLING ($ZAPBRI_SIGNALLING). Abortring" ;; esac die() { echo "$@" >&2 - exit 1 + exit_cleanup 1 } say() { @@ -160,6 +159,16 @@ say() { echo "$@" >&2 } +# exit (exit value is the optional $1), and clean up after us +exit_cleanup() { + if [ -d "$tmp_dir" ]; then + # don't fail but don't hide error if directory is not + # empty + rmdir "$tmp_dir" || : + fi + exit $1 +} + # Wait for udev to generate /dev/zap/ctl, if needed: wait_for_zapctl() { # if device file already exists, or if zaptel has failed to load: @@ -529,12 +538,6 @@ unload_module() { } unload_modules() { - if - pids="$(pgrep asterisk)" - [ "$pids" != '' ] - then - die "Before unloading -- STOP asterisk (pids=$pids)." - fi say "Unloading zaptel modules:" unload_module zaptel say '' @@ -1052,7 +1055,7 @@ do c) lc_country=`echo $OPTARG | tr -d -c a-z` ;; d) do_detect=yes ;; F) fxsdisable=yes;; - u) do_unload=yes ;; + u) do_unload=yes ; force_stop_ast=yes ;; v) verbose=yes ;; l) mode='list' ;; M) do_module_list=yes; do_detect=yes ;; @@ -1101,14 +1104,14 @@ else echo >&2 "Asterisk is already running. Configuration left untouched" echo >&2 "You can use the option -s to shut down Asterisk for the" echo >&2 "duration of the detection." - exit 1 + exit_cleanup 1 fi fi if [ "$do_unload" = yes ] then unload_modules - exit + exit_cleanup $? fi if [ "$do_detect" = yes ] @@ -1144,7 +1147,7 @@ fi if [ "$force_stop_ast" != 'yes' ] || [ "$do_restart" != 'yes' ] then - exit 0 + exit_cleanup 0 fi if [ -x /etc/init.d/asterisk ] diff --git a/xpp/utils/hexfile.c b/xpp/utils/hexfile.c index 5d6eaa7..1493199 100644 --- a/xpp/utils/hexfile.c +++ b/xpp/utils/hexfile.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "hexfile.h" static const char rcsid[] = "$Id$"; @@ -41,11 +42,11 @@ parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_fun static void chomp(char buf[]) { size_t last = strlen(buf) - 1; - while(last >= 0 && (buf[last] == '\n' || buf[last] == '\r')) + while(last >= 0 && isspace(buf[last])) buf[last--] = '\0'; } -int checksum(struct hexline *hexline) +static int hexline_checksum(struct hexline *hexline) { unsigned int i; unsigned int chksm = 0; @@ -57,7 +58,7 @@ int checksum(struct hexline *hexline) return chksm & 0xFF; } -int dump_hexline(int recordno, struct hexline *line, FILE *outfile) +int dump_hexline(int recordno, struct hexline *line, FILE *fp) { uint8_t ll; uint16_t offset; @@ -70,16 +71,16 @@ int dump_hexline(int recordno, struct hexline *line, FILE *outfile) ll = line->d.content.header.ll; offset = line->d.content.header.offset; tt = line->d.content.header.tt; - fprintf(outfile, ":%02X%04X%02X", ll, offset, tt); + fprintf(fp, ":%02X%04X%02X", ll, offset, tt); data = line->d.content.tt_data.data; for(i = 0; i < ll; i++) { - fprintf(outfile, "%02X", data[i]); + fprintf(fp, "%02X", data[i]); } old_chksum = data[ll]; data[ll] = 0; - new_chksum = 0xFF - checksum(line) + 1; + new_chksum = 0xFF - hexline_checksum(line) + 1; data[ll] = old_chksum; - fprintf(outfile, "%02X\n", new_chksum); + fprintf(fp, "%02X\n", new_chksum); if(new_chksum != old_chksum) { if(report_func) report_func(LOG_ERR, "record #%d: new_chksum(%02X) != old_chksum(%02X)\n", @@ -89,22 +90,38 @@ int dump_hexline(int recordno, struct hexline *line, FILE *outfile) return 1; } -static int update_hexline(struct hexdata *hexdata, char *buf) +struct hexline *new_hexline(uint8_t datalen, uint16_t offset, uint8_t tt) +{ + struct hexline *hexline; + size_t allocsize; + + allocsize = sizeof(struct hexline) + datalen + 1; /* checksum byte */ + if((hexline = malloc(allocsize)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory\n"); + return NULL; + } + memset(hexline, 0, allocsize); + hexline->d.content.header.ll = datalen; + hexline->d.content.header.offset = offset; + hexline->d.content.header.tt = tt; + return hexline; +} + +static int append_hexline(struct hexdata *hexdata, char *buf) { int ret; unsigned int ll, offset, tt; char *p; struct hexline *hexline; unsigned int i; - int allocsize; - unsigned int last_line = hexdata->last_line; if(hexdata->got_eof) { if(report_func) report_func(LOG_ERR, "Extranous data after EOF record\n"); return -EINVAL; } - if(last_line >= hexdata->maxlines) { + if(hexdata->last_line >= hexdata->maxlines) { if(report_func) report_func(LOG_ERR, "Hexfile too large (maxline %d)\n", hexdata->maxlines); return -ENOMEM; @@ -121,41 +138,98 @@ static int update_hexline(struct hexdata *hexdata, char *buf) case TT_EOF: if(ll != 0) { if(report_func) - report_func(LOG_ERR, "Bad EOF record len = %d\n", ll); + report_func(LOG_ERR, + "%d: Record %d(EOF): Bad len = %d\n", + hexdata->last_line, tt, ll); return -EINVAL; } if(offset != 0) { if(report_func) - report_func(LOG_ERR, "Bad EOF record offset = %d\n", offset); + report_func(LOG_ERR, + "%d: Record %d(EOF): Bad offset = %d\n", + hexdata->last_line, tt, offset); return -EINVAL; } hexdata->got_eof = 1; break; - case TT_EXT_SEG: /* Unimplemented */ - case TT_START_SEG: /* Unimplemented */ - case TT_EXT_LIN: /* Unimplemented */ + case TT_EXT_SEG: + if(ll != 2) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_SEG): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_SEG): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + break; + case TT_START_SEG: + if(ll != 4) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(START_SEG): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(START_SEG): Bad offset = %d\n", + hexdata->last_line, tt, offset); + return -EINVAL; + } + break; + case TT_EXT_LIN: + if(ll != 2) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad offset = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + break; case TT_START_LIN: /* Unimplemented */ - return 1; + if(ll != 4) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad len = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + if(offset != 0) { + if(report_func) + report_func(LOG_ERR, + "%d: Record %d(EXT_LIN): Bad offset = %d\n", + hexdata->last_line, tt, ll); + return -EINVAL; + } + break; default: if(report_func) - report_func(LOG_ERR, "Unknown record type %d\n", tt); + report_func(LOG_ERR, "%d: Unimplemented record type %d: %s\n", + hexdata->last_line, tt, buf); return -EINVAL; } buf += 8; /* Skip header */ - ll++; /* include the checksum for now */ - allocsize = sizeof(struct hexline) + ll; - if((hexline = (struct hexline *)malloc(allocsize)) == NULL) { + if((hexline = new_hexline(ll, offset, tt)) == NULL) { if(report_func) report_func(LOG_ERR, "No more memory for hexfile lines\n"); return -EINVAL; } - memset(hexline, 0, allocsize); - hexline->d.content.header.ll = ll; - hexline->d.content.header.offset = offset; - hexline->d.content.header.tt = tt; - hexdata->lines[last_line++] = hexline; p = buf; - for(i = 0; i < ll; i++) { + for(i = 0; i < ll + 1; i++) { /* include checksum */ unsigned int val; if((*p == '\0') || (*(p+1) == '\0')) { @@ -172,14 +246,15 @@ static int update_hexline(struct hexdata *hexdata, char *buf) hexline->d.content.tt_data.data[i] = val; p += 2; } - hexline->d.content.header.ll--; /* Fix the checksum */ - if(checksum(hexline) != 0) { + if(hexline_checksum(hexline) != 0) { if(report_func) { - report_func(LOG_ERR, "Bad checksum (%d instead of 0)\n", checksum(hexline)); - dump_hexline(last_line, hexline, stderr); + report_func(LOG_ERR, "Bad checksum (%d instead of 0)\n", + hexline_checksum(hexline)); + dump_hexline(hexdata->last_line, hexline, stderr); } return -EINVAL; } + hexdata->lines[hexdata->last_line] = hexline; if(hexdata->got_eof) return 0; hexdata->last_line++; @@ -198,10 +273,19 @@ void free_hexdata(struct hexdata *hexdata) } } -int dump_hexfile(struct hexdata *hexdata, FILE *outfile) +int dump_hexfile(struct hexdata *hexdata, const char *outfile) { + FILE *fp; unsigned int i; + if(report_func) + report_func(LOG_INFO, "Dumping hex data into '%s'\n", outfile); + if(!outfile || strcmp(outfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); + } for(i = 0; i <= hexdata->last_line; i++) { struct hexline *line = hexdata->lines[i]; if(!line) { @@ -209,72 +293,76 @@ int dump_hexfile(struct hexdata *hexdata, FILE *outfile) report_func(LOG_ERR, "Missing line at #%d\n", i); return -EINVAL; } - if(!dump_hexline(i, line, outfile)) + if(!dump_hexline(i, line, fp)) return -EINVAL; } return 0; } -int dump_hexfile2(struct hexdata *hexdata, FILE *outfile, uint8_t maxwidth) +int dump_hexfile2(struct hexdata *hexdata, const char *outfile, uint8_t maxwidth) { - uint8_t ll; + FILE *fp; uint8_t tt; - uint8_t new_chksum; - uint8_t *data; unsigned int i; - unsigned int j; + struct hexline *line; - if (maxwidth <= sizeof(hexdata->lines[0]->d.content.header) ){ - if(report_func) - report_func(LOG_ERR, "Line width too small %d\n", maxwidth); - return -EINVAL; + if(report_func) + report_func(LOG_INFO, + "Dumping hex data into '%s' (maxwidth=%d)\n", + outfile, maxwidth); + if(!outfile || strcmp(outfile, "-") == 0) + fp = stdout; + else if((fp = fopen(outfile, "w")) == NULL) { + perror(outfile); + exit(1); } - + if(maxwidth == 0) + maxwidth = UINT8_MAX; for(i = 0; i <= hexdata->last_line; i++) { - struct hexline *line = hexdata->lines[i]; - struct hexline *extraline; - int allocsize; - int bytesleft = 0; - int extra_offset = 0; - unsigned int this_line = 0; + int bytesleft = 0; + int extra_offset = 0; + int base_offset; + uint8_t *base_data; + line = hexdata->lines[i]; if(!line) { if(report_func) report_func(LOG_ERR, "Missing line at #%d\n", i); return -EINVAL; } - ll = line->d.content.header.ll; - bytesleft = ll; + bytesleft = line->d.content.header.ll; /* split the line into several lines */ tt = line->d.content.header.tt; + base_offset = line->d.content.header.offset; + base_data = line->d.content.tt_data.data; while (bytesleft > 0) { - this_line = (bytesleft >= maxwidth) ? maxwidth : bytesleft; - allocsize = sizeof(struct hexline) + this_line + 1; + struct hexline *extraline; + uint8_t new_chksum; + unsigned int curr_bytes = (bytesleft >= maxwidth) ? maxwidth : bytesleft; + /* generate the new line */ - if((extraline = (struct hexline *)malloc(allocsize)) == NULL) { + if((extraline = new_hexline(curr_bytes, base_offset + extra_offset, tt)) == NULL) { if(report_func) report_func(LOG_ERR, "No more memory for hexfile lines\n"); return -EINVAL; } - memset( extraline, 0, allocsize ); - extraline->d.content.header.ll = this_line; - extraline->d.content.header.offset = line->d.content.header.offset + extra_offset; - extraline->d.content.header.tt = tt; - memcpy( extraline->d.content.tt_data.data, line->d.content.tt_data.data+extra_offset, this_line); - new_chksum = 0xFF - checksum(extraline) + 1; + memcpy(extraline->d.content.tt_data.data, base_data + extra_offset, curr_bytes); + new_chksum = 0xFF - hexline_checksum(extraline) + 1; + extraline->d.content.tt_data.data[curr_bytes] = new_chksum; /* print it */ - data = extraline->d.content.tt_data.data; - fprintf(outfile, ":%02X%04X%02X", extraline->d.content.header.ll, extraline->d.content.header.offset, tt); - for(j = 0; j < this_line; j++) { - fprintf(outfile, "%02X", data[j]); - } - fprintf(outfile, "%02X\n", new_chksum); + dump_hexline(i, extraline, fp); /* cleanups */ - free( extraline); - extra_offset += this_line; - bytesleft -= this_line; + free(extraline); + extra_offset += curr_bytes; + bytesleft -= curr_bytes; } } + if(tt != TT_EOF) { + if(report_func) + report_func(LOG_ERR, "Missing EOF record\n"); + return -EINVAL; + } + dump_hexline(i, line, fp); return 0; } @@ -313,12 +401,13 @@ void process_comment(struct hexdata *hexdata, char buf[]) struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines) { - FILE *fp; - struct hexdata *hexdata = NULL; - int datasize; - char buf[BUFSIZ]; - int line; - int ret; + FILE *fp; + struct hexdata *hexdata = NULL; + int datasize; + char buf[BUFSIZ]; + int line; + int dos_eof = 0; + int ret; assert(fname != NULL); if(report_func) @@ -337,27 +426,34 @@ struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines) report_func(LOG_ERR, "Failed to open hexfile '%s'\n", fname); goto err; } - line = 0; - while(fgets(buf, BUFSIZ, fp)) { - line++; + for(line = 1; fgets(buf, BUFSIZ, fp); line++) { + if(dos_eof) { + if(report_func) + report_func(LOG_ERR, "%s:%d - Got DOS EOF character before true EOF\n", fname, line); + goto err; + } + if(buf[0] == 0x1A && buf[1] == '\0') { /* DOS EOF char */ + dos_eof = 1; + continue; + } + chomp(buf); if(buf[0] == '\0') { if(report_func) - report_func(LOG_ERR, "Short line at %s:%d\n", fname, line); + report_func(LOG_ERR, "%s:%d - Short line\n", fname, line); goto err; } - chomp(buf); if(buf[0] == '#') { process_comment(hexdata, buf); continue; } if(buf[0] != ':') { if(report_func) - report_func(LOG_ERR, "Line begins with 0x%X at %s:%d\n", buf[0], fname, line); + report_func(LOG_ERR, "%s:%d - Line begins with 0x%X\n", fname, line, buf[0]); goto err; } - if((ret = update_hexline(hexdata, buf + 1)) < 0) { + if((ret = append_hexline(hexdata, buf + 1)) < 0) { if(report_func) - report_func(LOG_ERR, "Failed parsing %s at line: %d\n", fname, line); + report_func(LOG_ERR, "%s:%d - Failed parsing.\n", fname, line); goto err; } } @@ -387,16 +483,33 @@ void dump_binary(struct hexdata *hexdata, const char *outfile) if(!hexline) break; - if(hexline->d.content.header.tt == TT_EOF) { + switch(hexline->d.content.header.tt) { + case TT_EOF: if(report_func) report_func(LOG_INFO, "\ndump: good EOF record"); - continue; - } - if(report_func) - report_func(LOG_INFO, "dump: %6d\r", i); - len = hexline->d.content.header.ll; - if(fwrite(hexline->d.content.tt_data.data, 1, len, fp) != len) { - perror("write"); + break; + case TT_DATA: + if(report_func) + report_func(LOG_INFO, "dump: %6d\r", i); + len = hexline->d.content.header.ll; + if(fwrite(hexline->d.content.tt_data.data, 1, len, fp) != len) { + perror("write"); + exit(1); + } + break; + case TT_EXT_SEG: + case TT_START_SEG: + case TT_EXT_LIN: + case TT_START_LIN: + if(report_func) + report_func(LOG_INFO, + "\ndump(%d): ignored record type %d", + i, hexline->d.content.header.tt); + break; + default: + if(report_func) + report_func(LOG_ERR, "dump: Unknown record type %d\n", + hexline->d.content.header.tt); exit(1); } } @@ -405,11 +518,30 @@ void dump_binary(struct hexdata *hexdata, const char *outfile) fclose(fp); } +void gen_hexline(const uint8_t *data, uint16_t addr, size_t len, FILE *output) +{ + struct hexline *hexline; + + if(!data) { + fprintf(output, ":%02X%04X%02XFF\n", 0, 0, TT_EOF); + return; + } + if((hexline = new_hexline(len, addr, (!data) ? TT_EOF : TT_DATA)) == NULL) { + if(report_func) + report_func(LOG_ERR, "No more memory\n"); + return; + } + if(data) + memcpy(&hexline->d.content.tt_data, data, len); + dump_hexline(0, hexline, output); + free(hexline); +} + /* * Algorithm lifted of sum(1) implementation from coreutils. * We chose the default algorithm (BSD style). */ -int calc_checksum(struct hexdata *hexdata) +int bsd_checksum(struct hexdata *hexdata) { unsigned int i; size_t len; diff --git a/xpp/utils/hexfile.h b/xpp/utils/hexfile.h index 297cfba..f8bf6a9 100644 --- a/xpp/utils/hexfile.h +++ b/xpp/utils/hexfile.h @@ -113,10 +113,11 @@ typedef void (*parse_hexfile_report_func_t)(int level, const char *msg, ...); parse_hexfile_report_func_t parse_hexfile_set_reporting(parse_hexfile_report_func_t rf); void free_hexdata(struct hexdata *hexdata); struct hexdata *parse_hexfile(const char *fname, unsigned int maxlines); -int dump_hexfile(struct hexdata *hexdata, FILE *outfile); -int dump_hexfile2(struct hexdata *hexdata, FILE *outfile, uint8_t maxwidth); +int dump_hexfile(struct hexdata *hexdata, const char *outfile); +int dump_hexfile2(struct hexdata *hexdata, const char *outfile, uint8_t maxwidth); void dump_binary(struct hexdata *hexdata, const char *outfile); -int calc_checksum(struct hexdata *hexdata); +void gen_hexline(const uint8_t *data, uint16_t addr, size_t len, FILE *output); +int bsd_checksum(struct hexdata *hexdata); __END_DECLS #endif diff --git a/xpp/utils/zapconf b/xpp/utils/zapconf index 472c3af..1144684 100755 --- a/xpp/utils/zapconf +++ b/xpp/utils/zapconf @@ -355,12 +355,12 @@ callwaiting = yes context = numberplan-custom-1 fullname = $full_name cid_number = $exten -hasagent = yes +hasagent = no hasdirectory = no -hasiax = yes +hasiax = no hasmanager = no -hassip = yes -hasvoicemail = no +hassip = no +hasvoicemail = yes host = dynamic mailbox = $exten threewaycalling = yes @@ -368,8 +368,8 @@ vmsecret = 1234 secret = 1234 signalling = $sig zapchan = $num -registeriax = yes -registersip = yes +registeriax = no +registersip = no canreinvite = no nat = no dtmfmode = rfc2833 @@ -413,11 +413,15 @@ vmsecret = 1234 ; ; Create SIP Peer ; -hassip = yes +hassip = no ; ; Create IAX friend ; -hasiax = yes +hasiax = no +; +; Create Agent friend +; +hasagent = no ; ; Create H.323 friend ; @@ -438,7 +442,7 @@ cancallforward = yes callreturn = yes callgroup = 1 pickupgroup = 1 -localextenlength = 4 +localextenlength = @{[length($base_exten)]} HEAD diff --git a/xpp/utils/zaptel_hardware b/xpp/utils/zaptel_hardware index afd3a06..91fcb2e 100755 --- a/xpp/utils/zaptel_hardware +++ b/xpp/utils/zaptel_hardware @@ -31,9 +31,10 @@ my @spans = Zaptel::spans; sub show_xbus($) { my $xbus = shift or die; my @xpds = $xbus->xpds; + my $serialnum = $xbus->serial(); my $connector = ($xbus->status eq 'CONNECTED') ? $xbus->connector : "MISSING"; $connector = "(" . $connector . ")"; - printf "%-20s\n", $connector; + printf "%-10s %-20s\n", $serialnum, $connector; foreach my $xpd (sort { $a->num <=> $b->num } @xpds) { my $reg = $xpd->zt_registration; my $span; diff --git a/xpp/utils/zconf/Zaptel/Xpp.pm b/xpp/utils/zconf/Zaptel/Xpp.pm index 28de49d..ff0008a 100644 --- a/xpp/utils/zconf/Zaptel/Xpp.pm +++ b/xpp/utils/zconf/Zaptel/Xpp.pm @@ -23,6 +23,10 @@ sub by_connector { return $a->connector cmp $b->connector; } +sub by_serial { + return $a->serial cmp $b->serial; +} + sub xbuses { my $optsort = shift || 'SORT_NAME'; my @xbuses; @@ -46,6 +50,8 @@ sub xbuses { $sorter = \&by_connector; } elsif($optsort eq "SORT_NAME") { $sorter = \&by_name; + } elsif($optsort eq "SORT_SERIAL") { + $sorter = \&by_serial; } elsif(ref($optsort) eq 'CODE') { $sorter = $optsort; } else { diff --git a/xpp/utils/zt_registration b/xpp/utils/zt_registration index 9a8323f..fdcf33e 100755 --- a/xpp/utils/zt_registration +++ b/xpp/utils/zt_registration @@ -42,8 +42,8 @@ sub myprintf { my @spans = Zaptel::spans; -foreach my $xbus (Zaptel::Xpp::xbuses('SORT_CONNECTOR')) { - myprintf "%-10s\t\t%s\n", $xbus->name, $xbus->connector; +foreach my $xbus (Zaptel::Xpp::xbuses('SORT_SERIAL')) { + myprintf "%-10s\t%s\t%s\n", $xbus->name, $xbus->serial, $xbus->connector; next unless $xbus->status eq 'CONNECTED'; foreach my $xpd ($xbus->xpds()) { my $prev = $xpd->zt_registration($on); -- cgit v1.2.3