#include "../common/compandor.h" #include "../common/sender.h" #include "../common/call.h" #include "../common/ffsk.h" enum dsp_mode { DSP_MODE_OFF, /* no transmission */ DSP_MODE_AUDIO_TX, /* stream audio (TX only) */ DSP_MODE_AUDIO_TX_RX, /* stream audio */ DSP_MODE_FRAME, /* send frames */ }; enum r2000_chan_type { CHAN_TYPE_CC, /* calling channel */ CHAN_TYPE_TC, /* traffic channel */ CHAN_TYPE_CC_TC, /* combined CC + TC */ }; enum r2000_state { STATE_NULL = 0, /* power off state */ STATE_IDLE, /* channel is not in use */ STATE_INSCRIPTION, /* SM registers */ STATE_OUT_ASSIGN, /* assign outgoing call on CC */ STATE_IN_ASSIGN, /* assign incomming call on CC */ STATE_RECALL_ASSIGN, /* assign outgoing recall on CC */ STATE_OUT_IDENT, /* identity outgoing call on TC */ STATE_IN_IDENT, /* identity incomming call on TC */ STATE_RECALL_IDENT, /* identity outgoing recall on TC */ STATE_OUT_DIAL1, /* dialing outgoing call on TC */ STATE_OUT_DIAL2, /* dialing outgoing call on TC */ STATE_SUSPEND, /* suspend after dialing outgoing call on TC */ STATE_RECALL_WAIT, /* wait for calling back the phone */ STATE_IN_ALERT, /* alerting incomming call on TC */ STATE_OUT_ALERT, /* alerting outgoing call on TC */ STATE_RECALL_ALERT, /* alerting outgoing recall on TC */ STATE_ACTIVE, /* channel is in use */ STATE_RELEASE_CC, /* release call on CC */ STATE_RELEASE_TC, /* release call on TC */ }; typedef struct r2000_subscriber { uint8_t type; /* mobile station type */ uint16_t relais; /* home relais */ uint16_t mor; /* mobile ID */ char dialing[21]; /* dial string */ } r2000_subscriber_t; typedef struct r2000_sysinfo { enum r2000_chan_type chan_type; /* channel type */ uint8_t deport; /* sub-station number */ uint8_t agi; /* inscription parameter */ uint8_t sm_power; /* station mobile power 1 = high */ uint8_t taxe; /* rate parameter */ uint16_t relais; /* relais ID */ uint8_t crins; /* response to inscription */ uint8_t nconv; /* supervisory value */ int recall; /* do a recall when called party answered */ } r2000_sysinfo_t; typedef struct r2000 { sender_t sender; r2000_sysinfo_t sysinfo; compandor_t cstate; int pre_emphasis; /* use pre_emphasis by this instance */ int de_emphasis; /* use de_emphasis by this instance */ emphasis_t estate; /* sender's states */ enum r2000_state state; int callref; struct timer timer; r2000_subscriber_t subscriber; int page_try; /* the try number of calling the mobile */ int tx_frame_count; /* to count repeated frames */ /* features */ int compandor; /* if compandor shall be used */ /* dsp states */ enum dsp_mode dsp_mode; /* current mode: audio, durable tone 0 or 1, paging */ ffsk_t ffsk; /* ffsk processing */ uint16_t rx_sync; /* shift register to detect sync */ int rx_in_sync; /* if we are in sync and receive bits */ int rx_mute; /* mute count down after sync */ int rx_max; /* maximum bits to receive (including 32 bits sync sequence) */ char rx_frame[177]; /* receive frame (one extra byte to terminate string) */ int rx_count; /* next bit to receive */ double rx_level[256]; /* level infos */ double rx_quality[256]; /* quality infos */ sample_t *frame_spl; /* samples to store a complete rendered frame */ int frame_size; /* total size of sample buffer */ int frame_length; /* current length of data in sample buffer */ int frame_pos; /* current sample position in frame_spl */ uint64_t rx_bits_count; /* sample counter */ uint64_t rx_bits_count_current; /* sample counter of current frame */ uint64_t rx_bits_count_last; /* sample counter of last frame */ /* supervisory dsp states */ goertzel_t super_goertzel[2]; /* filter for fsk decoding */ int super_samples_per_window;/* how many samples to analyze in one window */ sample_t *super_filter_spl; /* array with samples_per_bit */ int super_filter_pos; /* current sample position in filter_spl */ int super_filter_step; /* number of samples for each analyzation */ int super_filter_bit; /* last bit, so we detect a bit change */ int super_filter_sample; /* count until it is time to sample bit */ sample_t *super_spl; /* samples to store a complete rendered frame */ int super_size; /* total size of sample buffer */ int super_length; /* current length of data in sample buffer */ int super_pos; /* current sample position in frame_spl */ double super_phaseshift65536[2];/* how much the phase of sine wave changes per sample */ double super_phase65536; /* current phase */ uint32_t super_rx_word; /* shift register for received supervisory info */ double super_rx_level[20]; /* level infos */ double super_rx_quality[20]; /* quality infos */ int super_rx_index; /* index for level and quality buffer */ uint32_t super_tx_word; /* supervisory info to transmit */ double super_bittime; double super_bitpos; } r2000_t; void r2000_channel_list(void); int r2000_channel_by_short_name(const char *short_name); const char *chan_type_short_name(enum r2000_chan_type chan_type); const char *chan_type_long_name(enum r2000_chan_type chan_type); int r2000_create(int band, int channel, enum r2000_chan_type chan_type, const char *audiodev, int use_sdr, int samplerate, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, uint16_t relais, uint8_t deport, uint8_t agi, uint8_t sm_power, uint8_t taxe, uint8_t crins, int destruction, uint8_t nconv, int recall, int loopback); void r2000_check_channels(void); void r2000_destroy(sender_t *sender); void r2000_go_idle(r2000_t *r2000); void r2000_band_list(void); double r2000_channel2freq(int band, int channel, int uplink); const char *r2000_get_frame(r2000_t *r2000); void r2000_receive_frame(r2000_t *r2000, const char *bits, double quality, double level); void r2000_receive_super(r2000_t *r2000, uint8_t super, double quality, double level);