/* * * Copyright (c) 2002, Smart Link Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * 3. Neither the name of the Smart Link Ltd. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* * * modem.h - modem definitions * * Author: sashak@smlink.com */ #ifndef __MODEM_H__ #define __MODEM_H__ #include #include #include #include #include #include #include #include /* modem modes */ enum MODEM_MODE { MODEM_MODE_DATA = 0, MODEM_MODE_FAX = 1, MODEM_MODE_VOICE = 8 }; /* modem status */ #define STATUS_OK 0x0 #define STATUS_NOCARRIER 0x0002 // 3 #define STATUS_ERROR 0x0004 // 4 #define STATUS_NODIALTONE 0x0010 // 6 #define STATUS_BUSY 0x0020 // 7 #define STATUS_NOANSWER 0x0040 // 8 #define STATUS_DP_LINK 0x0100 // 13 #define STATUS_DP_ERROR 0x0200 // 14 #define STATUS_PACK_LINK 0x0400 // 15 #define STATUS_PACK_ERROR 0x0800 // 16 #define STATUS_EC_LINK 0x1000 // 17 #define STATUS_EC_RELEASE 0x2000 // 18 #define STATUS_EC_ERROR 0x4000 // 19 /* * parameters * */ #define MODEM_FORMAT MFMT_S16_LE #define MODEM_RATE 9600 /* 8000 */ #define MODEM_FRAG (MODEM_RATE/200) #define MODEM_MIN_RATE 300 #define MODEM_MAX_RATE 56000 #define MODEM_DEFAULT_COUNTRY_CODE 0xb5 /* USA */ #define MODEM_CONFIG_CID 1 #define MODEM_CONFIG_VOICE 1 #define MODEM_CONFIG_FAX 1 #define MODEM_CONFIG_FAX_CLASS1 1 #define MODEM_CONFIG_RING_DETECTOR 1 /* * type definitions * */ /* modem driver struct */ struct modem_driver { const char *name; int (*start)(struct modem *m); int (*stop )(struct modem *m); int (*ioctl)(struct modem *m,unsigned cmd, unsigned long arg); }; /* modem data pumps driver struct */ struct dp_driver { const enum DP_ID id; const char *name; const char *code; struct dp_operations *op; }; /* * * compressor definitions * */ #define COMP_MAX_CODEWORDS 2048 /* dictionary size */ #define COMP_MAX_STRING 34 /* max string length */ /* encoder and decoder states */ struct comp_state { const char *name; enum COMP_MODE {TRANSPARENT,COMPRESSED} mode; int escape; /* escape state: decoder only */ u16 update_at; /* update dict. at node */ u16 next_free; /* next free dict entry */ u16 last_matched; /* last matched dict entry */ u16 last_added; /* last added dict entry */ u16 cw_size; /* cw size */ u16 threshold; /* cw size threshold */ u8 escape_char; /* escape char value */ int max_string; /* max string length */ int dict_size; /* dictionary size */ struct dict { u8 ch; u16 parent; u16 child; u16 next; } *dict; /* dictionary */ /* fixme: union may be used? */ int bit_len; u32 bit_data; int flushed_len; /* string length already sent */ int str_len; /* string length */ u8 str_data[COMP_MAX_STRING]; /* test statistics info : encoder only */ u16 cmp_last; /* compressed bits per last TEST_SLICE chars */ u32 cmp_bits; /* total compressed bits */ u32 raw_bits; /* total non-compressed bits */ /* temporary */ int olen; int ohead; char obuf[1024]; }; extern int modem_comp_init(struct modem *m); extern int modem_comp_config(struct modem *m, int dict_size, int max_str); extern void modem_comp_exit(struct modem *m); extern int modem_comp_encode(struct modem *m, u8 ch, char *buf, int n); extern int modem_comp_decode(struct modem *m, u8 ch, char *buf, int n); extern int modem_comp_flush_encoder(struct modem *m, char *buf, int n); extern int modem_comp_flush_decoder(struct modem *m, char *buf, int n); /* * * HDLC definitions * */ typedef struct hdlc_frame { struct hdlc_frame *next; int count; int size; //u16 addr; //u16 ctrl; u16 fcs; u8 *buf; } frame_t; /* * LAPM definitions * */ #define LAPM_MAX_WIN_SIZE 15 /* max supported winsize */ #define LAPM_MAX_INFO_SIZE 128 /* max supported infosize */ #define LAPM_INFO_FRAMES LAPM_MAX_WIN_SIZE + 1 /* number of info frames */ #define LAPM_CTRL_FRAMES 8 /* number of ctrl frames */ /* lapm state */ struct lapm_state { /* modem link */ struct modem *modem; int state; /* sub-states: may be optimized */ int config; /* those DATA sub-states may be optimized */ int reject; int busy; int peer_busy; u8 cmd_addr; u8 rsp_addr; u8 vs; u8 va; u8 vr; int rtx_count; /* retransmission counter () */ unsigned int tx_win_size; unsigned int rx_win_size; unsigned int tx_info_size; unsigned int rx_info_size; frame_t *sent_info; frame_t *tx_info; frame_t *info_list; frame_t *tx_ctrl; frame_t *ctrl_list; /* temporary: internal buffs */ /* rx buf (used when enter busy state) */ int rx_count; int rx_head; u8 rx_buf[LAPM_MAX_INFO_SIZE]; /* temporary: frames bufs */ struct { frame_t frame; u8 ctrl[4]; u8 info[LAPM_MAX_INFO_SIZE]; } info_buf[LAPM_INFO_FRAMES]; struct { frame_t frame; u8 ctrl[4]; u8 info[LAPM_MAX_INFO_SIZE]; } ctrl_buf[LAPM_CTRL_FRAMES]; /* temporary: debug counters: remove it */ int info_count; // debug int tx_count; // debug int sent_count; // debug int ctrl_count; // debug }; /* modem struct */ struct modem { const char *name; int pty; /* pty descriptor */ const char *dev_name, *pty_name; /* and names */ struct termios termios; /* device driver */ struct modem_driver driver; void *dev_data; /* modem states */ unsigned modem_info; unsigned state; unsigned started; unsigned command; unsigned result_code; unsigned hook; unsigned caller; unsigned rx_rate; unsigned tx_rate; enum MODEM_MODE mode; /* data,fax,voice */ /* modem events (ring,escape,waiting for connect,etc) */ unsigned event; unsigned new_event; struct timer event_timer; /* modem parameters */ unsigned min_rate; unsigned max_rate; unsigned char sregs[256]; /* s-registers */ const struct homolog_set *homolog; /* homologation parameters */ /* at processor */ unsigned int at_count; char at_line[64]; char at_cmd[64]; /* ring detector */ unsigned int ring_count; unsigned long ring_first; unsigned long ring_last; #ifdef MODEM_CONFIG_RING_DETECTOR void *rd_obj; #endif /* cid */ #ifdef MODEM_CONFIG_CID unsigned cid_requested; void *cid; #endif /* dialer */ char dial_string[128]; /* escape counter */ unsigned escape_count; unsigned long last_esc_check; /* xmit queue */ struct xmit_queue { int count; unsigned int head; unsigned int tail; unsigned int size; unsigned char *buf; } xmit; /* run time configuration */ struct modem_config { /* ec params */ u8 ec; u8 ec_detector; u8 ec_tx_win_size; u8 ec_rx_win_size; u16 ec_tx_info_size; u16 ec_rx_info_size; /* compressor params */ u8 comp; int comp_dict_size; int comp_max_string; } cfg; /* modem packer */ int (*get_chars)(struct modem *m, char *buf, int n); int (*put_chars)(struct modem *m, const char *buf, int n); //int tx_window; //int rx_window; int bit_timer; void (*bit_timer_func)(struct modem *m); void (*packer_process)(struct modem *m, int bits); struct bits_state { int bit; u32 data; } pack,unpack; int (*get_bits)(struct modem *m, int nbits, u8 *buf, int n); int (*put_bits)(struct modem *m, int nbits, u8 *buf, int n); union packer_union { struct async_state { struct packer *packer; int data_bits; int stop_bits; int parity; int char_size; } async; struct detect_state { int tx_count; u8 tx_pattern[2]; int rx_count; u8 rx_pattern[2]; int ec_enable; } detector; struct hdlc_state { struct hdlc_frame *tx_frame; struct hdlc_frame *rx_frame; int rx_error; int rx_ones,tx_ones; /* framer interface */ struct hdlc_frame *(*get_tx_frame)(void *framer); void (*tx_complete)(void *framer, frame_t *fr); void (*rx_complete)(void *framer, frame_t *fr); void *framer; /* temporary: internal bufs */ struct hdlc_frame _rx_frame; u8 _rx_buf[512]; } hdlc; } packer; /* error corrector */ union { struct lapm_state lapm; } ec; /* compressor */ struct comp_struct { // fixme: redo interface int head,count; char buf[256]; struct comp_state encoder; struct comp_state decoder; } comp; /* modem data pump interface */ unsigned srate; unsigned format; unsigned frag; unsigned dp_requested; unsigned automode_requested; int update_delay; void (*process)(struct modem *m,void *in,void *out,int cnt); /* process counter and sample timer */ unsigned long count; unsigned long sample_timer; void (*sample_timer_func)(struct modem *); /* data pump */ struct dp_operations **dp_ops; struct dp *dp; void *dp_runtime; /* dc evaluator and cleaner */ void *dcr; /* dsp info data */ struct dsp_info dsp_info; /* voice info */ #ifdef MODEM_CONFIG_VOICE void *voice_obj; struct voice_info voice_info; #endif #ifdef MODEM_CONFIG_FAX void *fax_obj; #endif }; /* * prototypes * */ /* device driver --> modem */ extern struct modem *modem_create(struct modem_driver *drv, const char *dev_name); extern void modem_delete(struct modem *m); extern int modem_write(struct modem *m, const char *buf, int n); extern void modem_hangup(struct modem *m); extern void modem_update_termios(struct modem *m, struct termios *tios); extern void modem_error (struct modem *m); extern void modem_ring (struct modem *m); extern void modem_event (struct modem *m); extern void modem_process(struct modem *m,void *in,void *out,int cnt); /* packers && EC */ // FIXME: improve interface extern void modem_async_start(struct modem *m); extern int modem_async_get_bits(struct modem *m,int nbits,u8 *buf,int cnt); extern int modem_async_put_bits(struct modem *m,int nbits,u8 *buf,int cnt); extern void modem_detector_start(struct modem *m); extern int modem_detector_get_bits(struct modem *m,int nbits,u8 *buf,int cnt); extern int modem_detector_put_bits(struct modem *m,int nbits,u8 *buf,int cnt); extern void modem_hdlc_start(struct modem *m); extern int modem_hdlc_get_bits(struct modem *m,int nbits,u8 *buf,int cnt); extern int modem_hdlc_put_bits(struct modem *m,int nbits,u8 *buf,int cnt); extern int modem_ec_init(struct modem *m); extern void modem_ec_exit(struct modem *m); extern void modem_ec_start(struct modem *m); extern void modem_ec_stop(struct modem *m); /* status & config */ extern void modem_update_status(struct modem *m, unsigned status); extern void modem_update_config(struct modem *m, struct modem_config *cfg); /* modem parameters access macros */ #define CRLF_CHARS(m) ((char *)((m)->sregs+SREG_CR_CHAR)) #define MODEM_DP(m) ((m)->sregs[SREG_DP]) #define MODEM_AUTOMODE(m) ((m)->sregs[SREG_AUTOMODE]) #endif /* __MODEM_H__ */