osmocom-analog/src/amps/amps.h

161 lines
7.5 KiB
C

#include "../common/sender.h"
#include "../common/compander.h"
#include "sysinfo.h"
#include "transaction.h"
enum dsp_mode {
DSP_MODE_OFF, /* channel not active (VC) */
DSP_MODE_AUDIO_RX_AUDIO_TX, /* stream audio */
DSP_MODE_AUDIO_RX_FRAME_TX, /* stream audio, send frames */
DSP_MODE_FRAME_RX_FRAME_TX, /* send and decode frames */
};
enum amps_chan_type {
CHAN_TYPE_CC, /* control channel */
CHAN_TYPE_PC, /* paging channel */
CHAN_TYPE_CC_PC, /* combined CC + PC */
CHAN_TYPE_VC, /* voice channel */
CHAN_TYPE_CC_PC_VC, /* combined CC + PC + TC */
};
enum amps_state {
STATE_NULL, /* power off state */
STATE_IDLE, /* channel is not in use */
STATE_BUSY, /* channel busy (call) */
};
enum fsk_rx_sync {
FSK_SYNC_NONE, /* we are not in sync and wait for valid dotting sequence */
FSK_SYNC_DOTTING, /* we received a valid dotting sequence and check for sync sequence */
FSK_SYNC_POSITIVE, /* we have valid sync and read all the bits of the frame */
FSK_SYNC_NEGATIVE, /* as above, but negative sync (high frequency deviation detected as low signal) */
};
#define FSK_MAX_BITS 1032 /* maximum number of bits to process */
typedef struct amps {
sender_t sender;
compander_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 amps_chan_type chan_type;
enum amps_state state;
int page_retry; /* current number of paging (re)try */
/* system info */
amps_si si;
/* cell nr selection */
int cell_auto; /* if set, cell_nr is selected automatically */
/* dsp states */
enum dsp_mode dsp_mode; /* current mode: audio, durable tone 0 or 1, paging */
int flip_polarity; /* 1 = flip */
int16_t fsk_deviation; /* deviation of FSK signal on sound card */
int16_t fsk_ramp_up[256]; /* samples of upward ramp shape */
int16_t fsk_ramp_down[256]; /* samples of downward ramp shape */
double fsk_bitduration; /* duration of one bit in samples */
double fsk_bitstep; /* fraction of one bit each sample */
/* tx bits generation */
int16_t *fsk_tx_buffer; /* tx buffer for one data block */
int fsk_tx_buffer_size; /* size of tx buffer (in samples) */
int fsk_tx_buffer_length; /* usage of buffer (in samples) */
int fsk_tx_buffer_pos; /* current position sending buffer */
double fsk_tx_phase; /* current bit position */
char fsk_tx_last_bit; /* save last bit of frame (for next frame's ramp) */
/* high-pass filter to remove DC offset from RX signal */
double highpass_factor; /* high pass filter factor */
double highpass_x_last; /* last input value */
double highpass_y_last; /* last output value */
/* rx detection of bits and sync */
int16_t fsk_rx_last_sample; /* last sample (for level change detection) */
double fsk_rx_elapsed; /* bit duration since last level change */
enum fsk_rx_sync fsk_rx_sync; /* sync state */
uint16_t fsk_rx_sync_register; /* shift register to detect sync word */
/* the dotting buffer stores the elapsed samples, so we can calculate
* an average time of zero-crossings during dotting sequence.
* this buffer wrapps every 256 values */
double fsk_rx_dotting_elapsed[256]; /* dotting buffer with elapsed samples since last zero-crossing */
uint8_t fsk_rx_dotting_pos; /* position of next value in dotting buffer */
int fsk_rx_dotting_life; /* counter to expire when no sync was found after dotting */
double fsk_rx_dotting_average; /* last average slope position of dotting sequnece. */
/* the ex buffer holds the duration of one bit, and wrapps every
* bit. */
double fsk_rx_bitcount; /* counts the bit. if it reaches or exceeds 1, the bit is complete and the next bit starts */
int16_t *fsk_rx_buffer; /* rx buffer for one bit */
int fsk_rx_buffer_length; /* length of rx buffer */
int fsk_rx_buffer_pos; /* current position in buffer */
/* the rx bufffer received one frame until rx length */
char fsk_rx_frame[FSK_MAX_BITS + 1]; /* +1 because 0-termination */
int fsk_rx_frame_length; /* length of expected frame */
int fsk_rx_frame_count; /* count number of received bit */
double fsk_rx_frame_level; /* sum of level of all bits */
double fsk_rx_frame_quality; /* sum of quality of all bits */
/* RECC frame states */
int rx_recc_word_count; /* counts received words */
uint32_t rx_recc_min1; /* mobile id */
uint16_t rx_recc_min2;
uint8_t rx_recc_msg_type; /* message (3 values) */
uint8_t rx_recc_ordq;
uint8_t rx_recc_order;
uint32_t rx_recc_esn;
uint32_t rx_recc_scm;
char rx_recc_dialing[33]; /* received dial string */
/* FOCC frame states */
int rx_focc_word_count; /* counts received words */
int tx_focc_frame_count; /* used to schedule system informations */
int tx_focc_send; /* if set, send message words */
uint32_t tx_focc_min1; /* mobile id */
uint16_t tx_focc_min2;
int tx_focc_chan; /* channel to assign for voice call */
uint8_t tx_focc_msg_type; /* message (3 values) */
uint8_t tx_focc_ordq;
uint8_t tx_focc_order;
int tx_focc_word_count; /* counts transmitted words in a muli word message */
int tx_focc_word_repeat; /* countrs repeats of mulit word message */
/* FVC frame states */
int tx_fvc_send; /* if set, send message words */
int tx_fvc_chan; /* channel to assign for voice call */
uint8_t tx_fvc_msg_type; /* message (3 values) */
uint8_t tx_fvc_ordq;
uint8_t tx_fvc_order;
/* SAT tone */
int sat; /* use SAT tone 0..2 */
int sat_samples; /* number of samples in buffer for supervisory detection */
int sat_coeff[5]; /* coefficient for SAT signal decoding */
int16_t *sat_filter_spl; /* array with sample buffer for supervisory detection */
int sat_filter_pos; /* current sample position in filter_spl */
double sat_phaseshift256[3]; /* how much the phase of sine wave changes per sample */
double sat_phase256; /* current phase */
int sat_detected; /* current detection state flag */
int sat_detect_count; /* current number of consecutive detections/losses */
int sig_detected; /* current detection state flag */
int sig_detect_count; /* current number of consecutive detections/losses */
transaction_t *trans_list; /* list of transactions */
} amps_t;
void amps_channel_list(void);
int amps_channel_by_short_name(const char *short_name);
const char *chan_type_short_name(enum amps_chan_type chan_type);
const char *chan_type_long_name(enum amps_chan_type chan_type);
double amps_channel2freq(int channel, int uplink);
enum amps_chan_type amps_channel2type(int channel);
char amps_channel2band(int channel);
const char *amps_min22number(uint16_t min2);
const char *amps_min12number(uint32_t min1);
void amps_number2min(const char *number, uint32_t *min1, uint16_t *min2);
const char *amps_min2number(uint32_t min1, uint16_t min2);
const char *amps_scm(uint8_t scm);
int amps_create(int channel, enum amps_chan_type chan_type, const char *sounddev, int samplerate, int cross_channels, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_wave, const char *read_wave, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int loopback);
void amps_destroy(sender_t *sender);
void amps_rx_signalling_tone(amps_t *amps, int tone, double quality);
void amps_rx_sat(amps_t *amps, int tone, double quality);
void amps_rx_recc(amps_t *amps, uint8_t scm, uint32_t esn, uint32_t min1, uint16_t min2, uint8_t msg_type, uint8_t ordq, uint8_t order, const char *dialing);
transaction_t *amps_tx_frame_focc(amps_t *amps);
transaction_t *amps_tx_frame_fvc(amps_t *amps);