osmocom-analog/src/amps/amps.h

187 lines
8.8 KiB
C

#include <libgoertzel/goertzel.h>
#include <libmobile/sender.h>
#include <libtimer/timer.h>
#include <libcompandor/compandor.h>
typedef struct amps amps_t;
#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 (FVC with dotting+sync) */
struct amps {
sender_t sender;
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 amps_chan_type chan_type;
enum amps_state state;
int channel_busy; /* indicate channel is busy while receiving */
/* display measurements */
dispmeasparam_t *dmp_frame_level;
dispmeasparam_t *dmp_frame_quality;
dispmeasparam_t *dmp_sat_level;
dispmeasparam_t *dmp_sat_quality;
/* 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 */
double fsk_deviation; /* deviation of FSK signal on sound card */
sample_t fsk_ramp_up[256]; /* samples of upward ramp shape */
sample_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 */
char fsk_tx_frame[FSK_MAX_BITS + 1]; /* +1 because 0-termination */
int fsk_tx_frame_pos; /* current position sending bits */
sample_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 */
sample_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 */
int fsk_rx_sync_tolerant; /* be more tolerant to sync */
/* the dotting buffer stores the elapsed samples, so we can calculate
* an average time of zero-crossings during dotting sequence.
* this buffer wrpps 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 wraps every
* bit. */
double fsk_rx_bitcount; /* counts the bit. if it reaches or exceeds 1, the bit is complete and the next bit starts */
sample_t *fsk_rx_window; /* rx buffer for one bit */
int fsk_rx_window_length; /* length of rx buffer */
int fsk_rx_window_half; /* half of length of rx buffer */
int fsk_rx_window_begin; /* where to begin detecting level */
int fsk_rx_window_end; /* where to end detecting level */
int fsk_rx_window_pos; /* current position in buffer */
/* the rx buffer 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_nawc; /* counts down received words */
int rx_recc_word_count; /* counts up 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;
uint8_t rx_recc_mpci;
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 information */
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 multi word message */
int tx_focc_word_repeat; /* counts repeats of multi 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 */
goertzel_t sat_goertzel[5]; /* filter for SAT signal decoding */
sample_t *sat_filter_spl; /* array with sample buffer for supervisory detection */
int sat_filter_pos; /* current sample position in filter_spl */
double sat_phaseshift65536[3]; /* how much the phase of sine wave changes per sample */
double sat_phase65536; /* current phase */
int sat_print; /* counts when to print result */
int dtx_state; /* 1 = high (fast sat detection) */
int sat_detected; /* current detection state flag (delayed detection) */
int sat_detect_count; /* current number of consecutive detections/losses */
int sig_detected; /* current detection state flag (delayed detection) */
int sig_detect_count; /* current number of consecutive detections/losses */
transaction_t *trans_list; /* list of transactions */
/* delay measurement in loopback mode */
double when_received; /* time stamp of received frame start (start of dotting) */
double when_transmitted[16]; /* time stamps of filler frames with different count */
int when_count; /* counter of the filler frame */
};
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);
const 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(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_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, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int tolerant, int loopback);
void amps_destroy(sender_t *sender);
void amps_go_idle(amps_t *amps);
void amps_rx_signaling_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, uint8_t mpci, 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);
void amps_display_status();