// // File: // // Written by: David M. Stanhope [voip@fobbit.com] // #include "vblast.h" #include #include #include #ifdef __FreeBSD__ # define FORMAT_CTRL "%d" # define FORMAT_PIPE "%d.%d" #else # define FORMAT_CTRL "%d.00" # define FORMAT_PIPE "%d.%02d" #endif // do any network initialization needed void init_network(void) { // nothing to do } void set_non_blocking(SOCKET fd) { fcntl(fd, F_SETFL, O_NONBLOCK); } void set_timeout(void) { // alarm(5); } void clr_timeout(void) { // alarm(0); } int Socket_Would_Block(int err) { if(err == EWOULDBLOCK) { return 1; } else { return 0; } } // return the name of the operating system char * os_name(void) { struct utsname names; static char buf[128]; if(uname(&names) < 0) { ERR(("uname failed, error(%s)\n", Show_Error())) exit(-1); } sprintf(buf, "%s %s %s", names.sysname, names.machine, names.release); MSG2(("OS_NAME(%s)\n", buf)) return buf; } #ifdef ALLOW_KEYBOARD static struct termios oterm; void keyboard_open(VBLAST *v, int device_index) { struct termios term; if((v->fd_keyboard = open("/dev/tty", 0)) < 0) { ERR(("Can't open '/dev/tty'\n")) exit(1); } // get the terminal settings tcgetattr(v->fd_keyboard, &oterm); // get a copy of the settings, which we modify */ memcpy(&term, &oterm, sizeof(term)); // put the terminal in non-canonical mode, any // reads will wait until a character has been // pressed this function will not timeout term.c_lflag = term.c_lflag & (!ICANON); term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; tcsetattr(v->fd_keyboard, TCSANOW, &term); MSG(("Keyboard opened\n")) } void keyboard_close(VBLAST *v) { if(v->fd_keyboard != INVALID_SOCKET) { tcsetattr(v->fd_keyboard, TCSANOW, &oterm); close(v->fd_keyboard); v->fd_keyboard = INVALID_SOCKET; } } #endif // Functions to manipulate the program title as show in ps extern char **environ ; static char *title_start; // start of the proc title space static char *title_end ; // end of the proc title space static int title_size ; void init_title(int argc, char *argv[], char *envp[], char *name) { int i; // // Move the environment so 'set_title' can use the space at // the top of memory. // for(i = 0; envp[i]; i++) { ; } // figure environment size environ = (char **) malloc(sizeof (char *) * (i + 1)); for(i = 0; envp[i]; i++) { environ[i] = strdup(envp[i]); } environ[i] = NULL; // // Save start and extent of argv for set_title. // title_start = argv[0]; // // Determine how much space we can use for set_title. // Use all contiguous argv and envp pointers starting at argv[0] // for(i = 0; i < argc; i++) { if((!i) || (title_end == argv[i])) { title_end = argv[i] + strlen(argv[i]) + 1; } } for(i = 0; envp[i]; i++) { if( title_end == envp[i] ) { title_end = envp[i] + strlen(envp[i]) + 1; } } strcpy(title_start, name); title_start += strlen(name); title_size = title_end - title_start; memset(title_start,0,title_size); } void set_title(const char *fmt, ...) { char buf[255]; va_list ap ; int n ; if(title_start) // insure 'init_title' called first { memset(title_start,0,title_size); // print the argument string va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); if(strlen(buf) > (title_size - 1)) { buf[title_size - 1] = '\0'; } if((n = strlen(buf)) < 1) { return; } if(buf[n - 1] == '\n') { buf[n - 1] = '\0'; } strcat(title_start, buf); } } #ifdef USE_UGEN #include // to get the ioctl definitions #define MAX_UGEN 8 static int open_endpoint(int ugen, int endp) { int flag, timeout, fd; char name[32]; sprintf(name, "/dev/ugen" FORMAT_PIPE, ugen, endp); MSG(("OPEN(%s)\n", name)) if((fd = open(name, O_RDWR)) < 0) { ERR(("Can't open <%s> for read-write\n", name)) exit(-1); } MSG(("OPEN(%s) DONE\n", name)) flag = 1; if(ioctl(fd, USB_SET_SHORT_XFER, &flag) < 0) { ERR(("ioctl(USB_SET_SHORT_XFER) for <%s> failed\n", name)) exit(-1); } timeout = 5000; if(ioctl(fd, USB_SET_TIMEOUT, &timeout) < 0) { ERR(("ioctl(USB_SET_TIMEOUT) for <%s> failed\n", name)) exit(-1); } return fd; } // insure that all descriptors are as they should be, returns 1 if all ok, // otherwise returns 0 if any problems static int validate_descriptors(int fd, usb_device_descriptor_t *desc) { int i; struct usb_config_desc conf; struct usb_interface_desc intf; struct usb_endpoint_desc endp; // ----------------------------------------------------------------------- // validate full device descriptor, already read in // ----------------------------------------------------------------------- if(check_desc_device(desc) == 0) { return 0; } // not valid // ----------------------------------------------------------------------- // get and validate config descriptor // ----------------------------------------------------------------------- memset(&conf, 0, sizeof(conf)); conf.config_index = 0; // there is only one configuration conf.desc.bLength = USB_CONFIG_DESCRIPTOR_SIZE; // only get first part if(ioctl(fd, USB_GET_CONFIG_DESC, &conf) < 0) { ERR(("ioctl(USB_GET_CONFIG_DESC) failed\n")) return 0; } if(check_desc_config(&(conf.desc)) == 0) { return 0; } // not valid // ----------------------------------------------------------------------- // get and validate config descriptor // ----------------------------------------------------------------------- memset(&intf, 0, sizeof(intf)); intf.config_index = 0; intf.interface_index = 0; intf.alt_index = 0; intf.desc.bLength = USB_INTERFACE_DESCRIPTOR_SIZE; if(ioctl(fd, USB_GET_INTERFACE_DESC, &intf) < 0) { ERR(("ioctl(USB_GET_INTERFACE_DESC) failed\n")) return 0; } if(check_desc_interface(&(intf.desc)) == 0) { return 0; } // not valid // ----------------------------------------------------------------------- // get and validate the endpoint descriptors // ----------------------------------------------------------------------- for(i = 0; i < 4; i++) // get endpoint descriptors { memset(&endp, 0, sizeof(endp)); endp.config_index = 0; endp.interface_index = 0; endp.alt_index = 0; endp.endpoint_index = i; endp.desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; if(ioctl(fd, USB_GET_ENDPOINT_DESC, &endp) < 0) { ERR(("ioctl(USB_GET_ENDPOINT_DESC) failed\n")) return 0; } if(check_desc_endpoint(&(endp.desc), i) == 0) { return 0; } } // ----------------------------------------------------------------------- return 1; // return all is valid } static int find_vblaster(int device_index, int *p_ugen) { char name[32]; int fd, ugen, found; usb_device_descriptor_t desc; for(found = 0, ugen = 0; ugen < MAX_UGEN; ugen++) { sprintf(name, "/dev/ugen" FORMAT_CTRL, ugen); if((fd = open(name, O_RDONLY)) < 0) { MSG1(("Can't open(%s): error(%s)\n", name, Show_Error())) continue; } MSG1(("Trying (%s)\n", name)) // ------------------------------------------------------------------- memset(&desc, 0, sizeof(desc)); if(ioctl(fd, USB_GET_DEVICE_DESC, &desc) < 0) { ERR(("ioctl(USB_GET_DEVICE_DESC) failed\n")) close(fd); continue; } // validate minimal device descriptor if(check_is_vblaster(&desc) == 0) { close(fd); continue; // not voip-blaster } MSG(("Found VOIP-Blaster(%d) at (%s)\n", found, name)) if(found++ != device_index) { close(fd); continue; } if(validate_descriptors(fd, &desc) == 0) { close(fd); return -1; } *p_ugen = ugen; // where found it return fd; // found ok } // ----------------------------------------------------------------------- ERR(("Can't find VOIP-Blaster (%d)\n", device_index)) return -1; } VBLAST * vblast_device_open(int device_index) { static VBLAST vb; int ugen; if((vb.fd_control = find_vblaster(device_index, &ugen)) < 0) { exit(-1); } // ----------------------------------------------------------------------- vb.fd_command = open_endpoint(ugen, 1); vb.fd_voice_out = open_endpoint(ugen, 2); // ----------------------------------------------------------------------- return &vb; } void vblast_device_close(VBLAST *v) { MSG(("vblast_close-start\n")) close(v->fd_control ); v->fd_control = -1; close(v->fd_command ); v->fd_command = -1; close(v->fd_voice_out); v->fd_voice_out = -1; MSG(("vblast_close-done\n")) } #endif // USE_UGEN // // The End! //