1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#include "../common/sender.h"
#include "../common/compandor.h"
#include "../common/dtmf.h"
#include "dms.h"
enum dsp_mode {
DSP_MODE_DIALTONE, /* stream dial tone to mobile phone */
DSP_MODE_AUDIO, /* stream audio */
DSP_MODE_SILENCE, /* stream nothing */
DSP_MODE_FRAME, /* send frames */
DSP_MODE_DTMF, /* send DTMF tones */
};
enum nmt_chan_type {
CHAN_TYPE_CC, /* calling channel */
CHAN_TYPE_TC, /* traffic channel */
CHAN_TYPE_CC_TC, /* combined CC + TC */
CHAN_TYPE_TEST, /* test channel */
};
enum nmt_state {
STATE_NULL, /* power off state */
STATE_IDLE, /* channel is not in use */
STATE_ROAMING_IDENT, /* seizure received, waiting for identity */
STATE_ROAMING_CONFIRM, /* identity received, sending confirm */
STATE_MO_IDENT, /* seizure of mobile originated call, waiting for identity */
STATE_MO_CONFIRM, /* identity received, sending confirm */
STATE_MO_DIALING, /* receiving digits from phone */
STATE_MO_COMPLETE, /* all digits received, completing call */
STATE_MT_PAGING, /* paging mobile phone */
STATE_MT_CHANNEL, /* assigning traffic channel */
STATE_MT_IDENT, /* waiting for identity */
STATE_MT_RINGING, /* mobile phone is ringing, waiting for answer */
STATE_MT_COMPLETE, /* mobile phone has answered, completing call */
STATE_ACTIVE, /* during active call */
STATE_MO_RELEASE, /* acknowlegde release from mobile phone */
STATE_MT_RELEASE, /* sending release toward mobile phone */
};
enum nmt_active_state {
ACTIVE_STATE_VOICE, /* normal conversation */
ACTIVE_STATE_MFT_IN, /* ack MFT converter in */
ACTIVE_STATE_MFT, /* receive digits in MFT mode */
ACTIVE_STATE_MFT_OUT, /* ack MFT converter out */
};
enum nmt_direction {
MTX_TO_MS,
MTX_TO_BS,
MTX_TO_XX,
BS_TO_MTX,
MS_TO_MTX,
XX_TO_MTX,
};
typedef struct nmt_sysinfo {
enum nmt_chan_type chan_type; /* channel type */
int ms_power; /* ms power level 3 = full */
uint8_t traffic_area; /* two digits traffic area, encoded as YY */
uint8_t area_no; /* Area no. 1..4, 0 = no Area no. */
} nmt_sysinfo_t;
typedef struct nmt_subscriber {
/* NOTE: country must be followed by number, so both represent a string */
char country; /* country digit */
char number[7]; /* phone suffix */
char password[4]; /* phone's password + '\0' */
int coinbox; /* phone is a coinbox and accept tariff information */
} nmt_subscriber_t;
const char *nmt_dir_name(enum nmt_direction dir);
typedef struct nmt {
sender_t sender;
nmt_sysinfo_t sysinfo;
compandor_t cstate;
dtmf_t dtmf;
/* sender's states */
enum nmt_state state;
enum nmt_active_state active_state;
nmt_subscriber_t subscriber; /* current subscriber */
struct timer timer;
int rx_frame_count; /* receive frame counter */
int tx_frame_count; /* transmit frame counter */
char dialing[33]; /* dialed digits */
int page_try; /* number of paging try */
int mft_num; /* counter for digit for MFT */
/* special state for paging on different CC */
struct nmt *page_for_nmt; /* only page and assign channel for nmt instance as set */
int mt_channel; /* channel to use */
/* features */
int compandor; /* if compandor shall be used */
int supervisory; /* if set, use supervisory signal 1..4 */
/* dsp states */
enum dsp_mode dsp_mode; /* current mode: audio, durable tone 0 or 1, paging */
int samples_per_bit; /* number of samples for one bit (1200 Baud) */
int super_samples; /* number of samples in buffer for supervisory detection */
int fsk_coeff[2]; /* coefficient k = 2*cos(2*PI*f/samplerate), k << 15 */
int super_coeff[5]; /* coefficient for supervisory signal */
int16_t *fsk_sine[2][2]; /* 4 pointers to 4 precalc. sine curves */
int fsk_polarity; /* current polarity state of bit */
int samples_per_chunk; /* how many samples lasts one chunk */
int16_t *fsk_filter_spl; /* array with samples_per_chunk */
int fsk_filter_pos; /* current sample position in filter_spl */
int fsk_filter_step; /* number of samples for each analyzation */
int fsk_filter_bit; /* last bit, so we detect a bit change */
int fsk_filter_sample; /* count until it is time to sample bit */
uint16_t fsk_filter_sync; /* shift register to detect sync */
int fsk_filter_in_sync; /* if we are in sync and receive bits */
int fsk_filter_mute; /* mute count down after sync */
char fsk_filter_frame[141]; /* receive frame (one extra byte to terminate string) */
int fsk_filter_count; /* next bit to receive */
double fsk_filter_level[256]; /* level infos */
double fsk_filter_quality[256];/* quality infos */
int16_t *super_filter_spl; /* array with sample buffer for supervisory detection */
int super_filter_pos; /* current sample position in filter_spl */
double super_phaseshift256[4]; /* how much the phase of sine wave changes per sample */
double super_phase256; /* current phase */
double dial_phaseshift256; /* how much the phase of sine wave changes per sample */
double dial_phase256; /* current phase */
int frame; /* set, if there is a valid frame */
int16_t *frame_spl; /* 166 * fsk_bit_length */
int frame_pos; /* current sample position in frame_spl */
uint64_t rx_sample_count; /* sample counter */
uint64_t rx_sample_count_current;/* sample counter of current frame */
uint64_t rx_sample_count_last; /* sample counter of last frame */
int super_detected; /* current detection state flag */
int super_detect_count; /* current number of consecutive detections/losses */
/* DMS states */
int dms_call; /* indicates that this call is a DMS call */
dms_t dms; /* DMS states */
} nmt_t;
void nmt_channel_list(void);
int nmt_channel_by_short_name(const char *short_name);
const char *chan_type_short_name(enum nmt_chan_type chan_type);
const char *chan_type_long_name(enum nmt_chan_type chan_type);
double nmt_channel2freq(int channel, int uplink);
void nmt_country_list(void);
uint8_t nmt_country_by_short_name(const char *short_name);
int nmt_create(int channel, enum nmt_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, uint8_t ms_power, uint8_t traffic_area, uint8_t area_no, int compandor, int supervisory, int loopback);
void nmt_destroy(sender_t *sender);
void nmt_receive_frame(nmt_t *nmt, const char *bits, double quality, double level, double frames_elapsed);
const char *nmt_get_frame(nmt_t *nmt);
void nmt_rx_super(nmt_t *nmt, int tone, double quality);
|