summaryrefslogtreecommitdiff
path: root/xpp/utils
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-10-03 16:46:13 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-10-03 16:46:13 +0000
commit82e6b0217e63d5a77e7f673bc2a7c3712c84b7e6 (patch)
tree75dd0e4c558d02887f828bbe873998f5c26d81f0 /xpp/utils
parent0599b53369244cd6b3696022309ece91446eae9d (diff)
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
Diffstat (limited to 'xpp/utils')
-rw-r--r--xpp/utils/Makefile2
-rw-r--r--xpp/utils/fpga_load.c404
-rwxr-xr-xxpp/utils/genzaptelconf31
-rw-r--r--xpp/utils/hexfile.c316
-rw-r--r--xpp/utils/hexfile.h7
-rwxr-xr-xxpp/utils/zapconf22
-rwxr-xr-xxpp/utils/zaptel_hardware3
-rw-r--r--xpp/utils/zconf/Zaptel/Xpp.pm6
-rwxr-xr-xxpp/utils/zt_registration4
9 files changed, 545 insertions, 250 deletions
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 <binfile>] # Output to <binfile>\n");
fprintf(stderr, "\t\t[-I <hexfile>] # Input from <hexfile>\n");
+ fprintf(stderr, "\t\t[-H <hexfile>] # Output to <hexfile> ('-' 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 <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <ctype.h>
#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);