aboutsummaryrefslogtreecommitdiffstats
path: root/src/nmt/nmt.h
blob: 4d472d284eeb7e12bddde8dae6b981b4ba9cbca6 (plain)
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 "../common/call.h"
#include "../common/fsk.h"
#include "../common/goertzel.h"
#include "dms.h"
#include "sms.h"


enum dsp_mode {
	DSP_MODE_SILENCE,	/* stream nothing */
	DSP_MODE_DIALTONE,	/* stream dial tone to mobile phone */
	DSP_MODE_AUDIO,		/* stream audio */
	DSP_MODE_FRAME,		/* send frames */
	DSP_MODE_DTMF,		/* send DTMF tones */
};

enum nmt_chan_type {
	CHAN_TYPE_CC,		/* calling channel */
	CHAN_TYPE_CCA,		/* calling channel type A mobiles */
	CHAN_TYPE_CCB,		/* calling channel type B mobiles */
	CHAN_TYPE_TC,		/* traffic channel */
	CHAN_TYPE_AC_TC,	/* combined AC + TC */
	CHAN_TYPE_CC_TC,	/* combined CC + TC */
	CHAN_TYPE_TEST,		/* test channel */
};

enum nmt_state {
	STATE_NULL = 0,		/* 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_AUTOANSWER,	/* sending autoanswer, waiting for reply */
	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 {
	int			system;			/* 450 or 900 */
	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;

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;
	struct transaction	*trans;			/* pointer to transaction, if bound to channel */

	/* sender's states */
	enum nmt_state		state;
	int			wait_autoanswer;	/* wait for frame 15 before we can send autoanswer */
	enum nmt_active_state	active_state;
	struct timer		timer;
	int			rx_frame_count;		/* receive frame counter */
	int			tx_frame_count;		/* transmit frame counter */
	int			tx_callerid_count;	/* counter for caller ID repetition */
	char			dialing[33];		/* dialed digits */
	int			mft_num;		/* counter for digit for MFT */

	/* display measurements */
	dispmeasparam_t		*dmp_frame_level;
	dispmeasparam_t		*dmp_frame_quality;

	/* features */
	int			compandor;		/* if compandor shall be used */
	int			supervisory;		/* if set, use supervisory signal 1..4 */
	int			send_callerid;		/* if set, send caller ID while ringing the phone */

	/* dsp states */
	enum dsp_mode		dsp_mode;		/* current mode: audio, durable tone 0 or 1, paging */
	fsk_t			fsk;			/* fsk processing */
	int			super_samples;		/* number of samples in buffer for supervisory detection */
	goertzel_t		super_goertzel[5];	/* filter for supervisory decoding */
	sample_t		*super_filter_spl;	/* array with sample buffer for supervisory detection */
	int			super_filter_pos;	/* current sample position in filter_spl */
	double			super_phaseshift65536[4];/* how much the phase of sine wave changes per sample */
	double			super_phase65536;	/* current phase */
	double			dial_phaseshift65536;	/* how much the phase of sine wave changes per sample */
	double			dial_phase65536;	/* current phase */
	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 */
	char			rx_frame[141];		/* 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 */
	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 */
	int			super_detected;		/* current detection state flag */
	int			super_detect_count;	/* current number of consecutive detections/losses */
	char			tx_frame[166];		/* carries bits of one frame to transmit */
	int			tx_frame_length;
	int			tx_frame_pos;

	/* DMS/SMS states */
	dms_t			dms;			/* DMS states */
	int			dms_call;		/* indicates that this call is a DMS call */
	sms_t			sms;			/* SMS states */
	char			smsc_number[33];	/* digits to match SMSC */
	struct timer		sms_timer;
} nmt_t;

void nmt_channel_list(int nmt_system);
int nmt_channel_by_short_name(int nmt_system, const char *short_name);
const char *chan_type_short_name(int nmt_system, enum nmt_chan_type chan_type);
const char *chan_type_long_name(int nmt_system, enum nmt_chan_type chan_type);
int nmt_create(int nmt_system, const char *country, int channel, enum nmt_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, uint8_t ms_power, uint8_t traffic_area, uint8_t area_no, int compandor, int supervisory, const char *smsc_number, int send_callerid, int loopback);
void nmt_check_channels(int nmt_system);
void nmt_destroy(sender_t *sender);
void nmt_go_idle(nmt_t *nmt);
void nmt_receive_frame(nmt_t *nmt, const char *bits, double quality, double level, int frames_elapsed);
const char *nmt_get_frame(nmt_t *nmt);
void nmt_rx_super(nmt_t *nmt, int tone, double quality);
void timeout_mt_paging(struct transaction *trans);
void deliver_sms(const char *sms);
int submit_sms(const char *sms);