// // File: // // Written by: David M. Stanhope [voip@fobbit.com] // // --------------------------------------------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 55 #define VERSION_DATE "February 7, 2002" // --------------------------------------------------------------------------- #ifdef __linux__ # define VB_IS_UNIX 1 # define USE_DEVFS 1 #ifdef OLD_WAY # define WANT_4_FDS 1 #endif #endif #ifdef __NetBSD__ # define VB_IS_UNIX 1 # define USE_SIN_LEN 1 # define USE_UGEN 1 #endif #ifdef __FreeBSD__ // not tested but should be close # define VB_IS_UNIX 1 # define USE_SIN_LEN 1 # define USE_UGEN 1 #endif #define ALLOW_KEYBOARD 1 #ifdef VB_IS_UNIX # include # include #ifdef __FreeBSD__ # include #else # include #endif # include # include # include # include #ifdef __FreeBSD__ # include # include #else # include #endif # include # include # include # include # include typedef int SOCKET; typedef int HANDLE; typedef unsigned long long U64; # define U64_FMT "%qu" # define OFF_T_FMT "%qd" # define SOCKET_ERROR (-1) # define INVALID_SOCKET (-1) # define INVALID_HANDLE_VALUE (-1) # define Socket_Read(fd, bp, n) read(fd, bp, n) # define Socket_Write(fd, bp, n) write(fd, bp, n) # define Socket_Close(fd) close(fd) # define Socket_Errno() (errno) # define Socket_Error() Show_Error() # define Socket_Error_String(e) Show_Error_String(e) # define File_Read(fd, bp, n) read(fd, bp, n) # define File_Write(fd, bp, n) write(fd, bp, n) # define File_Close(fd) close(fd) # define _cdecl // nothing # define nap(tenths) usleep((tenths) * 100000) # define File_Open_ReadOnly(name) open(name, O_RDONLY) # define File_Rewind(fd) lseek(fd, 0, SEEK_SET) #else // assume is windows # define IS_WINDOWS 1 # define WANT_4_FDS 1 # include # include # include # include # include # include # include # include # include # include # include "devioctl.h" # include # include typedef unsigned char u_char; typedef unsigned long off_t ; typedef unsigned __int64 U64; # define U64_FMT "%I64u" # define OFF_T_FMT "%lu" # define sleep(secs) Sleep((secs ) * 1000) # define nap(tenths) Sleep((tenths) * 100) # define File_Open_ReadOnly(name) \ CreateFile(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL) # define File_Close(fd) CloseHandle(fd) # define File_Rewind(fd) SetFilePointer(fd, 0, NULL, FILE_BEGIN) # define Socket_Close(fd) closesocket(fd) # define Socket_Read(fd, bp, n) recv(fd, bp, n, 0) # define Socket_Write(fd, bp, n) send(fd, bp, n, 0) #endif #define TXT_BUF_SIZE 512 #define BIG_BUF_SIZE 8192 // this would be nice to use but only works on NetBSD, not Windows // with these do not need the double parens when using the macros // #define MSG(x...) { fprintf(stdout, ## x) ; fflush(stdout); } // #define ERR(x...) { fprintf(stderr, ## x) ; fflush(stderr); } #ifdef IS_VBWIN extern int _cdecl x_main(int argc, char *argv[], char *env[]); extern void logger (char *fmt, ...); extern void progress (char *fmt, ...); extern void x_exit (int x ); extern void update_local (long x ); extern void clear_remote (void ); extern void update_remote(char *type, char *serial_number , char *listen_ip , char *listen_port , char *remote_name , char *remote_location, char *remote_email , char *remote_flags , char *remote_version , char *remote_os , char *received ); extern void update_status(int tt, int tu, int rt, int ru, int d, int m, int q); extern void check_not_running(int x); extern void keyboard_send(int key); # define main(x, y, z) x_main(x, y, z) # define exit(x) x_exit(x) # define PMSG(x) progress x ; # define MSG(x) logger x ; # define ERR(x) logger x ; # define NEED_RETURN(x) return x; // stop warning when redefine exit # define UPDATE_STATUS(tt,tu,rt,ru,d,m,q) update_status(tt,tu,rt,ru,d,m,q); # define UPDATE_LOCAL( x ) update_local (x ); # define UPDATE_REMOTE(x ) update_remote(x, d_serial_number , \ d_listen_ip , \ d_listen_port , \ d_remote_name , \ d_remote_location, \ d_remote_email , \ d_remote_flags , \ d_remote_version , \ d_remote_os , \ d_received ); # define CLEAR_REMOTE clear_remote(); # define CHECK_NOT_RUNNING(x) check_not_running(x); #else // IS_VBWIN # define PMSG(x) { printf x ; fflush(stdout); set_title x; } # define MSG(x) { printf x ; fflush(stdout); } # define ERR(x) { printf x ; fflush(stdout); } # define NEED_RETURN(x) // nothing # define UPDATE_STATUS(tt,tu,rt,ru,d,m,q) // nothing # define UPDATE_LOCAL( x ) // nothing # define UPDATE_REMOTE(x ) // nothing # define CLEAR_REMOTE // nothing # define CHECK_NOT_RUNNING(x) // nothing #endif // IS_VBWIN #define MSG0(x) MSG(x) #define MSG1(x) if(debug_level > 0) MSG(x) #define MSG2(x) if(debug_level > 1) MSG(x) #define MSG3(x) if(debug_level > 2) MSG(x) #define MSG4(x) if(debug_level > 3) MSG(x) #define MSG5(x) if(debug_level > 4) MSG(x) #define MSG6(x) if(debug_level > 5) MSG(x) #define MSG7(x) if(debug_level > 6) MSG(x) #define MSG8(x) if(debug_level > 7) MSG(x) #define MSG9(x) if(debug_level > 8) MSG(x) #define RIGHT_NOW time(NULL) #define INVALID_POSITION_VALUE ((off_t)(-1)) // ---------------------------------------------------------------------------- // various commands that can send to the VOIP Blaster device // ---------------------------------------------------------------------------- #define COMMAND_NONE 0x00 // (NONE) #define COMMAND_PHONE_OFF 0x01 // (SWITCHRELAYPSTN) drop loop current #define COMMAND_PHONE_ON 0x02 // (SWITCHRELAYIGSP) used on startup #define COMMAND_RING_ON 0x03 // (STARTRING) start ringing #define COMMAND_RING_OFF 0x04 // (STOPRING) used on startup & to stop ringing #define COMMAND_VOUT_START 0x05 // (PLAYBACKSTART ) start voice out #define COMMAND_VOUT_STOP 0x06 // (PLAYBACKSTOP ) #define COMMAND_VINP_START 0x07 // (RECORDINGSTART) #define COMMAND_VINP_STOP 0x08 // (RECORDINGSTOP ) #define COMMAND_UNKNOWN_1 0x09 // (TESTSTART ) don't know what this does #define COMMAND_UNKNOWN_2 0x0a // (TESTSTOP ) don't know what this does #define COMMAND_UNKNOWN_3 0x0b // (SENDFAXTONE ) doesn't seem to do anything // ---------------------------------------------------------------------------- #define COMMAND_HS_OFFHOOK 0x0c // (APPONHOOK?? ) go offhook for headset #define COMMAND_HS_ONHOOK 0x0d // (APPOFFHOOK?? ) go onhook for headset #define COMMAND_SETUP_MODE 0x0e // goto setup mode? #define COMMAND_VOUT_DONE 0x0f // voice in/out off, report output drained // ---------------------------------------------------------------------------- #define COMMAND_0x10 0x10 // used in file output, seems ok without #define COMMAND_0x11 0x11 // used in file output, seems ok without #define COMMAND_MUTE_ON 0x12 // audio mute on #define COMMAND_MUTE_OFF 0x13 // audio mute off // ---------------------------------------------------------------------------- #define COMMAND_VOL_0 0x34 // set volume (min) #define COMMAND_VOL_1 0x35 // set volume #define COMMAND_VOL_2 0x36 // set volume #define COMMAND_VOL_3 0x37 // set volume (default) #define COMMAND_VOL_4 0x38 // set volume #define COMMAND_VOL_5 0x39 // set volume #define COMMAND_VOL_6 0x3a // set volume (max) // ---------------------------------------------------------------------------- // various status bytes that can be returned by the VOIP Blaster device // can also return a '0' to '9', '*' or '#' when a DTMF character is heard // ---------------------------------------------------------------------------- #define STATUS_NONE 0x00 // (NONE ) #define STATUS_HOOK_OFF 0x01 // (OFFHOOK ) #define STATUS_HOOK_ON 0x02 // (ONHOOK ) #define STATUS_DEBUG 0x00 // (DEBUG ) ?? not used ?? #define STATUS_RINGDETECT 0x00 // (RINGDETECT ) ?? not used ?? #define STATUS_RINGING_ON 0x05 // (STARTRINGEXEC) is ringing #define STATUS_RINGING_OFF 0x06 // (STOPRINGEXEC ) not ringing #define STATUS_HEADSET_IN 0x08 // 0000-1000 headset plugged in #define STATUS_HEADSET_OUT 0x09 // 0000-1001 headset un-plugged #define STATUS_0x0a 0x0a // 0000-1010 setup accepted? #define STATUS_VOUT_DONE 0x0c // 0000-1100 voice output done // ---------------------------------------------------------------------------- #define SQ_SIZE 256 #define VP_SIZE 20 // all voice packets are this size #define NP_SIZE 21 // make room for 1 byte packet type on network #define TV_LEN (VP_SIZE * 256) #define TN_LEN (NP_SIZE * 256) #define MAGIC_VOICE ((u_char) 0x5a) // length implied at NP_SIZE #define MAGIC_CNTRL ((u_char) 0xa5) // followed by 2 byte length #define MSG_HEADER_SIZE 3 // generic message has 1 byte magic + 2 byte len typedef struct _voice_entry_ { struct _voice_entry_ *next ; u_char data[NP_SIZE]; } VOICE_ENTRY; typedef struct { int count; // how many currently queued VOICE_ENTRY *head ; VOICE_ENTRY *tail ; } MSG_QUEUE; #ifndef WANT_4_FDS # define fd_voice_inp fd_voice_out # define fd_status fd_command #endif typedef struct _phonebook_ { struct _phonebook_ *next ; char *name ; struct sockaddr_in address; } PHONEBOOK; extern PHONEBOOK *phonebook_head ; extern PHONEBOOK *phonebook_tail ; extern PHONEBOOK *phonebook_current; typedef struct { #ifdef WANT_4_FDS SOCKET fd_status ; SOCKET fd_voice_inp ; #else int fd_control ; // control endpoint #endif HANDLE fd_command ; // command/status endpoint HANDLE fd_voice_out ; // voice/data endpoint (g.723.1 encoded) SOCKET fd_accept ; // socket to accept for connecitons on SOCKET fd_peer_tcp ; // socket to talk with peer on for TCP SOCKET fd_peer_udp ; // socket to talk with peer on for UDP #ifdef ALLOW_KEYBOARD SOCKET fd_keyboard ; // socket to receive keyboard chars on #endif // ----------------------------- VOICE_ENTRY *free_list ; // ----------------------------- MSG_QUEUE queue_voice ; // ----------------------------- MSG_QUEUE queue_net ; int net_over_count ; // hueristic for too much queued int net_dropped ; // counter for how many packets dropped int net_blocked ; // counter for how many packets blocked int net_received_tcp ; // counter for how many packets received int net_received_udp ; // counter for how many packets received int net_sent_tcp ; // counter for how many packets sent int net_sent_udp ; // counter for how many packets sent // ----------------------------- u_char net_buffer[TN_LEN]; // space for net read buffer int net_buffered ; // how much currently buffered // ----------------------------- u_char sq_buffer[SQ_SIZE]; // status queue space int sq_head ; // status queue head int sq_tail ; // status queue tail // ----------------------------- int startup ; // flag that in startup mode int status_hook ; // on/off hook int status_headset ; // in/out headset int have_call ; // flag that have an incoming call } VBLAST; // flags for 'vblast_play_file' #define VB_PLAY_REPEAT 1 #define VB_PLAY_KEEP_STATUS 2 // for extern SOCKET create_socket(int type, int port, unsigned long net_address); // for extern char *Show_Error(void); extern void dump(char *msg, u_char *p, int n); extern char *new_string(char *s); extern void skip_whitespace(char **cp); extern char *get_token(char **cp, char *bp); extern int get_hex(int c); extern int get_hex2(char *cp); extern int get_hex4(char *cp); extern int get_hex8(char *cp); extern int hex_char(int c); // for extern int device_index ; extern int debug_level ; extern int port_listen_tcp ; extern int port_listen_udp ; extern int net_high_water ; extern int net_high_count ; extern int device_volume ; extern int dial_timeout_1 ; extern int dial_timeout_2 ; extern int can_accept_inbound ; extern int publish_to_server ; extern int query_server ; extern int http_server ; extern int cpc_duration ; extern int force_dial ; extern char *public_name ; extern char *public_location ; extern char *public_email ; extern char *sound_ringback ; extern char *sound_busy ; extern char *sound_dialtone ; extern char *sound_dialtone_hs ; extern struct sockaddr_in public_ip_and_port_tcp; extern struct sockaddr_in public_ip_and_port_udp; extern void process_ini(char *); extern void init_address(int port, struct sockaddr_in *pa); extern char *lookup_dialed(char *dialed, int *port); extern int scan_address(char *address, int default_port); extern int resolve_address(char *name, int port, struct sockaddr_in *pa); // for extern void var_parse(char *msg); extern char *var_find(char *name); extern char *var0_chk(char *name); extern void var_add_str(char *p, char *name, char *value); extern void var_add_int(char *p, char *name, int value); extern void var_add_i32(char *p, char *name, long value); // for #define vblast_enque_voice(a, b) vblast_vp_enque(a, 0, b, &(a->queue_voice)) #define vblast_deque_voice(a ) vblast_vp_deque(a, &(a->queue_voice)) #define vblast_reset_voice(a ) vblast_vp_reset( &(a->queue_voice)) #define vblast_enque_net( a, b) vblast_vp_enque(a, 1, b, &(a->queue_net )) #define vblast_deque_net( a ) vblast_vp_deque(a, &(a->queue_net )) #define vblast_reset_net( a ) vblast_vp_reset( &(a->queue_net )) #define vblast_ready_net( a ) (a->queue_net.head) extern char *timestamp(void); extern void send_msg(VBLAST *v, char *msg, struct sockaddr_in *udp_address); extern void send_my_id(VBLAST *v, char *cmd); extern int registration_update(VBLAST *v); extern char *time_string_time_t(time_t t); extern char *time_string_str(char *ts); extern char *server_query(char *destination, int *port); extern void send_stats(int net_sent_tcp, int net_sent_udp, int net_received_tcp, int net_received_udp, int net_dropped, int net_blocked, int max_queue, time_t duration, int called, char* peer_serial_number, int hangup_reason); // for extern char serial_number_string[80]; extern int vblast_socket_writer(char *msg, SOCKET fd, u_char *bp, int n); extern VBLAST *vblast_open(int i_ugen); extern void vblast_play_file(VBLAST *v, char *name, int flags, int (*callback)(VBLAST *v)); extern void vblast_ring(VBLAST *v, int (*callback)(VBLAST *v)); extern void vblast_command(VBLAST *p, int value); extern void vblast_voice_write(VBLAST *p, u_char *pt, int n); extern int vblast_wait_input(VBLAST *v, int seconds); extern void vblast_shutdown_voice(VBLAST *p); extern int vblast_status_deque(VBLAST *p); extern u_char *vblast_vp_deque(VBLAST *v, MSG_QUEUE *qp); extern void vblast_vp_flush(VBLAST *v); extern void vblast_close(VBLAST *v); extern void process_remote_cmd(VBLAST *v, u_char *bp); // for or extern char *os_name(void); extern void init_network(void); extern VBLAST *vblast_device_open(int device_index); extern void vblast_device_close(VBLAST *v); extern void init_title(int argc, char *argv[], char *envp[], char *name); extern void set_non_blocking(SOCKET fd); extern void keyboard_open(VBLAST *v, int device_index); extern void keyboard_close(VBLAST *v); extern void set_timeout(void); extern void clr_timeout(void); extern int Socket_Would_Block(int err); #ifdef IS_WINDOWS // for extern int File_Read(HANDLE fd, void *bp, DWORD len); extern int File_Write(HANDLE fd, void *bp, DWORD len); extern int inet_aton(char *s, struct in_addr *ap); // for extern int Socket_Errno(void); extern char *Socket_Error(void); extern char *Socket_Error_String(int err); #endif // // The End! //