Implementation of Advanced Mobile Phone Service (AMPS)
This commit is contained in:
parent
7d5d3da8d3
commit
d2c4ca4fa9
|
@ -24,5 +24,6 @@ src/anetz/anetz
|
|||
src/bnetz/bnetz
|
||||
src/cnetz/cnetz
|
||||
src/nmt/nmt
|
||||
src/amps/amps
|
||||
src/test/test_compander
|
||||
src/test/test_emphasis
|
||||
|
|
1
README
1
README
|
@ -7,6 +7,7 @@ and from mobile phone. Currently supported networks:
|
|||
* B-Netz (ATF-1)
|
||||
* C-Netz
|
||||
* NMT 450 (Nordic Mobile Telephone)
|
||||
* AMPS (Advanced Mobile Phone System)
|
||||
|
||||
|
||||
USE AT YOUR OWN RISK!
|
||||
|
|
|
@ -33,6 +33,7 @@ AC_OUTPUT(
|
|||
src/bnetz/Makefile
|
||||
src/cnetz/Makefile
|
||||
src/nmt/Makefile
|
||||
src/amps/Makefile
|
||||
src/test/Makefile
|
||||
src/Makefile
|
||||
Makefile)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = common anetz bnetz cnetz nmt test
|
||||
SUBDIRS = common anetz bnetz cnetz nmt amps test
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
AM_CPPFLAGS = -Wall -g $(all_includes)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
amps
|
||||
|
||||
amps_SOURCES = \
|
||||
amps.c \
|
||||
transaction.c \
|
||||
frame.c \
|
||||
dsp.c \
|
||||
sysinfo.c \
|
||||
image.c \
|
||||
tones.c \
|
||||
noanswer.c \
|
||||
outoforder.c \
|
||||
invalidnumber.c \
|
||||
congestion.c \
|
||||
stations.c \
|
||||
main.c
|
||||
amps_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/common/libcommon.a \
|
||||
$(ALSA_LIBS) \
|
||||
-lm
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,160 @@
|
|||
#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);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
|
||||
void init_congestion(void);
|
||||
|
|
@ -0,0 +1,866 @@
|
|||
/* AMPS audio processing
|
||||
*
|
||||
* (C) 2016 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* How does FSK decoding work:
|
||||
* ---------------------------
|
||||
*
|
||||
* AMPS modulates the carrier frequency. If it is 8 kHz above, it is high level,
|
||||
* if it is 8 kHz below, it is low level. The bits are coded using Manchester
|
||||
* code. A 1 is coded by low level, followed by a hight level. A 0 is coded by
|
||||
* a high level, followed by a low level. This will cause at least one level
|
||||
* change within each bit. Also the level changes between equal bits, see
|
||||
* Manchester coding. The bit rate is 10 KHz.
|
||||
*
|
||||
* In order to detect and demodulate a frame, the dotting sequnce is searched.
|
||||
* The dotting sequnece are alternate bits: 101010101... The duration of a
|
||||
* level change within the dotting sequnene ist 100uS. If all offsets of 8
|
||||
* level changes lay within +-50% of the expected time, the dotting sequence is
|
||||
* valid. Now the next 12 bits will be searched for sync sequnece. If better
|
||||
* dotting-offsets are found, the counter for searching the sync sequence is
|
||||
* reset, so the next 12 bits will be searched for sync too. If no sync was
|
||||
* detected, the state changes to search for next dotting sequence.
|
||||
*
|
||||
* The average level change offsets of the dotting sequence is used to set the
|
||||
* window for the first bit. When all samples for the window are received, a
|
||||
* raise in level is detected as 1, fall in level is detected as 0. This is done
|
||||
* by substracting the average sample value of the left side of the window by
|
||||
* the average sample value of the right side. After the bit has been detected,
|
||||
* the samples for the next window will be received and detected.
|
||||
*
|
||||
* As soon as a sync pattern is detected, the polarity of the pattern is used
|
||||
* to decode the following frame bits with correct polarity. During reception
|
||||
* of the frame bits, no sync and no dotting sequnece is searched or detected.
|
||||
*
|
||||
* After reception of the bit, the bits are re-assembled, parity checked and
|
||||
* decoded. Then the process hunts for next dotting sequence.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/call.h"
|
||||
#include "../common/goertzel.h"
|
||||
#include "amps.h"
|
||||
#include "frame.h"
|
||||
#include "dsp.h"
|
||||
|
||||
/* uncomment this to debug the encoding process */
|
||||
//#define DEBUG_ENCODER
|
||||
|
||||
/* uncomment this to debug the decoding process */
|
||||
//#define DEBUG_DECODER
|
||||
|
||||
#define PI M_PI
|
||||
|
||||
#define FSK_DEVIATION 32767.0 /* +-8 KHz */
|
||||
#define SAT_DEVIATION 8192.0 /* +-2 KHz */
|
||||
#define TX_AUDIO_0dBm0 45000 /* works quite well */
|
||||
#define BITRATE 10000
|
||||
#define SIG_TONE_CROSSINGS 2000 /* 2000 crossings are 100ms @ 10 KHz */
|
||||
#define SIG_TONE_MINBITS 950 /* minimum bit durations to detect signalling tone (1000 is perfect for 100 ms) */
|
||||
#define SIG_TONE_MAXBITS 1050 /* as above, maximum bits */
|
||||
#define SAT_DURATION 0.100 /* duration of SAT signal measurement */
|
||||
#define SAT_QUALITY 0.85 /* quality needed to detect sat */
|
||||
#define SAT_DETECT_COUNT 3 /* number of measures to detect SAT signal */
|
||||
#define SAT_LOST_COUNT 3 /* number of measures to loose SAT signal */
|
||||
#define SIG_DETECT_COUNT 3 /* number of measures to detect Signalling Tone */
|
||||
#define SIG_LOST_COUNT 2 /* number of measures to loose Signalling Tone */
|
||||
#define CUT_OFF_HIGHPASS 300.0 /* cut off frequency for high pass filter to remove dc level from sound card / sample */
|
||||
#define BEST_QUALITY 0.68 /* Best possible RX quality */
|
||||
|
||||
static int16_t ramp_up[256], ramp_down[256];
|
||||
|
||||
static double sat_freq[5] = {
|
||||
5970.0,
|
||||
6000.0,
|
||||
6030.0,
|
||||
5800.0, /* noise level to check against */
|
||||
10000.0, /* signalling tone */
|
||||
};
|
||||
|
||||
static int dsp_sine_sat[256];
|
||||
|
||||
/* global init for FSK */
|
||||
void dsp_init(void)
|
||||
{
|
||||
int i;
|
||||
double s;
|
||||
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Generating sine table for SAT signal.\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
s = sin((double)i / 256.0 * 2.0 * PI);
|
||||
dsp_sine_sat[i] = (int)(s * SAT_DEVIATION);
|
||||
}
|
||||
}
|
||||
|
||||
static void dsp_init_ramp(amps_t *amps)
|
||||
{
|
||||
double c;
|
||||
int i;
|
||||
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Generating smooth ramp table.\n");
|
||||
for (i = 0; i < 256; i++) {
|
||||
c = cos((double)i / 256.0 * PI);
|
||||
#if 0
|
||||
if (c < 0)
|
||||
c = -sqrt(-c);
|
||||
else
|
||||
c = sqrt(c);
|
||||
#endif
|
||||
ramp_down[i] = (int)(c * (double)amps->fsk_deviation);
|
||||
ramp_up[i] = -ramp_down[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void sat_reset(amps_t *amps, const char *reason);
|
||||
|
||||
/* Init FSK of transceiver */
|
||||
int dsp_init_sender(amps_t *amps, int high_pass)
|
||||
{
|
||||
double coeff;
|
||||
int16_t *spl;
|
||||
int i;
|
||||
int rc;
|
||||
double RC, dt;
|
||||
|
||||
/* attack (3ms) and recovery time (13.5ms) according to amps specs */
|
||||
init_compander(&s->cstate, 8000, 3.0, 13.5, TX_AUDIO_0dBm0);
|
||||
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Init DSP for transceiver.\n");
|
||||
|
||||
if (amps->sender.samplerate < 96000) {
|
||||
PDEBUG(DDSP, DEBUG_ERROR, "Sample rate must be at least 96000 Hz to process FSK and SAT signals.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
amps->fsk_bitduration = (double)amps->sender.samplerate / (double)BITRATE;
|
||||
amps->fsk_bitstep = 1.0 / amps->fsk_bitduration;
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Use %.4f samples for full bit duration @ %d.\n", amps->fsk_bitduration, amps->sender.samplerate);
|
||||
|
||||
amps->fsk_tx_buffer_size = amps->fsk_bitduration * (double)FSK_MAX_BITS + 10; /* 10 extra to avoid overflow due to routing */
|
||||
amps->fsk_tx_buffer = calloc(sizeof(int16_t), amps->fsk_tx_buffer_size);
|
||||
if (!amps->fsk_tx_buffer) {
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n");
|
||||
rc = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
amps->fsk_rx_buffer_length = ceil(amps->fsk_bitduration); /* buffer holds one bit (rounded up) */
|
||||
amps->fsk_rx_buffer = calloc(sizeof(int16_t), amps->fsk_rx_buffer_length);
|
||||
if (!amps->fsk_rx_buffer) {
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n");
|
||||
rc = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* create devation and ramp */
|
||||
amps->fsk_deviation = FSK_DEVIATION; /* be sure not to overflow 32767 */
|
||||
dsp_init_ramp(amps);
|
||||
|
||||
/* allocate ring buffer for SAT signal detection */
|
||||
amps->sat_samples = (int)((double)amps->sender.samplerate * SAT_DURATION + 0.5);
|
||||
spl = calloc(1, amps->sat_samples * sizeof(*spl));
|
||||
if (!spl) {
|
||||
PDEBUG(DDSP, DEBUG_ERROR, "No memory!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
amps->sat_filter_spl = spl;
|
||||
|
||||
/* count SAT tones */
|
||||
for (i = 0; i < 5; i++) {
|
||||
coeff = 2.0 * cos(2.0 * PI * sat_freq[i] / (double)amps->sender.samplerate);
|
||||
amps->sat_coeff[i] = coeff * 32768.0;
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "sat_coeff[%d] = %d\n", i, (int)amps->sat_coeff[i]);
|
||||
|
||||
if (i < 3) {
|
||||
amps->sat_phaseshift256[i] = 256.0 / ((double)amps->sender.samplerate / sat_freq[i]);
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "sat_phaseshift256[%d] = %.4f\n", i, amps->sat_phaseshift256[i]);
|
||||
}
|
||||
}
|
||||
sat_reset(amps, "Initial state");
|
||||
|
||||
/* use this filter to remove dc level for 0-crossing detection
|
||||
* if we have de-emphasis, we don't need it, so high_pass is not set. */
|
||||
if (high_pass) {
|
||||
RC = 1.0 / (CUT_OFF_HIGHPASS * 2.0 *3.14);
|
||||
dt = 1.0 / amps->sender.samplerate;
|
||||
amps->highpass_factor = RC / (RC + dt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
dsp_cleanup_sender(amps);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Cleanup transceiver instance. */
|
||||
void dsp_cleanup_sender(amps_t *amps)
|
||||
{
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Cleanup DSP for treansceiver.\n");
|
||||
|
||||
if (amps->fsk_tx_buffer)
|
||||
free(amps->fsk_tx_buffer);
|
||||
if (amps->fsk_rx_buffer)
|
||||
free(amps->fsk_rx_buffer);
|
||||
if (amps->sat_filter_spl) {
|
||||
free(amps->sat_filter_spl);
|
||||
amps->sat_filter_spl = NULL;
|
||||
}
|
||||
#if 0
|
||||
if (amps->frame_spl) {
|
||||
free(amps->frame_spl);
|
||||
amps->frame_spl = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int fsk_encode(amps_t *amps, const char *bits)
|
||||
{
|
||||
int16_t *spl;
|
||||
double phase, bitstep, deviation;
|
||||
int count;
|
||||
char last;
|
||||
|
||||
if (strlen(bits) > FSK_MAX_BITS) {
|
||||
fprintf(stderr, "FSK buffer too small\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
deviation = amps->fsk_deviation;
|
||||
spl = amps->fsk_tx_buffer;
|
||||
phase = amps->fsk_tx_phase;
|
||||
last = amps->fsk_tx_last_bit;
|
||||
bitstep = amps->fsk_bitstep * 256.0 * 2.0; /* half bit ramp */
|
||||
|
||||
//printf("%s\n", bits);
|
||||
while (*bits) {
|
||||
//printf("%d %d\n", (*bits) & 1, last & 1);
|
||||
if (((*bits) & 1)) {
|
||||
if ((last & 1)) {
|
||||
/* last bit was 1, this bit is 1, so we ramp down first */
|
||||
do {
|
||||
*spl++ = ramp_down[(int)phase];
|
||||
phase += bitstep;
|
||||
} while (phase < 256.0);
|
||||
phase -= 256.0;
|
||||
} else {
|
||||
/* last bit was 0, this bit is 1, so we stay down first */
|
||||
do {
|
||||
*spl++ = -deviation;
|
||||
phase += bitstep;
|
||||
} while (phase < 256.0);
|
||||
phase -= 256.0;
|
||||
}
|
||||
/* ramp up */
|
||||
do {
|
||||
*spl++ = ramp_up[(int)phase];
|
||||
phase += bitstep;
|
||||
} while (phase < 256.0);
|
||||
phase -= 256.0;
|
||||
} else {
|
||||
if ((last & 1)) {
|
||||
/* last bit was 1, this bit is 0, so we stay up first */
|
||||
do {
|
||||
*spl++ = deviation;
|
||||
phase += bitstep;
|
||||
} while (phase < 256.0);
|
||||
phase -= 256.0;
|
||||
} else {
|
||||
/* last bit was 0, this bit is 0, so we ramp up first */
|
||||
do {
|
||||
*spl++ = ramp_up[(int)phase];
|
||||
phase += bitstep;
|
||||
} while (phase < 256.0);
|
||||
phase -= 256.0;
|
||||
}
|
||||
/* ramp up */
|
||||
do {
|
||||
*spl++ = ramp_down[(int)phase];
|
||||
phase += bitstep;
|
||||
} while (phase < 256.0);
|
||||
phase -= 256.0;
|
||||
}
|
||||
last = *bits;
|
||||
bits++;
|
||||
}
|
||||
|
||||
/* depending on the number of samples, return the number */
|
||||
count = ((uintptr_t)spl - (uintptr_t)amps->fsk_tx_buffer) / sizeof(*spl);
|
||||
|
||||
amps->fsk_tx_last_bit = last;
|
||||
amps->fsk_tx_phase = phase;
|
||||
amps->fsk_tx_buffer_length = count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int fsk_frame(amps_t *amps, int16_t *samples, int length)
|
||||
{
|
||||
int count = 0, pos, copy, i;
|
||||
int16_t *spl;
|
||||
const char *bits;
|
||||
|
||||
again:
|
||||
/* there must be length, otherwise we would skip blocks */
|
||||
if (count == length)
|
||||
return count;
|
||||
|
||||
pos = amps->fsk_tx_buffer_pos;
|
||||
spl = amps->fsk_tx_buffer + pos;
|
||||
|
||||
/* start new frame, so we generate one */
|
||||
if (pos == 0) {
|
||||
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_FRAME_TX)
|
||||
bits = amps_encode_frame_fvc(amps);
|
||||
else
|
||||
bits = amps_encode_frame_focc(amps);
|
||||
if (!bits)
|
||||
return 0;
|
||||
fsk_encode(amps, bits);
|
||||
}
|
||||
|
||||
copy = amps->fsk_tx_buffer_length - pos;
|
||||
if (length - count < copy)
|
||||
copy = length - count;
|
||||
//printf("pos=%d length=%d copy=%d\n", pos, length, copy);
|
||||
for (i = 0; i < copy; i++) {
|
||||
#ifdef DEBUG_ENCODER
|
||||
puts(debug_amplitude((double)(*spl) / 32767.0));
|
||||
#endif
|
||||
*samples++ = *spl++;
|
||||
}
|
||||
pos += copy;
|
||||
count += copy;
|
||||
if (pos ==amps->fsk_tx_buffer_length) {
|
||||
amps->fsk_tx_buffer_pos = 0;
|
||||
goto again;
|
||||
}
|
||||
|
||||
amps->fsk_tx_buffer_pos = pos;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Generate audio stream with SAT signal. Keep phase for next call of function. */
|
||||
static void sat_encode(amps_t *amps, int16_t *samples, int length)
|
||||
{
|
||||
double phaseshift, phase;
|
||||
int32_t sample;
|
||||
int i;
|
||||
|
||||
phaseshift = amps->sat_phaseshift256[amps->sat];
|
||||
phase = amps->sat_phase256;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
sample = *samples;
|
||||
sample += dsp_sine_sat[((uint8_t)phase) & 0xff];
|
||||
if (sample > 32767)
|
||||
sample = 32767;
|
||||
else if (sample < -32767)
|
||||
sample = -32767;
|
||||
*samples++ = sample;
|
||||
phase += phaseshift;
|
||||
if (phase >= 256)
|
||||
phase -= 256;
|
||||
}
|
||||
|
||||
amps->sat_phase256 = phase;
|
||||
}
|
||||
|
||||
/* Provide stream of audio toward radio unit */
|
||||
void sender_send(sender_t *sender, int16_t *samples, int length)
|
||||
{
|
||||
amps_t *amps = (amps_t *) sender;
|
||||
int count;
|
||||
|
||||
again:
|
||||
switch (amps->dsp_mode) {
|
||||
case DSP_MODE_OFF:
|
||||
off:
|
||||
/* silence, if transmitter is off */
|
||||
memset(samples, 0, length * sizeof(*samples));
|
||||
break;
|
||||
case DSP_MODE_AUDIO_RX_AUDIO_TX:
|
||||
audio:
|
||||
jitter_load(&s->sender.audio, samples, length);
|
||||
/* pre-emphasis */
|
||||
if (amps->pre_emphasis)
|
||||
pre_emphasis(&s->estate, samples, length);
|
||||
/* encode sat */
|
||||
sat_encode(amps, samples, length);
|
||||
break;
|
||||
case DSP_MODE_AUDIO_RX_FRAME_TX:
|
||||
case DSP_MODE_FRAME_RX_FRAME_TX:
|
||||
/* Encode frame into audio stream. If frames have
|
||||
* stopped, process again for rest of stream. */
|
||||
count = fsk_frame(amps, samples, length);
|
||||
#if 0
|
||||
/* special case: add SAT signal to frame at loop test */
|
||||
if (amps->sender.loopback)
|
||||
sat_encode(amps, samples, length);
|
||||
#endif
|
||||
/* count == 0: no frame, this should not happen */
|
||||
if (count == 0)
|
||||
goto off;
|
||||
/* * also if the mode changed to audio during processing */
|
||||
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX)
|
||||
goto audio;
|
||||
samples += count;
|
||||
length -= count;
|
||||
goto again;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fsk_rx_bit(amps_t *amps, int16_t *spl, int len, int pos)
|
||||
{
|
||||
int i, ii;
|
||||
int32_t first, second;
|
||||
int bit;
|
||||
int32_t max = -32768, min = 32767;
|
||||
|
||||
/* decode one bit. substact the first half from the second half.
|
||||
* the result shows the direction of the bit change: 1 == positive.
|
||||
*/
|
||||
ii = len >> 1;
|
||||
second = first = 0;
|
||||
for (i = 0; i < ii; i++) {
|
||||
if (--pos < 0)
|
||||
pos = len - 1;
|
||||
//printf("second %d: %d\n", pos, spl[pos]);
|
||||
second += spl[pos];
|
||||
if (spl[pos] > max)
|
||||
max = spl[pos];
|
||||
if (spl[pos] < min)
|
||||
min = spl[pos];
|
||||
}
|
||||
second /= ii;
|
||||
for (i = 0; i < ii; i++) {
|
||||
if (--pos < 0)
|
||||
pos = len - 1;
|
||||
//printf("first %d: %d\n", pos, spl[pos]);
|
||||
first += spl[pos];
|
||||
if (spl[pos] > max)
|
||||
max = spl[pos];
|
||||
if (spl[pos] < min)
|
||||
min = spl[pos];
|
||||
}
|
||||
first /= ii;
|
||||
//printf("first = %d second = %d\n", first, second);
|
||||
/* get bit */
|
||||
if (second > first)
|
||||
bit = 1;
|
||||
else
|
||||
bit = 0;
|
||||
#ifdef DEBUG_DECODER
|
||||
if (amps->fsk_rx_sync != FSK_SYNC_POSITIVE && amps->fsk_rx_sync != FSK_SYNC_NEGATIVE)
|
||||
printf("Decoded bit as %d (dotting life = %d)\n", bit, amps->fsk_rx_dotting_life);
|
||||
else
|
||||
printf("Decoded bit as %d\n", bit);
|
||||
#endif
|
||||
|
||||
if (amps->fsk_rx_sync != FSK_SYNC_POSITIVE && amps->fsk_rx_sync != FSK_SYNC_NEGATIVE) {
|
||||
amps->fsk_rx_sync_register = (amps->fsk_rx_sync_register << 1) | bit;
|
||||
/* check if we received a sync */
|
||||
if ((amps->fsk_rx_sync_register & 0x7ff) == 0x712) {
|
||||
#ifdef DEBUG_DECODER
|
||||
printf("Sync word detected (positive)\n");
|
||||
#endif
|
||||
amps->fsk_rx_sync = FSK_SYNC_POSITIVE;
|
||||
prepare_frame:
|
||||
amps->fsk_rx_frame_count = 0;
|
||||
amps->fsk_rx_frame_quality = 0.0;
|
||||
amps->fsk_rx_frame_level = 0.0;
|
||||
amps->fsk_rx_sync_register = 0x555;
|
||||
return;
|
||||
}
|
||||
if ((amps->fsk_rx_sync_register & 0x7ff) == 0x0ed) {
|
||||
#ifdef DEBUG_DECODER
|
||||
printf("Sync word detected (negative)\n");
|
||||
#endif
|
||||
amps->fsk_rx_sync = FSK_SYNC_NEGATIVE;
|
||||
goto prepare_frame;
|
||||
return;
|
||||
}
|
||||
/* if no sync, count down the dotting life counter */
|
||||
if (--amps->fsk_rx_dotting_life == 0) {
|
||||
#ifdef DEBUG_DECODER
|
||||
printf("No Sync detected after dotting\n");
|
||||
#endif
|
||||
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* count level and quality */
|
||||
amps->fsk_rx_frame_level += (double)(max - min) / (double)FSK_DEVIATION / 2.0;
|
||||
if (bit)
|
||||
amps->fsk_rx_frame_quality += (double)(second - first) / (double)FSK_DEVIATION / 2.0 / BEST_QUALITY;
|
||||
else
|
||||
amps->fsk_rx_frame_quality += (double)(first - second) / (double)FSK_DEVIATION / 2.0 / BEST_QUALITY;
|
||||
|
||||
/* invert bit if negative sync was detected */
|
||||
if (amps->fsk_rx_sync == FSK_SYNC_NEGATIVE)
|
||||
bit = 1 - bit;
|
||||
|
||||
/* read next bit. after all bits, we reset to FSK_SYNC_NONE */
|
||||
amps->fsk_rx_frame[amps->fsk_rx_frame_count++] = bit + '0';
|
||||
if (amps->fsk_rx_frame_count > FSK_MAX_BITS) {
|
||||
fprintf(stderr, "our fsk_tx_count (%d) is larger than our max bits we can handle, please fix!\n", amps->fsk_rx_frame_count);
|
||||
abort();
|
||||
}
|
||||
if (amps->fsk_rx_frame_count == amps->fsk_rx_frame_length) {
|
||||
int more;
|
||||
|
||||
/* a complete frame was received, so we process it */
|
||||
amps->fsk_rx_frame[amps->fsk_rx_frame_count] = '\0';
|
||||
more = amps_decode_frame(amps, amps->fsk_rx_frame, amps->fsk_rx_frame_count, amps->fsk_rx_frame_level / (double)amps->fsk_rx_frame_count, amps->fsk_rx_frame_quality / amps->fsk_rx_frame_level, (amps->fsk_rx_sync == FSK_SYNC_NEGATIVE));
|
||||
if (more) {
|
||||
/* switch to next worda length without DCC included */
|
||||
amps->fsk_rx_frame_length = 240;
|
||||
goto prepare_frame;
|
||||
} else {
|
||||
/* switch back to first word length with DCC included */
|
||||
if (amps->fsk_rx_frame_length == 240)
|
||||
amps->fsk_rx_frame_length = 247;
|
||||
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fsk_rx_dotting(amps_t *amps, double _elapsed, int dir)
|
||||
{
|
||||
uint8_t pos = amps->fsk_rx_dotting_pos++;
|
||||
double average, elapsed, offset;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG_DECODER
|
||||
printf("Level change detected\n");
|
||||
#endif
|
||||
/* store into dotting list */
|
||||
amps->fsk_rx_dotting_elapsed[pos++] = _elapsed;
|
||||
|
||||
/* check quality of dotting sequence.
|
||||
* in case this is not a dotting sequence, noise or speech, the quality
|
||||
* should be bad.
|
||||
* count (only) 7 'elapsed' values between 8 zero-crossings.
|
||||
* calculate the average relative to the current position.
|
||||
*/
|
||||
average = 0.0;
|
||||
elapsed = 0.0;
|
||||
for (i = 1; i < 8; i++) {
|
||||
elapsed += amps->fsk_rx_dotting_elapsed[--pos];
|
||||
offset = elapsed - (double)i;
|
||||
if (offset >= 0.5 || offset <= -0.5) {
|
||||
#ifdef DEBUG_DECODER
|
||||
// printf("offset %.3f (last but %d) not within -0.5 .. 0.5 bit position, detecting no dotting.\n", offset, i - 1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
average += offset;
|
||||
}
|
||||
average /= (double)i;
|
||||
|
||||
amps->fsk_rx_dotting_life = 12;
|
||||
|
||||
/* if we are already found dotting, we detect better dotting.
|
||||
* this happens, if dotting was falsely detected due to noise.
|
||||
* then the real dotting causes a reastart of hunting for sync sequence.
|
||||
*/
|
||||
if (amps->fsk_rx_sync == FSK_SYNC_NONE || fabs(average) < amps->fsk_rx_dotting_average) {
|
||||
#ifdef DEBUG_DECODER
|
||||
printf("Found (better) dotting sequence (average = %.3f)\n", average);
|
||||
#endif
|
||||
amps->fsk_rx_sync = FSK_SYNC_DOTTING;
|
||||
amps->fsk_rx_dotting_average = fabs(average);
|
||||
amps->fsk_rx_bitcount = 0.5 + average;
|
||||
}
|
||||
}
|
||||
|
||||
/* decode frame */
|
||||
void sender_receive_frame(amps_t *amps, int16_t *samples, int length)
|
||||
{
|
||||
int16_t *spl, last_sample;
|
||||
int len, pos;
|
||||
double bitstep, elapsed;
|
||||
int i;
|
||||
|
||||
bitstep = amps->fsk_bitstep;
|
||||
spl = amps->fsk_rx_buffer;
|
||||
pos = amps->fsk_rx_buffer_pos;
|
||||
len = amps->fsk_rx_buffer_length;
|
||||
last_sample = amps->fsk_rx_last_sample;
|
||||
elapsed = amps->fsk_rx_elapsed;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
#ifdef DEBUG_DECODER
|
||||
puts(debug_amplitude((double)samples[i] / (double)FSK_DEVIATION));
|
||||
#endif
|
||||
/* push sample to detection window and shift */
|
||||
spl[pos++] = samples[i];
|
||||
if (pos == len)
|
||||
pos = 0;
|
||||
if (amps->fsk_rx_sync != FSK_SYNC_POSITIVE && amps->fsk_rx_sync != FSK_SYNC_NEGATIVE) {
|
||||
/* check for change in polarity */
|
||||
if (last_sample <= 0) {
|
||||
if (samples[i] > 0) {
|
||||
fsk_rx_dotting(amps, elapsed, 1);
|
||||
elapsed = 0.0;
|
||||
}
|
||||
} else {
|
||||
if (samples[i] <= 0) {
|
||||
fsk_rx_dotting(amps, elapsed, 0);
|
||||
elapsed = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
last_sample = samples[i];
|
||||
elapsed += bitstep;
|
||||
// printf("%.4f\n", bitcount);
|
||||
if (amps->fsk_rx_sync != FSK_SYNC_NONE) {
|
||||
amps->fsk_rx_bitcount += bitstep;
|
||||
if (amps->fsk_rx_bitcount >= 1.0) {
|
||||
amps->fsk_rx_bitcount -= 1.0;
|
||||
fsk_rx_bit(amps, spl, len, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amps->fsk_rx_last_sample = last_sample;
|
||||
amps->fsk_rx_elapsed = elapsed;
|
||||
amps->fsk_rx_buffer_pos = pos;
|
||||
}
|
||||
|
||||
|
||||
/* decode signalling tone */
|
||||
/* compare supervisory signal against noise floor on 5800 Hz */
|
||||
static void sat_decode(amps_t *amps, int16_t *samples, int length)
|
||||
{
|
||||
int coeff[3];
|
||||
double result[3], quality[2];
|
||||
|
||||
coeff[0] = amps->sat_coeff[amps->sat];
|
||||
coeff[1] = amps->sat_coeff[3]; /* noise floor detection */
|
||||
coeff[2] = amps->sat_coeff[4]; /* signalling tone */
|
||||
audio_goertzel(samples, length, 0, coeff, result, 3);
|
||||
|
||||
quality[0] = (result[0] - result[1]) / result[0];
|
||||
if (quality[0] < 0)
|
||||
quality[0] = 0;
|
||||
quality[1] = (result[2] - result[1]) / result[2];
|
||||
if (quality[1] < 0)
|
||||
quality[1] = 0;
|
||||
|
||||
PDEBUG(DDSP, DEBUG_NOTICE, "SAT level %.2f%% quality %.0f%%\n", result[0] * 32767.0 / SAT_DEVIATION / 0.63662 * 100.0, quality[0] * 100.0);
|
||||
if (amps->sender.loopback || debuglevel == DEBUG_DEBUG) {
|
||||
PDEBUG(DDSP, debuglevel, "Signalling Tone level %.2f%% quality %.0f%%\n", result[2] * 32767.0 / FSK_DEVIATION / 0.63662 * 100.0, quality[1] * 100.0);
|
||||
}
|
||||
if (quality[0] > SAT_QUALITY) {
|
||||
if (amps->sat_detected == 0) {
|
||||
amps->sat_detect_count++;
|
||||
if (amps->sat_detect_count == SAT_DETECT_COUNT) {
|
||||
amps->sat_detected = 1;
|
||||
amps->sat_detect_count = 0;
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "SAT signal detected with level=%.0f%%, quality=%.0f%%.\n", result[0] / 0.63662 * 100.0, quality[0] * 100.0);
|
||||
amps_rx_sat(amps, 1, quality[0]);
|
||||
}
|
||||
} else
|
||||
amps->sat_detect_count = 0;
|
||||
} else {
|
||||
if (amps->sat_detected == 1) {
|
||||
amps->sat_detect_count++;
|
||||
if (amps->sat_detect_count == SAT_LOST_COUNT) {
|
||||
amps->sat_detected = 0;
|
||||
amps->sat_detect_count = 0;
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "SAT signal lost.\n");
|
||||
amps_rx_sat(amps, 0, 0.0);
|
||||
}
|
||||
} else
|
||||
amps->sat_detect_count = 0;
|
||||
}
|
||||
if (quality[1] > 0.8) {
|
||||
if (amps->sig_detected == 0) {
|
||||
amps->sig_detect_count++;
|
||||
if (amps->sig_detect_count == SIG_DETECT_COUNT) {
|
||||
amps->sig_detected = 1;
|
||||
amps->sig_detect_count = 0;
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Signalling Tone detected with level=%.0f%%, quality=%.0f%%.\n", result[2] / 0.63662 * 100.0, quality[1] * 100.0);
|
||||
amps_rx_signalling_tone(amps, 1, quality[1]);
|
||||
}
|
||||
} else
|
||||
amps->sig_detect_count = 0;
|
||||
} else {
|
||||
if (amps->sig_detected == 1) {
|
||||
amps->sig_detect_count++;
|
||||
if (amps->sig_detect_count == SIG_LOST_COUNT) {
|
||||
amps->sig_detected = 0;
|
||||
amps->sig_detect_count = 0;
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "Signalling Tone lost.\n");
|
||||
amps_rx_signalling_tone(amps, 0, 0.0);
|
||||
}
|
||||
} else
|
||||
amps->sig_detect_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* decode signalling/audio */
|
||||
/* Count SIG_TONE_CROSSINGS of zero crossings, then check if the elapsed bit
|
||||
* time is between SIG_TONE_MINBITS and SIG_TONE_MAXBITS. If it is, the
|
||||
* frequency is close to the singalling tone, so it is detected
|
||||
*/
|
||||
void sender_receive_audio(amps_t *amps, int16_t *samples, int length)
|
||||
{
|
||||
transaction_t *trans = amps->trans_list;
|
||||
int16_t *spl;
|
||||
int max, pos;
|
||||
int i;
|
||||
|
||||
/* SAT detection */
|
||||
|
||||
max = amps->sat_samples;
|
||||
spl = amps->sat_filter_spl;
|
||||
pos = amps->sat_filter_pos;
|
||||
for (i = 0; i < length; i++) {
|
||||
spl[pos++] = samples[i];
|
||||
if (pos == max) {
|
||||
pos = 0;
|
||||
sat_decode(amps, spl, max);
|
||||
}
|
||||
}
|
||||
amps->sat_filter_pos = pos;
|
||||
|
||||
/* receive audio, but only if call established and SAT detected */
|
||||
|
||||
if ((amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX || amps->dsp_mode == DSP_MODE_AUDIO_RX_FRAME_TX)
|
||||
&& amps->sender.callref && trans && trans->sat_detected) {
|
||||
int16_t down[length]; /* more than enough */
|
||||
int pos, count;
|
||||
int16_t *spl;
|
||||
int i;
|
||||
|
||||
/* de-emphasis */
|
||||
if (amps->de_emphasis)
|
||||
de_emphasis(&s->estate, samples, length);
|
||||
/* downsample */
|
||||
count = samplerate_downsample(&s->sender.srstate, samples, length, down);
|
||||
expand_audio(&s->cstate, down, count);
|
||||
spl = amps->sender.rxbuf;
|
||||
pos = amps->sender.rxbuf_pos;
|
||||
for (i = 0; i < count; i++) {
|
||||
spl[pos++] = down[i];
|
||||
if (pos == 160) {
|
||||
call_tx_audio(amps->sender.callref, spl, 160);
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
amps->sender.rxbuf_pos = pos;
|
||||
} else
|
||||
amps->sender.rxbuf_pos = 0;
|
||||
}
|
||||
|
||||
/* Process received audio stream from radio unit. */
|
||||
void sender_receive(sender_t *sender, int16_t *samples, int length)
|
||||
{
|
||||
amps_t *amps = (amps_t *) sender;
|
||||
double x, y, x_last, y_last, factor;
|
||||
int32_t value;
|
||||
int i;
|
||||
|
||||
/* high pass filter to remove 0-level
|
||||
* if factor is not set, we should already have 0-level. */
|
||||
factor = amps->highpass_factor;
|
||||
if (factor) {
|
||||
x_last = amps->highpass_x_last;
|
||||
y_last = amps->highpass_y_last;
|
||||
for (i = 0; i < length; i++) {
|
||||
x = (double)samples[i];
|
||||
y = factor * (y_last + x - x_last);
|
||||
x_last = x;
|
||||
y_last = y;
|
||||
value = (int32_t)(y + 0.5);
|
||||
if (value < -32768.0)
|
||||
value = -32768.0;
|
||||
else if (value > 32767)
|
||||
value = 32767;
|
||||
samples[i] = value;
|
||||
}
|
||||
amps->highpass_x_last = x_last;
|
||||
amps->highpass_y_last = y_last;
|
||||
}
|
||||
|
||||
switch (amps->dsp_mode) {
|
||||
case DSP_MODE_OFF:
|
||||
break;
|
||||
case DSP_MODE_FRAME_RX_FRAME_TX:
|
||||
sender_receive_frame(amps, samples, length);
|
||||
break;
|
||||
case DSP_MODE_AUDIO_RX_AUDIO_TX:
|
||||
case DSP_MODE_AUDIO_RX_FRAME_TX:
|
||||
sender_receive_audio(amps, samples, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset SAT detection states, so ongoing tone will be detected again. */
|
||||
static void sat_reset(amps_t *amps, const char *reason)
|
||||
{
|
||||
PDEBUG(DDSP, DEBUG_DEBUG, "SAT detector reset: %s.\n", reason);
|
||||
amps->sat_detected = 0;
|
||||
amps->sat_detect_count = 0;
|
||||
amps->sig_detected = 0;
|
||||
amps->sig_detect_count = 0;
|
||||
}
|
||||
|
||||
void amps_set_dsp_mode(amps_t *amps, enum dsp_mode mode, int frame_length)
|
||||
{
|
||||
#if 0
|
||||
/* reset telegramm */
|
||||
if (mode == DSP_MODE_FRAME && amps->dsp_mode != mode)
|
||||
amps->frame = 0;
|
||||
#endif
|
||||
if (mode == DSP_MODE_FRAME_RX_FRAME_TX) {
|
||||
/* reset SAT detection */
|
||||
sat_reset(amps, "Change to FOCC");
|
||||
}
|
||||
if (amps->dsp_mode == DSP_MODE_FRAME_RX_FRAME_TX
|
||||
&& (mode == DSP_MODE_AUDIO_RX_AUDIO_TX || mode == DSP_MODE_AUDIO_RX_FRAME_TX)) {
|
||||
/* reset SAT detection */
|
||||
sat_reset(amps, "Change from FOCC to FVC");
|
||||
}
|
||||
|
||||
amps->dsp_mode = mode;
|
||||
if (frame_length)
|
||||
amps->fsk_rx_frame_length = frame_length;
|
||||
|
||||
/* reset detection process */
|
||||
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
||||
amps->fsk_rx_sync_register = 0x555;
|
||||
|
||||
/* reset transmitter */
|
||||
amps->fsk_tx_buffer_pos = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
void dsp_init(void);
|
||||
int dsp_init_sender(amps_t *amps, int high_pass);
|
||||
void dsp_cleanup_sender(amps_t *amps);
|
||||
void amps_set_dsp_mode(amps_t *amps, enum dsp_mode mode, int frame_length);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,225 @@
|
|||
|
||||
enum amps_ie {
|
||||
AMPS_IE_010111,
|
||||
AMPS_IE_1,
|
||||
AMPS_IE_11,
|
||||
AMPS_IE_1111,
|
||||
AMPS_IE_ACT,
|
||||
AMPS_IE_AUTH,
|
||||
AMPS_IE_AUTHBS,
|
||||
AMPS_IE_AUTHR,
|
||||
AMPS_IE_AUTHU,
|
||||
AMPS_IE_Acked_Data,
|
||||
AMPS_IE_Async_Data,
|
||||
AMPS_IE_BIS,
|
||||
AMPS_IE_BSCAP,
|
||||
AMPS_IE_BSPC,
|
||||
AMPS_IE_CHAN,
|
||||
AMPS_IE_CHANPOS,
|
||||
AMPS_IE_CHARACTER_1,
|
||||
AMPS_IE_CHARACTER_2,
|
||||
AMPS_IE_CHARACTER_3,
|
||||
AMPS_IE_CMAC,
|
||||
AMPS_IE_CMAX_1,
|
||||
AMPS_IE_COUNT,
|
||||
AMPS_IE_CPA,
|
||||
AMPS_IE_CPN_RL,
|
||||
AMPS_IE_CRC,
|
||||
AMPS_IE_CRI_E11,
|
||||
AMPS_IE_CRI_E12,
|
||||
AMPS_IE_CRI_E13,
|
||||
AMPS_IE_CRI_E14,
|
||||
AMPS_IE_CRI_E21,
|
||||
AMPS_IE_CRI_E22,
|
||||
AMPS_IE_CRI_E23,
|
||||
AMPS_IE_CRI_E24,
|
||||
AMPS_IE_CRI_E31,
|
||||
AMPS_IE_CRI_E32,
|
||||
AMPS_IE_CRI_E33,
|
||||
AMPS_IE_CRI_E34,
|
||||
AMPS_IE_CRI_E41,
|
||||
AMPS_IE_CRI_E42,
|
||||
AMPS_IE_CRI_E43,
|
||||
AMPS_IE_CRI_E44,
|
||||
AMPS_IE_CRI_E51,
|
||||
AMPS_IE_CRI_E52,
|
||||
AMPS_IE_CRI_E53,
|
||||
AMPS_IE_CRI_E54,
|
||||
AMPS_IE_CRI_E61,
|
||||
AMPS_IE_CRI_E62,
|
||||
AMPS_IE_CRI_E63,
|
||||
AMPS_IE_CRI_E64,
|
||||
AMPS_IE_CRI_E71,
|
||||
AMPS_IE_CRI_E72,
|
||||
AMPS_IE_CRI_E73,
|
||||
AMPS_IE_CRI_E74,
|
||||
AMPS_IE_CRI_E81,
|
||||
AMPS_IE_CRI_E82,
|
||||
AMPS_IE_CRI_E83,
|
||||
AMPS_IE_CRI_E84,
|
||||
AMPS_IE_DCC,
|
||||
AMPS_IE_DIGIT_1,
|
||||
AMPS_IE_DIGIT_10,
|
||||
AMPS_IE_DIGIT_11,
|
||||
AMPS_IE_DIGIT_12,
|
||||
AMPS_IE_DIGIT_13,
|
||||
AMPS_IE_DIGIT_14,
|
||||
AMPS_IE_DIGIT_15,
|
||||
AMPS_IE_DIGIT_16,
|
||||
AMPS_IE_DIGIT_17,
|
||||
AMPS_IE_DIGIT_18,
|
||||
AMPS_IE_DIGIT_19,
|
||||
AMPS_IE_DIGIT_2,
|
||||
AMPS_IE_DIGIT_20,
|
||||
AMPS_IE_DIGIT_21,
|
||||
AMPS_IE_DIGIT_22,
|
||||
AMPS_IE_DIGIT_23,
|
||||
AMPS_IE_DIGIT_24,
|
||||
AMPS_IE_DIGIT_25,
|
||||
AMPS_IE_DIGIT_26,
|
||||
AMPS_IE_DIGIT_27,
|
||||
AMPS_IE_DIGIT_28,
|
||||
AMPS_IE_DIGIT_29,
|
||||
AMPS_IE_DIGIT_3,
|
||||
AMPS_IE_DIGIT_30,
|
||||
AMPS_IE_DIGIT_31,
|
||||
AMPS_IE_DIGIT_32,
|
||||
AMPS_IE_DIGIT_4,
|
||||
AMPS_IE_DIGIT_5,
|
||||
AMPS_IE_DIGIT_6,
|
||||
AMPS_IE_DIGIT_7,
|
||||
AMPS_IE_DIGIT_8,
|
||||
AMPS_IE_DIGIT_9,
|
||||
AMPS_IE_DMAC,
|
||||
AMPS_IE_DTX,
|
||||
AMPS_IE_DTX_Support,
|
||||
AMPS_IE_DVCC,
|
||||
AMPS_IE_Data_Part,
|
||||
AMPS_IE_Data_Privacy,
|
||||
AMPS_IE_E,
|
||||
AMPS_IE_EC,
|
||||
AMPS_IE_EF,
|
||||
AMPS_IE_END,
|
||||
AMPS_IE_EP,
|
||||
AMPS_IE_ER,
|
||||
AMPS_IE_ESN,
|
||||
AMPS_IE_F,
|
||||
AMPS_IE_G3_Fax,
|
||||
AMPS_IE_HDVCC,
|
||||
AMPS_IE_Hyperband,
|
||||
AMPS_IE_LOCAID,
|
||||
AMPS_IE_LOCAL_CONTROL,
|
||||
AMPS_IE_LOCAL_MSG_TYPE,
|
||||
AMPS_IE_LREG,
|
||||
AMPS_IE_LT,
|
||||
AMPS_IE_MAXBUSY_OTHER,
|
||||
AMPS_IE_MAXBUSY_PGR,
|
||||
AMPS_IE_MAXSZTR_OTHER,
|
||||
AMPS_IE_MAXSZTR_PGR,
|
||||
AMPS_IE_MEM,
|
||||
AMPS_IE_MIN1,
|
||||
AMPS_IE_MIN2,
|
||||
AMPS_IE_MPCI,
|
||||
AMPS_IE_MSCAP,
|
||||
AMPS_IE_MSPC,
|
||||
AMPS_IE_N_1,
|
||||
AMPS_IE_NAWC ,
|
||||
AMPS_IE_NEWACC,
|
||||
AMPS_IE_NULL,
|
||||
AMPS_IE_OHD,
|
||||
AMPS_IE_OLC_0,
|
||||
AMPS_IE_OLC_1,
|
||||
AMPS_IE_OLC_10,
|
||||
AMPS_IE_OLC_11,
|
||||
AMPS_IE_OLC_12,
|
||||
AMPS_IE_OLC_13,
|
||||
AMPS_IE_OLC_14,
|
||||
AMPS_IE_OLC_15,
|
||||
AMPS_IE_OLC_2,
|
||||
AMPS_IE_OLC_3,
|
||||
AMPS_IE_OLC_4,
|
||||
AMPS_IE_OLC_5,
|
||||
AMPS_IE_OLC_6,
|
||||
AMPS_IE_OLC_7,
|
||||
AMPS_IE_OLC_8,
|
||||
AMPS_IE_OLC_9,
|
||||
AMPS_IE_ORDER,
|
||||
AMPS_IE_ORDQ,
|
||||
AMPS_IE_P,
|
||||
AMPS_IE_PCI,
|
||||
AMPS_IE_PCI_HOME,
|
||||
AMPS_IE_PCI_ROAM,
|
||||
AMPS_IE_PDREG,
|
||||
AMPS_IE_PI,
|
||||
AMPS_IE_PM,
|
||||
AMPS_IE_PM_D,
|
||||
AMPS_IE_PSCC,
|
||||
AMPS_IE_PUREG,
|
||||
AMPS_IE_PVI,
|
||||
AMPS_IE_RAND1_A,
|
||||
AMPS_IE_RAND1_B,
|
||||
AMPS_IE_RANDBS,
|
||||
AMPS_IE_RANDC,
|
||||
AMPS_IE_RANDSSD_1,
|
||||
AMPS_IE_RANDSSD_2,
|
||||
AMPS_IE_RANDSSD_3,
|
||||
AMPS_IE_RANDU,
|
||||
AMPS_IE_RCF,
|
||||
AMPS_IE_REGH,
|
||||
AMPS_IE_REGID,
|
||||
AMPS_IE_REGINCR,
|
||||
AMPS_IE_REGR,
|
||||
AMPS_IE_RLP,
|
||||
AMPS_IE_RL_W,
|
||||
AMPS_IE_RSVD,
|
||||
AMPS_IE_S,
|
||||
AMPS_IE_SAP,
|
||||
AMPS_IE_SBI,
|
||||
AMPS_IE_SCC,
|
||||
AMPS_IE_SCM,
|
||||
AMPS_IE_SDCC1,
|
||||
AMPS_IE_SDCC2,
|
||||
AMPS_IE_SI,
|
||||
AMPS_IE_SID1,
|
||||
AMPS_IE_SIGNAL,
|
||||
AMPS_IE_Service_Code,
|
||||
AMPS_IE_T,
|
||||
AMPS_IE_T1T2,
|
||||
AMPS_IE_TA,
|
||||
AMPS_IE_TCI1,
|
||||
AMPS_IE_TCI21,
|
||||
AMPS_IE_TCI22,
|
||||
AMPS_IE_TCI23,
|
||||
AMPS_IE_TCI24,
|
||||
AMPS_IE_TCI31,
|
||||
AMPS_IE_TCI32,
|
||||
AMPS_IE_TCI33,
|
||||
AMPS_IE_TCI34,
|
||||
AMPS_IE_TCI41,
|
||||
AMPS_IE_TCI42,
|
||||
AMPS_IE_TCI43,
|
||||
AMPS_IE_TCI44,
|
||||
AMPS_IE_TCI5,
|
||||
AMPS_IE_VMAC,
|
||||
AMPS_IE_WFOM,
|
||||
AMPS_IE_NUM
|
||||
};
|
||||
|
||||
typedef struct amps_frame {
|
||||
enum amps_ie ie[AMPS_IE_NUM];
|
||||
} frame_t;
|
||||
|
||||
void init_frame(void);
|
||||
uint64_t amps_encode_word1_system(uint8_t dcc, uint16_t sid1, uint8_t ep, uint8_t auth, uint8_t pci, uint8_t nawc);
|
||||
uint64_t amps_encode_word2_system(uint8_t dcc, uint8_t s, uint8_t e, uint8_t regh, uint8_t regr, uint8_t dtx, uint8_t n_1, uint8_t rcf, uint8_t cpa, uint8_t cmax_1, uint8_t end);
|
||||
uint64_t amps_encode_registration_id(uint8_t dcc, uint32_t regid, uint8_t end);
|
||||
uint64_t amps_encode_registration_increment(uint8_t dcc, uint16_t regincr, uint8_t end);
|
||||
uint64_t amps_encode_location_area(uint8_t dcc, uint8_t pureg, uint8_t pdreg, uint8_t lreg, uint16_t locaid, uint8_t end);
|
||||
uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_t end);
|
||||
uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, uint8_t end);
|
||||
uint64_t amps_encode_access_type(uint8_t dcc, uint8_t bis, uint8_t pci_home, uint8_t pci_roam, uint8_t bspc, uint8_t bscap, uint8_t end);
|
||||
uint64_t amps_encode_access_attempt(uint8_t dcc, uint8_t maxbusy_pgr, uint8_t maxsztr_pgr, uint8_t maxbusy_other, uint8_t maxsztr_other, uint8_t end);
|
||||
const char *amps_encode_frame_focc(amps_t *amps);
|
||||
const char *amps_encode_frame_fvc(amps_t *amps);
|
||||
int amps_decode_frame(amps_t *amps, const char *bits, int count, double level, double quality, int negative);
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "image.h"
|
||||
|
||||
const char *image[] = {
|
||||
"",
|
||||
" @R| |",
|
||||
" @Y| @R/|===|\\",
|
||||
" @Y-=@wO@Y=- @R/ |\\ /| \\ @w~",
|
||||
" @Y| @wAMPS @R/ | X | \\ @w~",
|
||||
" @R/ |===| \\",
|
||||
" @R/ | |\\ \\",
|
||||
" @R/ /| | \\ \\ @w~",
|
||||
" @R|--| / / |===| \\ \\",
|
||||
" @R/|\\/|\\ / / | | \\ \\",
|
||||
" @R/ |--| \\ / / | | \\ \\",
|
||||
" @R/ | |\\ \\ / / |===| \\ \\",
|
||||
"@g__ @R/ /|--| \\ \\ / / | | \\ \\",
|
||||
"@g \\_ @R/ / | | \\ \\ / / | | \\ \\",
|
||||
"@g \\ @R/ / | | \\ \\______/ / | | \\| \\|",
|
||||
"@g \\@R=========================================================================",
|
||||
"@g \\_______@R|/\\|@g______ _@G***@g_@G*@g__@G**@g_@G***@g___@G**@g_@G*@g_@R| X | @R|MMMM|",
|
||||
"@g \\__ @R|\\/|@g \\______/@G* ** * * * ** * @R|/ \\|@g______@y________@R|MMMM|",
|
||||
"@y _____@g \\_@R|/\\|@G * * * * ** * * * * * * @R|\\ /|@G*@y____/ ~ ~ ~ ~",
|
||||
"@y/ ~ ~\\@b_______@RI@b__@RI@b_________@G*@b______@G*@b_@G*@b___@G*@b__@G*@b___@G*@b__@G*@b_@G*@b_@R| X |@y/ ~ ~ _________",
|
||||
"@y_______\\@b _ _ _ _ _ _ _ _ _ _ @R|/@y_@R\\@y/ ~ ______/",
|
||||
"@b _ _ _ _ _ _ _ @y_/~ ~ ____/ ~ ~ ~",
|
||||
"@b_ @y_@b _ _ _ _ _ @y/_____/ ~ ____________",
|
||||
"@y__/~\\______________@b _ _ _ _ @y_/ ~ ~ __________/ ~ ~ ~",
|
||||
"@y ~ ~ ~ \\____________________________/ / ~ ~ ~ ~ ~",
|
||||
"@w",
|
||||
NULL
|
||||
};
|
||||
|
||||
void print_image(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; image[i]; i++) {
|
||||
for (j = 0; j < strlen(image[i]); j++) {
|
||||
if (image[i][j] == '@') {
|
||||
j++;
|
||||
switch(image[i][j]) {
|
||||
case 'R': /* bright red */
|
||||
printf("\033[1;31m");
|
||||
break;
|
||||
case 'g': /* gray */
|
||||
printf("\033[0;37m");
|
||||
break;
|
||||
case 'G': /* green */
|
||||
printf("\033[0;32m");
|
||||
break;
|
||||
case 'w': /* white */
|
||||
printf("\033[1;37m");
|
||||
break;
|
||||
case 'b': /* blue */
|
||||
printf("\033[0;34m");
|
||||
break;
|
||||
case 'y': /* yellow */
|
||||
printf("\033[0;33m");
|
||||
break;
|
||||
case 'Y': /* bright yellow */
|
||||
printf("\033[1;33m");
|
||||
break;
|
||||
}
|
||||
} else
|
||||
printf("%c", image[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\033[0;39m");
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
void print_image(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
|
||||
void init_invalidnumber(void);
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
/* AMPS main
|
||||
*
|
||||
* (C) 2016 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include "../common/main.h"
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/call.h"
|
||||
#include "../common/mncc_sock.h"
|
||||
#include "amps.h"
|
||||
#include "dsp.h"
|
||||
#include "frame.h"
|
||||
#include "image.h"
|
||||
#include "tones.h"
|
||||
#include "noanswer.h"
|
||||
#include "outoforder.h"
|
||||
#include "invalidnumber.h"
|
||||
#include "congestion.h"
|
||||
#include "stations.h"
|
||||
|
||||
/* settings */
|
||||
int num_chan_type = 0;
|
||||
enum amps_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_CC_PC_VC };
|
||||
const char *flip_polarity = "";
|
||||
int ms_power = 4, dcc = 0, scc = 0, sid = 40, regh = 1, regr = 1, pureg = 1, pdreg = 1, locaid = -1, regincr = 300;
|
||||
|
||||
void print_help(const char *arg0)
|
||||
{
|
||||
print_help_common(arg0, "-E -e -F yes | no ");
|
||||
/* - - */
|
||||
printf(" -t --channel-type <channel type> | list\n");
|
||||
printf(" Give channel type, use 'list' to get a list. (default = '%s')\n", chan_type_short_name(chan_type[0]));
|
||||
printf(" -F --flip-polarity no | yes\n");
|
||||
printf(" Flip polarity of transmitted FSK signal. If yes, the sound card\n");
|
||||
printf(" generates a negative signal rather than a positive one. Be sure that\n");
|
||||
printf(" a positive signal causes a positive deviation on your transmitter.\n");
|
||||
printf(" If the phone shows 'NoSrv', try the other way.\n");
|
||||
printf(" -P --ms-power <power level>\n");
|
||||
printf(" Give power level of the mobile station 0..7. (default = '%d')\n", ms_power);
|
||||
printf(" 0 = 4 W; 1 = 1.6 W; 2 = 630 mW; 3 = 250 mW;\n");
|
||||
printf(" 4 = 100 mW; 5 = 40 mW; 6 = 16 mW; 7 = 6.3 mW\n");
|
||||
printf(" -S --sysinfo sid=<System ID> | sid=list\n");
|
||||
printf(" Give system ID of cell broadcast (default = '%d')\n", sid);
|
||||
printf(" If it changes, phone re-registers. Use 'sid=list' to get a full list.\n");
|
||||
printf(" -S --sysinfo dcc=<digital color code>\n");
|
||||
printf(" Give digital color code 0..3 (default = '%d')\n", dcc);
|
||||
printf(" -S --sysinfo scc=<SAT color code>\n");
|
||||
printf(" Give supervisor tone color code 0..2 (default = '%d')\n", scc);
|
||||
printf(" -S --sysinfo regincr\n");
|
||||
printf(" Amount to add to REGID after successful registration (default = '%d')\n", regincr);
|
||||
printf(" Since REGID is incremented every second, this value define after how\n");
|
||||
printf(" many second the phone waits before it re-registers.\n");
|
||||
printf(" -S --sysinfo pureg=0 | pureg=1\n");
|
||||
printf(" If 1, phone registers on every power on (default = '%d')\n", pureg);
|
||||
printf(" -S --sysinfo pdreg=0 | pdreg=1\n");
|
||||
printf(" If 1, phone de-registers on every power down (default = '%d')\n", pureg);
|
||||
printf(" -S --sysinfo locaid=<location area ID > | locaid=-1 to disable\n");
|
||||
printf(" (default = '%d')\n", locaid);
|
||||
printf(" If it changes, phone re-registers.\n");
|
||||
printf(" -S --sysinfo regh=0 | regh=1\n");
|
||||
printf(" If 1, phone registers only if System ID matches (default = '%d')\n", regh);
|
||||
printf(" -S --sysinfo regr=0 | regr=1\n");
|
||||
printf(" If 1, phone registers only if System ID is different (default = '%d')\n", regr);
|
||||
printf("\nstation-id: Give 10 digit station-id, you don't need to enter it for every\n");
|
||||
printf(" start of this program.\n");
|
||||
}
|
||||
|
||||
static int handle_options(int argc, char **argv)
|
||||
{
|
||||
const char *p;
|
||||
int skip_args = 0;
|
||||
int rc;
|
||||
|
||||
static struct option long_options_special[] = {
|
||||
{"channel-type", 1, 0, 't'},
|
||||
{"flip-polarity", 1, 0, 'F'},
|
||||
{"ms-power", 1, 0, 'P'},
|
||||
{"sysinfo", 1, 0, 'S'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
set_options_common("t:F:P:S:", long_options_special);
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
|
||||
c = getopt_long(argc, argv, optstring, long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
if (!strcmp(optarg, "list")) {
|
||||
amps_channel_list();
|
||||
exit(0);
|
||||
}
|
||||
rc = amps_channel_by_short_name(optarg);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error, channel type '%s' unknown. Please use '-t list' to get a list. I suggest to use the default.\n", optarg);
|
||||
exit(0);
|
||||
}
|
||||
OPT_ARRAY(num_chan_type, chan_type, rc)
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'F':
|
||||
if (!strcasecmp(optarg, "no"))
|
||||
flip_polarity = "no";
|
||||
else if (!strcasecmp(optarg, "yes"))
|
||||
flip_polarity = "yes";
|
||||
else {
|
||||
fprintf(stderr, "Given polarity '%s' is illegal, see help!\n", optarg);
|
||||
exit(0);
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'P':
|
||||
ms_power = atoi(optarg);
|
||||
if (ms_power > 3)
|
||||
ms_power = 3;
|
||||
if (ms_power < 0)
|
||||
ms_power = 0;
|
||||
skip_args += 2;
|
||||
break;
|
||||
case 'S':
|
||||
p = strchr(optarg, '=');
|
||||
if (!p) {
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' requires '=' character to set value, see help!\n", optarg);
|
||||
exit(0);
|
||||
}
|
||||
p++;
|
||||
if (!strncasecmp(optarg, "sid=", 4)) {
|
||||
if (!strcasecmp(p, "list")) {
|
||||
list_stations();
|
||||
exit(0);
|
||||
}
|
||||
sid = atoi(p);
|
||||
if (sid > 32767)
|
||||
sid = 32767;
|
||||
if (sid < 0)
|
||||
sid = 0;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "dcc=", 4)) {
|
||||
dcc = atoi(p);
|
||||
if (dcc > 3)
|
||||
dcc = 3;
|
||||
if (dcc < 0)
|
||||
dcc = 0;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "scc=", 4)) {
|
||||
scc = atoi(p);
|
||||
if (scc > 2)
|
||||
scc = 2;
|
||||
if (scc < 0)
|
||||
scc = 0;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "regincr=", 4)) {
|
||||
regincr = atoi(p);
|
||||
} else
|
||||
if (!strncasecmp(optarg, "pureg=", 4)) {
|
||||
pureg = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "pdreg=", 4)) {
|
||||
pdreg = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "locaid=", 4)) {
|
||||
locaid = atoi(p);
|
||||
if (locaid > 4095)
|
||||
locaid = 4095;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "regh=", 4)) {
|
||||
regh = atoi(p) & 1;
|
||||
} else
|
||||
if (!strncasecmp(optarg, "regr=", 4)) {
|
||||
regr = atoi(p) & 1;
|
||||
} else {
|
||||
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
|
||||
exit(0);
|
||||
}
|
||||
skip_args += 2;
|
||||
break;
|
||||
default:
|
||||
opt_switch_common(c, argv[0], &skip_args);
|
||||
}
|
||||
}
|
||||
|
||||
free(long_options);
|
||||
|
||||
return skip_args;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int skip_args;
|
||||
const char *station_id = "";
|
||||
int polarity;
|
||||
int i;
|
||||
|
||||
/* override default */
|
||||
samplerate = 96000;
|
||||
|
||||
/* init common tones */
|
||||
init_tones();
|
||||
init_noanswer();
|
||||
init_outoforder();
|
||||
init_invalidnumber();
|
||||
init_congestion();
|
||||
|
||||
skip_args = handle_options(argc, argv);
|
||||
argc -= skip_args;
|
||||
argv += skip_args;
|
||||
|
||||
if (argc > 1) {
|
||||
station_id = argv[1];
|
||||
if (strlen(station_id) != 10) {
|
||||
printf("Given station ID '%s' does not have 10 digits\n", station_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!num_kanal) {
|
||||
printf("No channel (\"Kanal\") is specified, I suggest channel 334.\n\n");
|
||||
print_help(argv[-skip_args]);
|
||||
return 0;
|
||||
}
|
||||
if (num_kanal == 1 && num_sounddev == 0)
|
||||
num_sounddev = 1; /* use defualt */
|
||||
if (num_kanal != num_sounddev) {
|
||||
fprintf(stdout, "You need to specify as many sound devices as you have channels.\n");
|
||||
exit(0);
|
||||
}
|
||||
if (num_kanal == 1 && num_chan_type == 0)
|
||||
num_chan_type = 1; /* use defualt */
|
||||
if (num_kanal != num_chan_type) {
|
||||
fprintf(stdout, "You need to specify as many channel types as you have channels.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!loopback)
|
||||
print_image();
|
||||
sid_stations(sid);
|
||||
|
||||
/* init functions */
|
||||
if (use_mncc_sock) {
|
||||
rc = mncc_init("/tmp/bsc_mncc");
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to setup MNCC socket. Quitting!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
dsp_init();
|
||||
init_frame();
|
||||
rc = call_init(station_id, call_sounddev, samplerate, latency, 10, loopback);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to create call control instance. Quitting!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check for mandatory CC */
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
if (chan_type[i] == CHAN_TYPE_CC || chan_type[i] == CHAN_TYPE_CC_PC || chan_type[i] == CHAN_TYPE_CC_PC_VC)
|
||||
break;
|
||||
}
|
||||
if (i == num_kanal) {
|
||||
fprintf(stderr, "You must define at least one CC (control) or combined channel type. Quitting!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check for mandatory PC */
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
if (chan_type[i] == CHAN_TYPE_CC_PC || chan_type[i] == CHAN_TYPE_CC_PC_VC)
|
||||
break;
|
||||
}
|
||||
if (i == num_kanal) {
|
||||
fprintf(stderr, "You must define at least one PC (paging) or combined channel type. Quitting!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check for mandatory VC */
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
if (chan_type[i] == CHAN_TYPE_VC || chan_type[i] == CHAN_TYPE_CC_PC_VC)
|
||||
break;
|
||||
}
|
||||
if (i == num_kanal)
|
||||
fprintf(stderr, "You did not define any VC (voice) channel. You will not be able to make any call.\n");
|
||||
|
||||
if (!do_pre_emphasis || !do_de_emphasis) {
|
||||
fprintf(stderr, "*******************************************************************************\n");
|
||||
fprintf(stderr, "I strongly suggest to let me do pre- and de-emphasis (options -E -e)!\n");
|
||||
fprintf(stderr, "Use a transmitter/receiver without emphasis and let me do that!\n");
|
||||
fprintf(stderr, "Because carrier FSK signalling does not use emphasis, I like to control\n");
|
||||
fprintf(stderr, "emphasis by myself for best results.\n");
|
||||
fprintf(stderr, "*******************************************************************************\n");
|
||||
}
|
||||
|
||||
if (!strcmp(flip_polarity, "no"))
|
||||
polarity = 1; /* positive */
|
||||
else if (!strcmp(flip_polarity, "yes"))
|
||||
polarity = -1; /* negative */
|
||||
else {
|
||||
fprintf(stderr, "You must define, if the the TX deviation polarity has to be flipped. (-F yes | no) See help.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* create transceiver instance */
|
||||
for (i = 0; i < num_kanal; i++) {
|
||||
amps_si si;
|
||||
|
||||
init_sysinfo(&si, ms_power, ms_power, dcc, sid >> 1, regh, regr, pureg, pdreg, locaid, regincr);
|
||||
rc = amps_create(kanal[i], chan_type[i], sounddev[i], samplerate, cross_channels, rx_gain, do_pre_emphasis, do_de_emphasis, write_wave, read_wave, &si, sid, scc, polarity, loopback);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
||||
goto fail;
|
||||
}
|
||||
printf("Base station on channel %d ready, please tune transmitter to %.3f MHz and receiver to %.3f MHz.\n", kanal[i], amps_channel2freq(kanal[i], 0), amps_channel2freq(kanal[i], 1));
|
||||
}
|
||||
|
||||
signal(SIGINT,sighandler);
|
||||
signal(SIGHUP,sighandler);
|
||||
signal(SIGTERM,sighandler);
|
||||
signal(SIGPIPE,sighandler);
|
||||
|
||||
if (rt_prio > 0) {
|
||||
struct sched_param schedp;
|
||||
int rc;
|
||||
|
||||
memset(&schedp, 0, sizeof(schedp));
|
||||
schedp.sched_priority = rt_prio;
|
||||
rc = sched_setscheduler(0, SCHED_RR, &schedp);
|
||||
if (rc)
|
||||
fprintf(stderr, "Error setting SCHED_RR with prio %d\n", rt_prio);
|
||||
}
|
||||
|
||||
main_loop(&quit, latency);
|
||||
|
||||
if (rt_prio > 0) {
|
||||
struct sched_param schedp;
|
||||
|
||||
memset(&schedp, 0, sizeof(schedp));
|
||||
schedp.sched_priority = 0;
|
||||
sched_setscheduler(0, SCHED_OTHER, &schedp);
|
||||
}
|
||||
|
||||
fail:
|
||||
/* cleanup functions */
|
||||
call_cleanup();
|
||||
if (use_mncc_sock)
|
||||
mncc_exit();
|
||||
|
||||
/* destroy transceiver instance */
|
||||
while (sender_head)
|
||||
amps_destroy(sender_head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
|
||||
void init_noanswer(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
|
||||
void init_outoforder(void);
|
||||
|
|
@ -0,0 +1,738 @@
|
|||
#include <stdio.h>
|
||||
#include "stations.h"
|
||||
|
||||
/*
|
||||
1: the SID, system Identification number
|
||||
2: the BID, the billing identification number, or 0= if same as the SID
|
||||
3: a City in the area of the service (multiple cities may be listed)
|
||||
4: the Postal Code for the State or Province of the City in column 3 (Note: BH was used for Bahamas.)
|
||||
5: the telephone company name
|
||||
6: a customer service number for the area indicated by columns 3 and 4
|
||||
7: the clearing house that handles roamers' billing records
|
||||
*/
|
||||
static struct amps_stations {
|
||||
int sid, bid;
|
||||
const char *city, *state, *company, *customer_service, *clearing_house;
|
||||
} amps_stations[] = {
|
||||
{ 1, 0, "Chicago", "IL", "Cellular One", "800 235 5663", "GTEDS" },
|
||||
{ 2, 0, "Los Angles", "CA", "Pactel Cellular", "714 553 6100", "GTEDS" },
|
||||
{ 2, 0, "Palm Springs", "CA", "Pactel Cellular", "714 553 6100", "GTEDS" },
|
||||
{ 3, 0, "Buffalo", "NY", "Buffalo Telephone Company", "716 854 5076", "BANK/IL" },
|
||||
{ 4, 0, "San Diego", "CA", "Pactel Cellular", "619 535 6464", "GTEDS" },
|
||||
{ 5, 0, "Milwaukee", "WI", "Cellular One", "414 783 5500", "APPEX" },
|
||||
{ 6, 0, "Seattle", "WA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 6, 0, "Tacoma", "WA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 7, 0, "Boston", "MA", "Cellular One", "617 890 1555", "(Boston)" },
|
||||
{ 8, 0, "Allentown", "PA", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 8, 0, "Philadelphia", "PA", "Bell Atlantic Mobile", "800 953 2200", "GTEDS" },
|
||||
{ 8, 0, "Reading", "PA", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 8, 0, "Trenton", "NJ", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 8, 0, "Wilmington", "DE", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 12, 0, "Beaumont", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 12, 0, "Bryan", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 12, 0, "College Station", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 12, 0, "Galveston", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 12, 0, "Houston", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 12, 0, "Port Arthur", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 13, 0, "Baltimore", "MD", "Cellular One", "301 220 0060", "(Baltimore)" },
|
||||
{ 13, 0, "Washington", "DC", "Cellular One", "301 220 0060", "(Baltimore)" },
|
||||
{ 15, 0, "Cleveland", "OH", "Cellular One", "216 351 1414", "Commonwealth" },
|
||||
{ 15, 0, "Elyria", "OH", "Cellular One", "216 351 1414", "Commonwealth" },
|
||||
{ 15, 0, "Lorain", "OH", "Cellular One", "216 351 1414", "Commonwealth" },
|
||||
{ 17, 0, "St. Louis", "MO", "Cybertel Cellular", "314 423 6500", "GTEDS" },
|
||||
{ 18, 0, "Alexandria", "VA", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 18, 0, "Baltimore", "MD", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 18, 30016, "Frederick", "MD", "Bell Atlantic Mobile", "", "GTEDS" },
|
||||
{ 18, 0, "Silver Spring", "MD", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 18, 0, "Washington", "DC", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 19, 0, "Indianapolis", "IN", "Cellular One", "317 252 5367", "CBIS" },
|
||||
{ 20, 0, "Chicago", "IL", "Ameritech Mobile", "800 221 0994", "GTEDS" },
|
||||
{ 21, 0, "Detroit", "MI", "Cellular One", "313 737 5123", "APPEX" },
|
||||
{ 21, 0, "Flint", "MI", "Cellular One", "313 239 6661", "APPEX" },
|
||||
{ 21, 0, "Grand Rapids", "MI", "Cellular One", "616 451 3523", "APPEX" },
|
||||
{ 21, 0, "Lansing", "MI", "Cellular One", "517 323 9462", "APPEX" },
|
||||
{ 21, 0, "Lima", "OH", "Cellular One", "419 234 1091", "APPEX" },
|
||||
{ 21, 0, "Muskegon", "WI", "Cellular One", "517 323 9492", "APPEX" },
|
||||
{ 21, 0, "Saginaw", "MI", "Cellular One", "517 323 9462", "APPEX" },
|
||||
{ 21, 0, "Toledo", "OH", "Cellular One", "419 243 1091", "APPEX" },
|
||||
{ 22, 0, "Brooklyn", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Congers", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Freehold", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Hackensack", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Madison", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Morristown", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Nassau County", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "New Brunswick", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Newark", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Paterson", "NJ", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Pleasantville", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Rahway", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "Suffolk County", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "White Plains", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 22, 0, "World Trade Center", "NY", "Nynex Mobile Com", "800 227 1069", "Nynex" },
|
||||
{ 23, 0, "Minneapolis", "MN", "Cellular One", "612 867 2273", "APPEX" },
|
||||
{ 24, 0, "Miami", "FL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 24, 0, "West Palm Beach", "FL", "Bell South Mobile", "305 577 4975", "GTEDS" },
|
||||
{ 25, 0, "New York", "NY", "Metro One", "201 587 8000", "APPEX" },
|
||||
{ 26, 0, "Minneapolis", "MN", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 27, 0, "Los Angles", "CA", "LA Cellular Telephone Co.", "213 721 8722", "APPEX" },
|
||||
{ 27, 0, "Oxnard", "CA", "Cellular One", "805 987 0955", "APPEX" },
|
||||
{ 28, 0, "Auburn", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Boston", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Brockton", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Framington", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Lawrence", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Lowell", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Lynn", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "New Bedford", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Providence", "RI", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 28, 0, "Worchester", "MA", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 29, 0, "Philadelphia", "PA", "Metrophone", "800 327 9666", "APPEX" },
|
||||
{ 30, 0, "Portland", "OR", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 30, 0, "Salem", "OR", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 31, 30015, "Napa", "CA", "Cellular One", "800 331 4322", "APPEX" },
|
||||
{ 31, 30017, "Santa Cruz", "CA", "Cellular One", "415 344 1999", "GTEDS" },
|
||||
{ 31, 0, "Oakland", "CA", "Cellular One", "415 344 1999", "APPEX" },
|
||||
{ 31, 0, "San Francisco", "CA", "Cellular One", "415 344 1999", "GTEDS" },
|
||||
{ 31, 0, "San Jose", "CA", "Cellular One", "415 344 1999", "GTEDS" },
|
||||
{ 31, 0, "San Rosa", "CA", "Cellular One", "800 331 4322", "GTEDS" },
|
||||
{ 31, 0, "Vallejo", "CA", "Cellular One", "800 331 4322", "GTEDS" },
|
||||
{ 32, 0, "Pittsburgh", "PA", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 32, 30020, "Altoona", "PA", "Bell Atlantic Mobile", "814 944 3011", "GTEDS" },
|
||||
{ 32, 30022, "Charleston", "WV", "Bell Atlantic Mobile", "304 925 4000", "GTEDS" },
|
||||
{ 32, 30024, "Huntington", "WV", "Bell Atlantic Mobile", "304 525 4101", "GTEDS" },
|
||||
{ 32, 30026, "Johnstown", "PA", "Bell Atlantic Mobile", "814 467 5521", "GTEDS" },
|
||||
{ 32, 30030, "Parkesburg", "PA", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 32, 30034, "State College", "PA", "Bell Atlantic Mobile", "814 231 3900", "GTEDS" },
|
||||
{ 32, 30032, "Steubenville", "OH", "Bell Atlantic Mobile", "614 282 6202", "GTEDS" },
|
||||
{ 32, 30032, "Weirton", "WV", "Bell Atlantic Mobile", "614 282 6202", "GTEDS" },
|
||||
{ 32, 30028, "Wheeling", "WV", "Bell Atlantic Mobile", "614 695 9611", "GTEDS" },
|
||||
{ 33, 0, "Dallas", "TX", "Metrocell Cellular", "214 263 4921", "APPEX" },
|
||||
{ 33, 0, "Ft. Worth", "TX", "Metrocell Cellular", "214 263 4921", "APPEX" },
|
||||
{ 33, 0, "Denton", "TX", "Metrocell Cellular", "214 263 4921", "APPEX" },
|
||||
{ 34, 0, "Athens", "GA", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 34, 0, "Atlanta", "GA", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 35, 0, "Houston", "TX", "Houston Cellular Telephone", "713 688 8020", "APPEX" },
|
||||
{ 36, 0, "New Orleans", "LA", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 37, 0, "Ft. Lauderdale", "FL", "McCaw Cellular", "407 655 1948", "APPEX" },
|
||||
{ 37, 0, "Miami", "FL", "Cellular One", "305 792 2355", "APPEX" },
|
||||
{ 37, 0, "Stuart", "FL", "Cellular One", "407 833 1111", "APPEX" },
|
||||
{ 37, 0, "West Palm Beach", "FL", "Cellular One", "407 833 1111", "APPEX" },
|
||||
{ 38, 0, "Ft. Worth", "TX", "Southwestern Bell Mobile", "800 331 0500", "GTEDS" },
|
||||
{ 38, 0, "Dallas", "TX", "Southwestern Bell Mobile", "800 331 0500", "GTEDS" },
|
||||
{ 38, 0, "Denison", "TX", "Southwestern Bell Mobile", "800 331 0500", "GTEDS" },
|
||||
{ 38, 0, "Sherman", "TX", "Southwestern Bell Mobile", "800 331 0500", "GTEDS" },
|
||||
{ 39, 0, "Johnstown", "PA", "Cellular One", "814 242 0100", "APPEX" },
|
||||
{ 39, 0, "Pittsburgh", "PA", "Cellular One", "412 471 3922", "APPEX" },
|
||||
{ 39, 30059, "Wheeling", "WV", "Cellular One", "304 281 0100", "APPEX" },
|
||||
{ 40, 0, "Salinas", "CA", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 40, 0, "San Francisco", "CA", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 40, 0, "San Jose", "CA", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 40, 0, "San Rosa", "CA", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 40, 30002, "Santa Barbara", "CA", "GTE Mobile", "800 366 5665", "GTEDS" },
|
||||
{ 41, 0, "Athens", "GA", "Pactel Cellular", "404 449 3900", "GTEDS" },
|
||||
{ 41, 0, "Atlanta", "GA", "Pactel Cellular", "404 449 3900", "GTEDS" },
|
||||
{ 42, 0, "Brandenton", "FL", "GTE Mobile", "813 221 1662", "GTEDS" },
|
||||
{ 42, 0, "Ft. Meyers", "FL", "GTE Mobile", "800 877 5665", "GTEDS" },
|
||||
{ 42, 0, "Lakeland", "FL", "GTE Mobile", "800 877 5665", "GTEDS" },
|
||||
{ 42, 0, "Sarasota", "FL", "GTE Mobile", "800 877 5665", "GTEDS" },
|
||||
{ 42, 0, "Tampa", "FL", "GTE Mobile", "800 877 5665", "GTEDS" },
|
||||
{ 42, 0, "Venice", "FL", "GTE Mobile", "800 877 5665", "GTEDS" },
|
||||
{ 42, 0, "Winter Haven", "FL", "GTE Mobile", "800 877 5665", "GTEDS" },
|
||||
{ 43, 0, "San Diego", "CA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 45, 0, "Colorado Springs", "CO", "Cellular One", "303 831 1200", "APPEX" },
|
||||
{ 45, 0, "Denver", "CO", "Cellular One", "303 831 1200", "APPEX" },
|
||||
{ 45, 0, "Ft. Collins", "CO", "Cellular One", "303 831 1200", "APPEX" },
|
||||
{ 45, 0, "Greely", "CO", "Cellular One", "303 831 1200", "APPEX" },
|
||||
{ 46, 0, "St. Louis", "MO", "Southwestern Bell Mobile", "314 542 9999", "GTEDS" },
|
||||
{ 47, 0, "Bellingham", "WA", "Cellular One", "206 285 2273", "APPEX" },
|
||||
{ 47, 0, "Bremerton", "WA", "Cellular One", "206 285 2273", "APPEX" },
|
||||
{ 47, 0, "Olympia", "WA", "Cellular One", "206 285 2273", "APPEX" },
|
||||
{ 47, 0, "Seattle", "WA", "Cellular One", "206 285 2273", "APPEX" },
|
||||
{ 47, 0, "Tacoma", "WA", "Cellular One", "206 285 2273", "APPEX" },
|
||||
{ 48, 0, "Phoenix", "AZ", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 51, 0, "Cincinnati", "OH", "Cellular One", "513 733 5515", "Commonwealth" },
|
||||
{ 51, 0, "Hamilton", "OH", "Cellular One", "513 733 5515", "Commonwealth" },
|
||||
{ 52, 0, "Kansas City", "KS", "Southwestern Bell Mobile", "913 894 1600", "GTEDS" },
|
||||
{ 52, 0, "Kansas City", "MO", "Southwestern Bell Mobile", "913 894 1600", "GTEDS" },
|
||||
{ 52, 0, "Lawrence", "KS", "Southwestern Bell Mobile", "913 894 1600", "GTEDS" },
|
||||
{ 52, 0, "St. Joseph", "MO", "Southwestern Bell Mobile", "913 894 1600", "GTEDS" },
|
||||
{ 52, 0, "Topeka", "KS", "Southwestern Bell Mobile", "913 894 1600", "GTEDS" },
|
||||
{ 53, 0, "Phoenix", "AZ", "Metro Mobile", "602 731 6000", "APPEX" },
|
||||
{ 53, 30053, "Tuscon", "AZ", "Metro Mobile", "602 628 9541", "APPEX" },
|
||||
{ 54, 0, "Akron", "OH", "GTE Mobile", "800 669 5665", "GTEDS" },
|
||||
{ 54, 0, "Canton", "OH", "GTE Mobile", "800 669 5665", "GTEDS" },
|
||||
{ 54, 0, "Cleveland", "OH", "GTE Mobile", "800 669 5665", "GTEDS" },
|
||||
{ 54, 0, "Elyria", "OH", "GTE Mobile", "800 669 5665", "GTEDS" },
|
||||
{ 54, 0, "Erie", "PA", "GTE Mobile", "800 669 5665", "GTEDS" },
|
||||
{ 54, 0, "Lorain", "OH", "GTE Mobile", "800 669 5665", "GTEDS" },
|
||||
{ 56, 0, "Buffalo", "NY", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 57, 0, "New Orleans", "LA", "Cellular One", "504 830 5400", "GTEDS" },
|
||||
{ 58, 0, "Denver", "CO", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 59, 30057, "Kansas City", "KS", "Cellular One", "913 432 3141", "APPEX" },
|
||||
{ 59, 30057, "Kansas City", "MO", "Cellular One", "913 432 3141", "APPEX" },
|
||||
{ 59, 0, "Lawrence", "KS", "Cellular One", "913 842 0577", "APPEX" },
|
||||
{ 59, 0, "Topeka", "KS", "Cellular One", "913 234 4984", "APPEX" },
|
||||
{ 60, 0, "Honolulu", "HI", "GTE Mobile", "808 941 9934", "GTEDS" },
|
||||
{ 61, 0, "Eugene", "OR", "Cellular One", "503 345 1818", "APPEX" },
|
||||
{ 61, 0, "Medford", "OR", "Cellular One", "503 944 5555", "APPEX" },
|
||||
{ 61, 0, "Portland", "OR", "Cellular One", "503 228 1717", "APPEX" },
|
||||
{ 61, 0, "Salem", "OR", "Cellular One", "503 364 3335", "APPEX" },
|
||||
{ 62, 0, "Memphis", "TN", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 63, 0, "Albany", "NY", "Cellular One", "518 465 7300", "BANK/IL" },
|
||||
{ 64, 0, "Las Vegas", "NV", "Centel Cellular", "702 365 6500", "GTEDS" },
|
||||
{ 65, 0, "Louisville", "KY", "Cellular One", "502 582 2355", "APPEX" },
|
||||
{ 68, 0, "Orlando", "FL", "Bell South Mobile", "305 577 4975", "GTEDS" },
|
||||
{ 69, 0, "Durham", "NC", "Cellular One", "919 481 1181", "GTEDS" },
|
||||
{ 69, 0, "Raleigh", "NC", "Cellular One", "919 481 1181", "GTEDS" },
|
||||
{ 70, 0, "Wichita", "KS", "Southwestern Bell Mobile", "316 687 2355", "GTEDS" },
|
||||
{ 71, 0, "Richmond", "VA", "Cellular One", "804 288 3805", "GTEDS" },
|
||||
{ 73, 0, "Akron", "OH", "Cellular One", "216 867 3900", "Commonwealth" },
|
||||
{ 73, 0, "Canton", "OH", "Cellular One", "216 867 3900", "Commonwealth" },
|
||||
{ 74, 0, "Bristol", "TX", "Centel Cellular", "", "GTEDS" },
|
||||
{ 74, 0, "Johnson City", "TN", "Centel Cellular", "", "GTEDS" },
|
||||
{ 74, 0, "Kingsport", "TN", "Centel Cellular", "", "GTEDS" },
|
||||
{ 75, 0, "Jacksonville", "FL", "Cellular One", "904 731 2355", "APPEX" },
|
||||
{ 76, 0, "Louisville", "KY", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 77, 0, "Syracuse", "NY", "Cellular One", "315 446 0400", "Cell-T" },
|
||||
{ 78, 0, "Albany", "NY", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 79, 0, "Albuquerque", "NM", "Metro Mobile", "505 266 9000", "APPEX" },
|
||||
{ 80, 0, "Anderson", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Bloomington", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Ft. Wayne", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Indianapolis", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Kokomo", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Lafayette", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Muncie", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 80, 0, "Terre Haute", "IN", "GTE Mobile", "800 669 3001", "GTEDS" },
|
||||
{ 81, 0, "Mobile", "AL", "Gulf Coast Cellular", "205 343 9700", "Cell-T" },
|
||||
{ 83, 0, "Newport News", "VA", "Centel Cellular", "804 473 9600", "GTEDS" },
|
||||
{ 83, 0, "Norfolk", "VA", "Centel Cellular", "804 473 9600", "GTEDS" },
|
||||
{ 83, 0, "Virginia Beach", "VA", "Centel Cellular", "804 473 9600", "GTEDS" },
|
||||
{ 84, 0, "Aiken", "GA", "Cellular Phone of", "404 738 2355", "GTEDS" },
|
||||
{ 84, 0, "Augusta", "GA", "Cellular Phone of", "404 738 2355", "GTEDS" },
|
||||
{ 85, 0, "Baton Rouge", "LA", "Cellular One", "504 291 9703", "GTEDS" },
|
||||
{ 86, 0, "Syracuse", "NY", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 88, 0, "SNET", "CT", "SNET Cellular", "203 553 7594", "GTEDS" },
|
||||
{ 88, 30006, "Springfield", "MA", "SNET Cellular", "203 553 7594", "GTEDS" },
|
||||
{ 89, 0, "Sharon", "PA", "Cellular One", "412 866 5000", "APPEX" },
|
||||
{ 89, 0, "Warren", "OH", "Cellular One", "216 565 5000", "APPEX" },
|
||||
{ 89, 0, "Youngstown", "OH", "Cellular One", "216 565 5000", "APPEX" },
|
||||
{ 91, 0, "Provo", "UT", "Cellular One", "801 359 2273", "APPEX" },
|
||||
{ 91, 0, "Salt Lake City", "UT", "Cellular One", "801 359 2273", "APPEX" },
|
||||
{ 92, 0, "El Paso", "TX", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 92, 0, "Las Cruces", "NM", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 93, 0, "Knoxville", "TN", "Cellular One", "615 584 2355", "APPEX" },
|
||||
{ 94, 0, "Salt Lake City", "UT", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 95, 0, "Greensboro", "NC", "Cellular One", "919 668 3600", "GTEDS" },
|
||||
{ 96, 0, "Harrisburg", "PA", "Centel Cellular", "717 545 3300", "GTEDS" },
|
||||
{ 96, 0, "Lancaster", "PA", "Centel Cellular", "717 545 3300", "GTEDS" },
|
||||
{ 96, 0, "York", "PA", "Centel Cellular", "717 545 3300", "GTEDS" },
|
||||
{ 97, 30097, "El Paso", "TX", "Metro Mobile", "915 532 5559", "APPEX" },
|
||||
{ 97, 30097, "Las Cruces", "NM", "Metro Mobile", "505 526 2233", "APPEX" },
|
||||
{ 98, 0, "Anniston", "AL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 98, 0, "Birmingham", "AL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 98, 0, "Tuscaloosa", "AL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 100, 0, "Fayetteville", "NC", "Centel Cellular", "919 833 7494", "GTEDS" },
|
||||
{ 103, 0, "Allentown", "PA", "Cellular One", "215 434 2355", "GTEDS" },
|
||||
{ 103, 30023, "Reading", "PA", "Cellular One", "215 434 2355", "GTEDS" },
|
||||
{ 103, 0, "York", "PA", "Cellular One", "717 579 2355", "GTEDS" },
|
||||
{ 104, 0, "Knoxville", "TN", "US Cellular", "615 584 9500", "GTEDS" },
|
||||
{ 105, 0, "NE PA", "PA", "Cellular One", "717 434 2355", "GTEDS" },
|
||||
{ 106, 0, "Baton Rouge", "LA", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 107, 0, "Austin", "TX", "Cellular One", "512 388 6777", "APPEX" },
|
||||
{ 110, 0, "Albuquerque", "NM", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 111, 0, "Tulsa", "OK", "Cellular One", "918 584 7722", "APPEX" },
|
||||
{ 112, 0, "Sacramemto", "CA", "Pactel Cellular", "916 520 0645", "GTEDS" },
|
||||
{ 113, 30043, "Anniston", "AL", "Cellular One", "205 942 2355", "APPEX" },
|
||||
{ 113, 0, "Birmingham", "AL", "Cellular One", "205 942 2355", "APPEX" },
|
||||
{ 113, 30025, "Florence", "AL", "Cellular One", "205 942 2355", "APPEX" },
|
||||
{ 113, 30029, "Gadsden", "AL", "Cellular One", "205 942 2355", "APPEX" },
|
||||
{ 114, 0, "Charlotte", "NC", "Alltel Mobile", "704 529 0001", "GTEDS" },
|
||||
{ 116, 0, "Anderson", "SC", "Centel Cellular", "803 297 8860", "GTEDS" },
|
||||
{ 116, 0, "Greenville", "SC", "Centel Cellular", "803 297 8860", "GTEDS" },
|
||||
{ 116, 0, "Spartanburg", "SC", "Centel Cellular", "803 297 8860", "GTEDS" },
|
||||
{ 117, 0, "Rochester", "NY", "Genesse Telephone", "716 232 6600", "BANK/IL" },
|
||||
{ 118, 0, "Clarksville", "TN", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 118, 0, "Nashville", "TN", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 119, 0, "Bridgeport", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 119, 0, "Danbury", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 119, 30119, "Fairfield County", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 119, 0, "Hartford", "CT", "Metro Mobile", "203 688 3737", "APPEX" },
|
||||
{ 119, 0, "New Bedford", "MA", "Metro Mobile", "401 272 3800", "APPEX" },
|
||||
{ 119, 0, "New Haven", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 119, 0, "North Bedford", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 119, 0, "Norwalk", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 119, 0, "Norwich", "CT", "Metro Mobile", "203 688 3737", "APPEX" },
|
||||
{ 119, 0, "Pittsfield", "MA", "Metro Mobile", "203 688 3737", "APPEX" },
|
||||
{ 119, 0, "Providence", "RI", "Metro Mobile", "401 272 3800", "APPEX" },
|
||||
{ 119, 31119, "Springfield", "MA", "Metro Mobile", "203 688 3737", "APPEX" },
|
||||
{ 119, 0, "Waterbury", "CT", "Metro Mobile", "203 852 9292", "APPEX" },
|
||||
{ 120, 0, "Mobile", "AL", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 120, 0, "Pensacola", "FL", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 122, 0, "San Antonio", "TX", "Southwestern Bell Mobile", "512 646 9955", "GTEDS" },
|
||||
{ 123, 0, "Wilmington", "DE", "Cellular One", "302 737 3333", "APPEX" },
|
||||
{ 126, 0, "Sharon", "PA", "Centel Cellular", "216 758 4502", "GTEDS" },
|
||||
{ 126, 0, "Warren", "OH", "Centel Cellular", "216 758 4502", "GTEDS" },
|
||||
{ 126, 0, "Youngstown", "OH", "Centel Cellular", "216 758 4502", "GTEDS" },
|
||||
{ 127, 0, "Charleston", "SC", "Cellular One", "803 763 6363", "GTEDS" },
|
||||
{ 129, 0, "Sacramemto", "CA", "Cellular One", "916 923 2400", "APPEX" },
|
||||
{ 129, 0, "Yuba City", "CA", "Cellular One", "916 923 2400", "APPEX" },
|
||||
{ 130, 0, "Toledo", "OH", "Centel Cellular", "419 893 1077", "GTEDS" },
|
||||
{ 131, 0, "Abilene", "TX", "Cellular One", "", "GTEDS" },
|
||||
{ 133, 0, "Columbus", "OH", "Cellular One", "614 846 7317", "Commonwealth" },
|
||||
{ 136, 0, "Jacksonville", "FL", "Bell South Mobile", "305 577 4975", "GTEDS" },
|
||||
{ 137, 0, "Omaha", "NE", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 139, 0, "Anderson", "SC", "Metro Mobile", "803 234 7954", "APPEX" },
|
||||
{ 139, 30139, "Charlotte", "NC", "Metro Mobile", "704 552 5185", "APPEX" },
|
||||
{ 139, 31139, "Greenville", "SC", "Metro Mobile", "803 234 7954", "APPEX" },
|
||||
{ 140, 0, "Tuscon", "AZ", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 142, 0, "Greensboro", "NC", "Centel Cellular", "919 299 3333", "GTEDS" },
|
||||
{ 142, 0, "Winston-Salem", "NC", "Centel Cellular", "919 299 3333", "GTEDS" },
|
||||
{ 143, 0, "Memphis", "TN", "Cellular One", "901 683 2355", "APPEX" },
|
||||
{ 144, 0, "Burlington", "NC", "Centel Cellular", "919 833 7494", "GTEDS" },
|
||||
{ 144, 0, "Durham", "NC", "Centel Cellular", "919 833 7494", "GTEDS" },
|
||||
{ 144, 0, "Raleigh", "NC", "Centel Cellular", "919 833 7494", "GTEDS" },
|
||||
{ 146, 0, "Oklahoma City", "OK", "Southwestern Bell Mobile", "405 720 2212", "GTEDS" },
|
||||
{ 148, 0, "Chattanooga", "TN", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 149, 0, "Bristol", "TX", "Cellular One", "615 349 4500", "APPEX" },
|
||||
{ 149, 0, "Johnson City", "TN", "Cellular One", "615 349 4500", "APPEX" },
|
||||
{ 149, 0, "Kingsport", "TN", "Cellular One", "615 349 4500", "APPEX" },
|
||||
{ 150, 0, "Des Moines", "IA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 151, 0, "San Antonio", "TX", "Cellular One", "512 349 2600", "APPEX" },
|
||||
{ 152, 0, "Omaha", "NE", "Centel Cellular", "402 330 6500", "GTEDS" },
|
||||
{ 153, 0, "Fresno", "CA", "Cellular One", "209 438 8888", "APPEX" },
|
||||
{ 153, 0, "Visilia", "CA", "Cellular One", "209 738 0999", "APPEX" },
|
||||
{ 156, 0, "Charleston", "SC", "Centel Cellular", "803 767 1340", "GTEDS" },
|
||||
{ 159, 0, "Harrisburg", "PA", "Cellular One", "717 579 2355", "GTEDS" },
|
||||
{ 159, 30011, "Lancaster", "PA", "Cellular One", "717 579 2355", "GTEDS" },
|
||||
{ 159, 30013, "York", "PA", "Cellular One", "717 579 2355", "GTEDS" },
|
||||
{ 160, 0, "Jackson", "MS", "Alltel Mobile", "601 354 1212", "GTEDS" },
|
||||
{ 161, 0, "Chattanooga", "TN", "Cellular One", "615 892 2355", "APPEX" },
|
||||
{ 162, 0, "Fresno", "CA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 162, 0, "Visilia", "CA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 163, 0, "Dayton", "OH", "Cellular One", "513 477 1999", "GTEDS" },
|
||||
{ 163, 0, "Springfield", "OH", "Cellular One", "513 434 2355", "Commonwealth" },
|
||||
{ 164, 0, "Austin", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 165, 0, "Wichita", "KS", "Cellular One", "316 686 8811", "APPEX" },
|
||||
{ 166, 0, "Tulsa", "OK", "US Cellular", "918 665 0101", "GTEDS" },
|
||||
{ 167, 0, "Honolulu", "HI", "Honolulu Cellular", "808 545 4755", "APPEX" },
|
||||
{ 168, 0, "Newport News", "VA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 168, 0, "Norfolk", "VA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 169, 0, "Oklahoma City", "OK", "Cellular One", "405 843 9113", "APPEX" },
|
||||
{ 170, 0, "Petersburg", "VA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 170, 0, "Richmond", "VA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 171, 0, "Gulf of Mexico", "XX", "Petrocomm", "800 257 3876", "GTEDS" },
|
||||
{ 173, 0, "Long Branch", "NJ", "Cellular One", "800 227 9222", "APPEX" },
|
||||
{ 173, 0, "New Brunswick", "NJ", "Cellular One", "800 227 9222", "APPEX" },
|
||||
{ 175, 0, "Brandenton", "FL", "Cellular One", "813 221 1662", "APPEX" },
|
||||
{ 175, 0, "Lakeland", "FL", "Cellular One", "813 221 1662", "APPEX" },
|
||||
{ 175, 0, "Melbourne", "FL", "Cellular One", "407 258 7100", "APPEX" },
|
||||
{ 175, 0, "Orlando", "FL", "Cellular One", "407 425 2355", "APPEX" },
|
||||
{ 175, 0, "Sarasota", "FL", "Cellular One", "813 221 1662", "APPEX" },
|
||||
{ 175, 0, "Tampa", "FL", "Cellular One", "813 221 1662", "APPEX" },
|
||||
{ 179, 0, "Clarksville", "TN", "Cellular One", "615 645 2200", "APPEX" },
|
||||
{ 179, 0, "Mt. Juliet", "TN", "Cellular One", "615 269 2273", "APPEX" },
|
||||
{ 179, 0, "Nashville", "TN", "Cellular One", "615 269 2273", "APPEX" },
|
||||
{ 180, 0, "Colorado Springs", "CO", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 181, 0, "Augusta", "GA", "Cellular One", "404 868 0086", "GTEDS" },
|
||||
{ 182, 0, "Columbia", "SC", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 183, 0, "Bakersfield", "CA", "Bakersfield Cellular", "805 327 8700", "Cell-T" },
|
||||
{ 184, 0, "Corpus Christi", "TX", "Southwestern Bell Mobile", "512 854 5678", "GTEDS" },
|
||||
{ 185, 0, "Beaumont", "TX", "Cellular One", "409 898 8000", "Cell-T" },
|
||||
{ 186, 0, "Davenport", "IA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 186, 0, "Bettendorf", "IA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 186, 0, "Rock Island", "IL", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 186, 0, "Moline", "IL", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 188, 0, "Lansing", "MI", "Century Cellunet", "517 393 0311", "GTEDS" },
|
||||
{ 189, 0, "Columbia", "SC", "Metro Mobile", "803 731 8300", "APPEX" },
|
||||
{ 190, 0, "Evansville", "IN", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 190, 0, "Henderson", "KY", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 190, 0, "Owensboro", "KY", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 191, 0, "Corpus Christi", "TX", "Cellular One", "512 937 8243", "APPEX" },
|
||||
{ 193, 0, "Davenport", "IA", "Cellular One", "319 388 8000", "GTEDS" },
|
||||
{ 193, 0, "Bettendorf", "IA", "Cellular One", "319 388 8000", "GTEDS" },
|
||||
{ 193, 0, "Rock Island", "IL", "Cellular One", "319 388 8000", "GTEDS" },
|
||||
{ 193, 0, "Moline", "IL", "Cellular One", "319 388 8000", "GTEDS" },
|
||||
{ 194, 0, "Gulf of Mexico", "XX", "Coastel Cellular", "800 822 8400", "GTEDS" },
|
||||
{ 195, 0, "Des Moines", "IA", "Cellular One", "515 223 6611", "GTEDS" },
|
||||
{ 197, 0, "Evansville", "IN", "Cellular One", "812 464 5111", "GTEDS" },
|
||||
{ 198, 0, "Huntsville", "AL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 199, 0, "Ft. Wayne", "IN", "Cellular One", "219 484 2500", "CBIS" },
|
||||
{ 203, 0, "Huntsville", "AL", "Cellular One", "205 830 6633", "APPEX" },
|
||||
{ 204, 0, "Albany", "GA", "Alltel Mobile", "912 888 8200", "GTEDS" },
|
||||
{ 206, 0, "Georgetown", "KY", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 206, 0, "Lexington", "KY", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 208, 0, "Little Rock", "AR", "Alltel Mobile", "501 666 6688", "GTEDS" },
|
||||
{ 211, 0, "Las Vegas", "NV", "Cellular One", "702 732 2240", "APPEX" },
|
||||
{ 212, 0, "Alexandria", "LA", "US Cellular", "318 445 2065", "GTEDS" },
|
||||
{ 213, 0, "Lexington", "KY", "Cellular One", "606 223 3700", "APPEX" },
|
||||
{ 214, 0, "Peoria", "IL", "Centel Cellular", "309 693 3800", "GTEDS" },
|
||||
{ 215, 0, "Little Rock", "AR", "Cellular One", "501 225 2355", "APPEX" },
|
||||
{ 215, 0, "Pine Bluff", "AR", "Cellular One", "501 221 1771", "APPEX" },
|
||||
{ 216, 0, "Saginaw", "MI", "Century Cellunet", "517 792 1556", "GTEDS" },
|
||||
{ 217, 30039, "Appleton", "WI", "Cellular One", "414 738 0110", "APPEX" },
|
||||
{ 217, 30041, "Beloit", "WI", "Cellular One", "608 751 2273", "APPEX" },
|
||||
{ 217, 30031, "Green Bay", "WI", "Cellular One", "414 496 2273", "APPEX" },
|
||||
{ 217, 30041, "Janesville", "WI", "Cellular One", "608 751 2273", "APPEX" },
|
||||
{ 217, 30035, "Kenosha", "WI", "Cellular One", "414 652 2022", "APPEX" },
|
||||
{ 217, 0, "Madison", "WI", "Cellular One", "608 271 2273", "APPEX" },
|
||||
{ 217, 0, "Oshkosh", "WI", "Cellular One", "414 738 0110", "APPEX" },
|
||||
{ 217, 30037, "Racine", "WI", "Cellular One", "414 939 2273", "APPEX" },
|
||||
{ 217, 30033, "Rockford", "IL", "Cellular One", "815 494 2273", "APPEX" },
|
||||
{ 220, 0, "Shreveport", "LA", "Century Cellunet", "318 687 8502", "GTEDS" },
|
||||
{ 221, 0, "Peoria", "IL", "US Cellular", "309 685 1234", "GTEDS" },
|
||||
{ 222, 0, "Spokane", "WA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 224, 0, "Modesto", "CA", "Pactel Cellular", "916 520 0645", "GTEDS" },
|
||||
{ 224, 0, "Stockton", "CA", "Pactel Cellular", "916 520 0645", "GTEDS" },
|
||||
{ 226, 0, "Rome", "NY", "Avantage Cellular", "315 797 2041", "GTEDS" },
|
||||
{ 226, 0, "Utica", "NY", "Avantage Cellular", "315 797 2041", "GTEDS" },
|
||||
{ 228, 0, "Bakersfield", "CA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 229, 0, "Longview", "TX", "Cellular One", "318 636 9888", "APPEX" },
|
||||
{ 229, 0, "Marshall", "TX", "Cellular One", "318 636 9888", "APPEX" },
|
||||
{ 229, 0, "Shreveport", "LA", "Cellular One", "318 636 9888", "APPEX" },
|
||||
{ 229, 0, "Texarkana", "TX", "Cellular One", "318 636 9888", "APPEX" },
|
||||
{ 231, 0, "Spokane", "WA", "Cellular One", "509 838 2273", "APPEX" },
|
||||
{ 233, 0, "Modesto", "CA", "Cellular One", "209 572 1004", "APPEX" },
|
||||
{ 233, 0, "Stockton", "CA", "Cellular One", "209 476 1500", "APPEX" },
|
||||
{ 235, 0, "Rome", "NY", "Cellular One", "315 768 4400", "Cell-T" },
|
||||
{ 235, 0, "Utica", "NY", "Cellular One", "315 768 4400", "Cell-T" },
|
||||
{ 240, 0, "Appleton", "WI", "Cellulink", "414 735 9707", "GTEDS" },
|
||||
{ 240, 0, "Oshkosh", "WI", "Cellulink", "414 735 9797", "GTEDS" },
|
||||
{ 241, 0, "Albany", "GA", "Cellular One", "912 888 8228", "APPEX" },
|
||||
{ 244, 0, "Grand Rapids", "MI", "Century Cellunet", "616 940 0985", "GTEDS" },
|
||||
{ 246, 0, "Asheville", "NC", "US Cellular", "704 258 0000", "GTEDS" },
|
||||
{ 247, 0, "Altoona", "PA", "Cellular One", "814 946 4535", "GTEDS" },
|
||||
{ 249, 0, "Amarillo", "TX", "Cellular One", "806 374 1900", "Cell-T" },
|
||||
{ 250, 0, "Atlantic City", "NJ", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 250, 0, "Vineland", "NJ", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 251, 0, "Anchorage", "AK", "Cellular One", "907 561 1122", "APPEX" },
|
||||
{ 255, 0, "Anniston", "AL", "Cellular One", "205 942 2355", "Cell-T" },
|
||||
{ 256, 0, "Battle Creek", "MI", "Century Cellunet", "616 342 6655", "GTEDS" },
|
||||
{ 258, 0, "Bellingham", "WA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 260, 0, "Benton Harbor", "MI", "Century Cellunet", "616 342 6655", "GTEDS" },
|
||||
{ 264, 0, "Gulfport", "MS", "Cellular South", "", "GTEDS" },
|
||||
{ 266, 0, "Binghamton", "NY", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 266, 0, "Elmira", "NY", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 267, 0, "Atlantic City", "NJ", "Cellular One", "", "APPEX" },
|
||||
{ 268, 0, "Bismark", "ND", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 269, 0, "Asheville", "NC", "Cellular One", "", "Cell-T" },
|
||||
{ 271, 0, "Bangor", "ME", "US Cellular", "207 942 0700", "GTEDS" },
|
||||
{ 272, 0, "Boise", "ID", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 276, 0, "Bremerton", "WA", "Cellular One", "800 626 6611", "GTEDS" },
|
||||
{ 277, 0, "Benton Harbor", "MI", "Cellular One", "616 982 9900", "Cincin" },
|
||||
{ 278, 0, "Brownsville", "TX", "Southwestern Bell Mobile", "512 541 6200", "GTEDS" },
|
||||
{ 278, 0, "Harlingen", "TX", "Southwestern Bell Mobile", "512 428 6200", "GTEDS" },
|
||||
{ 278, 0, "McAllen", "TX", "Southwestern Bell Mobile", "512 380 6200", "GTEDS" },
|
||||
{ 279, 0, "Billings", "MT", "Cellular One", "406 652 0466", "GTEDS" },
|
||||
{ 281, 0, "Biloxi", "MS", "Cellular One", "", "GTEDS" },
|
||||
{ 283, 30007, "Binghamton", "NY", "Cellular One", "607 771 8000", "APPEX" },
|
||||
{ 283, 30009, "Elmira", "NY", "Cellular One", "607 737 1000", "APPEX" },
|
||||
{ 284, 0, "Casper", "WY", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 285, 0, "Bismark", "ND", "Cellular One", "701 224 1616", "GTEDS" },
|
||||
{ 286, 0, "Cedar Rapids", "IA", "Centel Cellular", "319 366 5700", "GTEDS" },
|
||||
{ 286, 0, "Iowa City", "IA", "Centel Cellular", "319 366 5700", "GTEDS" },
|
||||
{ 287, 0, "Bloomington", "IN", "Cellular One", "502 528 2355", "APPEX" },
|
||||
{ 289, 0, "Boise", "ID", "Cellular One", "208 345 2355", "GTEDS" },
|
||||
{ 292, 0, "Charlottesville", "VA", "Centel Cellular", "804 973 9100", "GTEDS" },
|
||||
{ 294, 0, "Chico", "CA", "Pactel Cellular", "916 920 0645", "GTEDS" },
|
||||
{ 294, 0, "Redding", "CA", "Pactel Cellular", "916 920 0645", "GTEDS" },
|
||||
{ 297, 0, "Bryan", "TX", "Cellular One", "409 696 2264", "APPEX" },
|
||||
{ 297, 0, "College Station", "TX", "Cellular One", "512 338 6777", "GTEDS" },
|
||||
{ 298, 0, "Columbia", "MO", "US Cellular", "314 474 0400", "GTEDS" },
|
||||
{ 299, 0, "Burlington", "NC", "Gencell", "800 888 7868", "GTEDS" },
|
||||
{ 300, 0, "Burlington", "VT", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 301, 0, "Casper", "WY", "Cellular One", "307 235 0110", "GTEDS" },
|
||||
{ 302, 0, "Columbus", "GA", "Public Service Cellular", "912 841 4117", "GTEDS" },
|
||||
{ 303, 0, "Cedar Rapids", "IA", "US Cellular", "319 365 1000", "GTEDS" },
|
||||
{ 304, 0, "Cumberland", "MD", "Gencell", "800 888 7868", "GTEDS" },
|
||||
{ 306, 0, "Danville", "VA", "Centel Cellular", "804 791 3100", "GTEDS" },
|
||||
{ 307, 0, "Charleston", "WV", "Cellular One", "304 345 2355", "GTEDS" },
|
||||
{ 307, 30047, "Huntington", "WV", "Cellular One", "304 345 2355", "GTEDS" },
|
||||
{ 308, 0, "Daytona Beach", "FL", "Bell South Mobile", "305 577 4975", "GTEDS" },
|
||||
{ 308, 0, "New Smyrna", "FL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 312, 0, "Dothan", "AL", "Graceba Cellular", "205 793 9148", "GTEDS" },
|
||||
{ 314, 0, "Dubuque", "IA", "Centel Cellular", "319 580 0010", "GTEDS" },
|
||||
{ 316, 0, "Duluth", "MN", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 318, 0, "Eau Claire", "WI", "Cellulink", "715 835 7370", "GTEDS" },
|
||||
{ 319, 0, "Columbus", "GA", "Cellular One", "404 596 9041", "APPEX" },
|
||||
{ 321, 0, "Cumberland", "MD", "Cellular One", "814 946 4535", "GTEDS" },
|
||||
{ 323, 0, "Danville", "VA", "Cellular One", "804 791 3453", "GTEDS" },
|
||||
{ 324, 0, "Enid", "OK", "Enid Cellular", "405 375 4111", "GTEDS" },
|
||||
{ 325, 0, "Daytona Beach", "FL", "Cellular One", "904 257 2355", "APPEX" },
|
||||
{ 328, 0, "Eugene", "OR", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 329, 0, "Dothan", "AL", "Cellular One", "205 671 4111", "Cell-T" },
|
||||
{ 330, 0, "Fargo", "ND", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 331, 0, "Dubuque", "IA", "US Cellular", "", "GTEDS" },
|
||||
{ 333, 0, "Duluth", "MN", "Cellular One", "218 727 4700", "GTEDS" },
|
||||
{ 334, 0, "Muscle Shoals", "LA", "Shoals Cellular", "205 383 5111", "GTEDS" },
|
||||
{ 336, 0, "Ft. Collins", "CO", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 336, 0, "Loveland", "CO", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 340, 0, "Ft. Pierce", "FL", "US Cellular", "305 287 7888", "GTEDS" },
|
||||
{ 342, 0, "Fayetteville", "AR", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 342, 0, "Ft. Smith", "AR", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 342, 0, "Rogers", "AR", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 343, 0, "Erie", "PA", "Cellular One", "814 881 0100", "APPEX" },
|
||||
{ 344, 0, "Ft. Walton Beach", "FL", "Centel Cellular", "904 664 2000", "GTEDS" },
|
||||
{ 348, 0, "Gainesville", "FL", "Alltel Cellular", "904 374 8500", "GTEDS" },
|
||||
{ 348, 0, "Ocala", "FL", "Alltel Mobile", "904 237 1100", "GTEDS" },
|
||||
{ 349, 0, "Fayetteville", "NC", "Cellular One", "919 483 1181", "GTEDS" },
|
||||
{ 350, 0, "Florence", "SC", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 355, 0, "Ft. Meyers", "FL", "Cellular One", "813 936 4534", "APPEX" },
|
||||
{ 356, 0, "Grand Forks", "ND", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 357, 0, "Ft. Pierce", "FL", "Cellular One", "407 833 1111", "APPEX" },
|
||||
{ 358, 0, "Great Falls", "MT", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 359, 0, "Ft. Smith", "AR", "Cellular One", "501 783 4600", "GTEDS" },
|
||||
{ 360, 0, "Greely", "CO", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 361, 0, "Ft. Walton Beach", "FL", "Cellular One", "904 433 7300", "GTEDS" },
|
||||
{ 361, 30021, "Pensacola", "FL", "Cellular One", "904 433 7300", "GTEDS" },
|
||||
{ 362, 0, "Green Bay", "WI", "Cellcom", "414 494 2355", "GTEDS" },
|
||||
{ 364, 0, "Hagerstown", "MD", "Bell Atlantic Mobile", "800 922 0204", "GTEDS" },
|
||||
{ 365, 0, "Gainesville", "FL", "Centel Cellular", "904 374 8100", "GTEDS" },
|
||||
{ 368, 0, "Hickory", "NC", "Centel Cellular", "704 327 4000", "GTEDS" },
|
||||
{ 370, 0, "Houma", "LA", "Mobiletel", "504 798 7894", "GTEDS" },
|
||||
{ 370, 0, "Thibodaux", "LA", "Mobiletel", "504 798 7894", "GTEDS" },
|
||||
{ 370, 0, "Larose", "LA", "Mobiletel", "504 798 7894", "GTEDS" },
|
||||
{ 370, 0, "Leeville", "LA", "Mobiletel", "504 798 7894", "GTEDS" },
|
||||
{ 373, 0, "Great Falls", "MT", "Cellular One", "406 727 2355", "GTEDS" },
|
||||
{ 374, 0, "Jackson", "MI", "Century Cellunet", "517 393 0311", "GTEDS" },
|
||||
{ 376, 0, "Jacksonville", "NC", "Centel Cellular", "919 833 7494", "GTEDS" },
|
||||
{ 377, 0, "Florence", "SC", "Cellular One", "803 664 2898", "GTEDS" },
|
||||
{ 381, 0, "Hagerstown", "MD", "Cellular One", "301 331 2355", "GTEDS" },
|
||||
{ 384, 0, "Joplin", "MO", "US Cellular", "417 624 2255", "GTEDS" },
|
||||
{ 385, 0, "Hickory", "NC", "Cellcom", "704 322 7557", "APPEX" },
|
||||
{ 386, 0, "Kalamazoo", "MI", "Century Cellunet", "616 342 6655", "GTEDS" },
|
||||
{ 387, 0, "Houma", "LA", "Cellular One", "504 686 0220", "GTEDS" },
|
||||
{ 387, 0, "Thibodaux", "LA", "Cellular One", "504 686 0220", "GTEDS" },
|
||||
{ 389, 0, "Iowa City", "IA", "Allcell Cellular", "319 351 5888", "CBIS" },
|
||||
{ 392, 0, "Killeen", "TX", "Centel Cellular", "817 771 0077", "GTEDS" },
|
||||
{ 392, 0, "Temple", "TX", "Centel Cellular", "817 771 0077", "GTEDS" },
|
||||
{ 393, 0, "Jacksonville", "NC", "Cellular One", "919 455 9300", "C-Tech" },
|
||||
{ 396, 0, "La Crosse", "WI", "Century Cellunet", "608 788 8000", "GTEDS" },
|
||||
{ 400, 0, "Lake Charles", "LA", "Mercury Cellular", "318 433 6298", "Lake Charles" },
|
||||
{ 401, 0, "Joplin", "MO", "Cellular One", "417 862 6611", "APPEX" },
|
||||
{ 402, 0, "Laredo", "TX", "Laredo Cellular", "512 722 2333", "GTEDS" },
|
||||
{ 403, 0, "Kalamazoo", "MI", "Cellular One", "616 388 8066", "CBIS" },
|
||||
{ 408, 0, "Lawton", "OK", "US Cellular", "405 355 3535", "GTEDS" },
|
||||
{ 409, 0, "Killeen", "TX", "Cellular One", "817 526 6800", "APPEX" },
|
||||
{ 409, 0, "Temple", "TX", "Cellular One", "817 526 6800", "APPEX" },
|
||||
{ 412, 0, "Lima", "OH", "Centel Cellular", "419 893 1077", "GTEDS" },
|
||||
{ 413, 0, "La Crosse", "WI", "US Cellular", "608 781 2600", "GTEDS" },
|
||||
{ 414, 0, "Lafayette", "LA", "Bell South Mobile", "305 577 4975", "GTEDS" },
|
||||
{ 415, 0, "Lafayette", "IN", "McCaw Cellular", "502 582 2273", "GTEDS" },
|
||||
{ 416, 0, "Lincoln", "NE", "Lincoln Telephone Cellular", "402 486 7266", "GTEDS" },
|
||||
{ 417, 0, "Lake Charles", "LA", "Celltelco", "318 279 6532", "GTEDS" },
|
||||
{ 418, 0, "Longview", "TX", "Centel Cellular", "214 561 5575", "GTEDS" },
|
||||
{ 418, 0, "Marshall", "TX", "Centel Cellular", "214 561 5575", "GTEDS" },
|
||||
{ 418, 0, "Tyler", "TX", "Centel Cellular", "214 561 5575", "GTEDS" },
|
||||
{ 422, 0, "Abilene", "TX", "Southwestern Bell Mobile", "915 698 7626", "GTEDS" },
|
||||
{ 422, 0, "Amarillo", "TX", "Southwestern Bell Mobile", "806 353 7447", "GTEDS" },
|
||||
{ 422, 0, "Lubbock", "TX", "Southwestern Bell Mobile", "806 791 0011", "GTEDS" },
|
||||
{ 422, 0, "Midland", "TX", "Southwestern Bell Mobile", "915 563 4611", "GTEDS" },
|
||||
{ 422, 0, "Odessa", "TX", "Southwestern Bell Mobile", "915 563 4611", "GTEDS" },
|
||||
{ 424, 0, "Lynchburg", "VA", "Centel Cellular", "804 528 3500", "GTEDS" },
|
||||
{ 426, 0, "Macon", "GA", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 427, 0, "Auburn", "ME", "US Cellular", "207 782 8010", "GTEDS" },
|
||||
{ 427, 0, "Lewiston", "ME", "US Cellular", "207 782 8010", "GTEDS" },
|
||||
{ 428, 0, "Manchester", "NH", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 428, 0, "Nashua", "NH", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 430, 0, "Mansfield", "OH", "Centel Cellular", "419 893 1077", "GTEDS" },
|
||||
{ 431, 0, "Lafayette", "LA", "Cellular One", "318 984 1777", "APPEX" },
|
||||
{ 436, 0, "Medford", "OR", "US Cellular", "", "GTEDS" },
|
||||
{ 439, 0, "Lubbock", "TX", "Cellular One", "806 797 2355", "GTEDS" },
|
||||
{ 440, 0, "Monroe", "LA", "Century Cellunet", "318 325 3600", "GTEDS" },
|
||||
{ 443, 0, "Macon", "GA", "Cellular One", "912 742 2355", "GTEDS" },
|
||||
{ 443, 0, "Warner Robins", "GA", "Cellular One", "", "GTEDS" },
|
||||
{ 444, 0, "Montgomery", "AL", "Alltel Mobile", "800 255 8351", "GTEDS" },
|
||||
{ 445, 0, "Manchester", "NH", "US Cellular", "603 624 8000", "GTEDS" },
|
||||
{ 447, 0, "Mansfield", "OH", "Cellular One", "419 564 5000", "Commonwealth" },
|
||||
{ 448, 0, "Muskegon", "WI", "Century Cellunet", "616 940 0985", "GTEDS" },
|
||||
{ 451, 0, "Jackson", "MS", "Cellular One", "512 686 2355", "Cell-T" },
|
||||
{ 451, 0, "McAllen", "TX", "Cellular One", "512 686 2355", "Cell-T" },
|
||||
{ 456, 0, "Olympia", "WA", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 462, 0, "Palm Springs", "FL", "Centel Cellular", "904 785 7000", "GTEDS" },
|
||||
{ 462, 0, "Panama City", "FL", "Centel Cellular", "904 785 7000", "GTEDS" },
|
||||
{ 465, 0, "Montgomery", "AL", "Montgomery Cellular", "205 265 2355", "GTEDS" },
|
||||
{ 467, 0, "Muncie", "IN", "Cellular One", "502 582 2355", "APPEX" },
|
||||
{ 473, 0, "Ocala", "FL", "Cellular One", "407 425 2355", "GTEDS" },
|
||||
{ 475, 0, "Odessa", "TX", "Cellular One", "806 797 2355", "GTEDS" },
|
||||
{ 476, 0, "Melbourne", "FL", "Bell South Mobile", "800 351 2400", "GTEDS" },
|
||||
{ 478, 30018, "Pine Bluff", "AK", "Pine Bluff Cellular", "501 536 4200", "GTEDS" },
|
||||
{ 479, 0, "Orange County", "NY", "Cellular One", "914 564 4447", "GTEDS" },
|
||||
{ 480, 0, "Pittsfield", "NY", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 481, 0, "Owensboro", "KY", "US Cellular", "502 685 5111", "GTEDS" },
|
||||
{ 483, 0, "Palm Springs", "FL", "Palmer Comm", "904 769 2269", "GTEDS" },
|
||||
{ 484, 0, "Biddeford", "ME", "Star Cellular", "800 346 9172", "GTEDS" },
|
||||
{ 484, 0, "Dover", "NH", "Star Cellular", "800 346 9172", "GTEDS" },
|
||||
{ 484, 0, "Portsmouth", "NH", "Star Cellular", "800 346 9172", "GTEDS" },
|
||||
{ 484, 0, "Saco", "ME", "Star Cellular", "800 346 9172", "GTEDS" },
|
||||
{ 486, 0, "Orange County", "NY", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 486, 0, "Poughkeepsie", "NY", "Nynex Mobile Com", "", "Nynex" },
|
||||
{ 488, 0, "Provo", "UT", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 494, 0, "Rapid City", "SD", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 498, 0, "Reno", "NV", "Pactel Cellular", "916 920 0645", "GTEDS" },
|
||||
{ 499, 0, "Portland", "ME", "Cellular One", "207 772 9805", "GTEDS" },
|
||||
{ 500, 0, "Richland", "WA", "US Cellular", "", "GTEDS" },
|
||||
{ 501, 0, "Portsmouth", "NH", "Cellular One", "617 890 1555", "(Boston)" },
|
||||
{ 502, 0, "Roanke", "VA", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 503, 0, "Poughkeepsie", "NY", "US Cellular", "914 297 3444", "GTEDS" },
|
||||
{ 504, 0, "Rochester", "MN", "US Cellular", "507 388 3000", "GTEDS" },
|
||||
{ 506, 0, "Rockford", "IL", "Contel Cellular", "800 792 8400", "GTEDS" },
|
||||
{ 510, 0, "San Angelo", "TX", "West Central Cellular", "915 944 9016", "GTEDS" },
|
||||
{ 511, 0, "Rapid City", "SD", "Cellular One", "", "GTEDS" },
|
||||
{ 513, 0, "Redding", "CA", "Cellular One", "916 923 2222", "APPEX" },
|
||||
{ 515, 0, "Reno", "NV", "Cellular One", "702 322 5511", "APPEX" },
|
||||
{ 519, 0, "Roanke", "VA", "Cellular One", "703 345 0808", "Cell-T" },
|
||||
{ 520, 0, "Savannah", "GA", "Savannah Cellular", "912 356 5224", "GTEDS" },
|
||||
{ 521, 0, "Rochester", "MN", "Cellular One", "507 254 2273", "APPEX" },
|
||||
{ 527, 0, "Monterey", "CA", "Cellular One", "408 754 8888", "APPEX" },
|
||||
{ 527, 0, "Salinas", "CA", "Cellular One", "408 647 8888", "APPEX" },
|
||||
{ 530, 0, "Elkhart", "IN", "Centel Cellular", "219 288 2355", "GTEDS" },
|
||||
{ 530, 0, "South Bend", "IN", "Centel Cellular", "219 288 2355", "GTEDS" },
|
||||
{ 531, 0, "Santa Barbara", "CA", "Santa Barbara Cellular", "800 722 7464", "Cell-T" },
|
||||
{ 534, 0, "St. Cloud", "MN", "US Cellular", "612 252 9000", "GTEDS" },
|
||||
{ 539, 0, "Savannah", "GA", "Cellular One", "912 352 3456", "GTEDS" },
|
||||
{ 540, 0, "Sioux Falls", "SD", "US West Cellular", "800 626 6611", "GTEDS" },
|
||||
{ 544, 0, "Talahassee", "FL", "Centel Cellular", "904 668 2200", "GTEDS" },
|
||||
{ 545, 0, "Denison", "TX", "Metrocell Cellular", "214 263 4921", "APPEX" },
|
||||
{ 545, 0, "Sherman", "TX", "Metrocell Cellular", "214 263 4921", "APPEX" },
|
||||
{ 546, 0, "Springfield", "MO", "Alltel Mobile", "417 882 2020", "GTEDS" },
|
||||
{ 547, 0, "Sioux City", "IA", "Centel Cellular", "712 274 2494", "" },
|
||||
{ 549, 0, "South Bend", "IN", "Cellular One", "219 289 0933", "Micro-T" },
|
||||
{ 550, 0, "Texarkana", "TX", "Century Cellunet", "214 793 0500", "GTEDS" },
|
||||
{ 551, 30045, "Bloomington", "IL", "Cellular One", "217 744 3000", "APPEX" },
|
||||
{ 551, 30005, "Champaign", "IL", "Cellular One", "217 744 3000", "APPEX" },
|
||||
{ 551, 30003, "Decatur", "IL", "Cellular One", "217 744 3000", "APPEX" },
|
||||
{ 551, 30001, "Springfield", "IL", "Cellular One", "217 744 3000", "APPEX" },
|
||||
{ 551, 30005, "Urbana", "IL", "Cellular One", "217 744 3000", "APPEX" },
|
||||
{ 555, 0, "Sioux Falls", "SD", "Cellular One", "605 336 0520", "Cell-T" },
|
||||
{ 557, 0, "St. Joseph", "MO", "Cellular One", "816 232 6158", "APPEX" },
|
||||
{ 561, 30019, "State College", "PA", "Cellular One", "717 579 2355", "GTEDS" },
|
||||
{ 562, 0, "Victoria", "TX", "GTE Mobile", "800 347 5665", "GTEDS" },
|
||||
{ 565, 0, "Talahassee", "FL", "Cellular One", "904 386 8999", "APPEX" },
|
||||
{ 566, 0, "Waco", "TX", "Centel Cellular", "817 771 0077", "GTEDS" },
|
||||
{ 567, 0, "Terre Haute", "IN", "Cellular One", "502 582 2355", "APPEX" },
|
||||
{ 568, 0, "Waterloo", "IA", "Centel Cellular", "319 236 0400", "GTEDS" },
|
||||
{ 570, 0, "Wausau", "WI", "US Cellular", "715 842 4200", "GTEDS" },
|
||||
{ 574, 0, "Wichita Falls", "TX", "US Cellular", "817 696 5500", "GTEDS" },
|
||||
{ 575, 0, "Trenton", "NJ", "Cellular One", "800 227 9222", "APPEX" },
|
||||
{ 576, 0, "Williamsport", "PA", "US Cellular", "707 321 9500", "GTEDS" },
|
||||
{ 577, 30027, "Tuscaloosa", "AL", "Cellular One", "205 942 2355", "APPEX" },
|
||||
{ 578, 0, "Wilmington", "NC", "Centel Cellular", "919 833 7494", "GTEDS" },
|
||||
{ 579, 0, "Tyler", "TX", "Cellular One", "214 561 2355", "GTEDS" },
|
||||
{ 580, 0, "Yakima", "WA", "US Cellular", "509 248 3000", "GTEDS" },
|
||||
{ 581, 0, "Victoria", "TX", "Cellular One", "512 573 1100", "Cell-T" },
|
||||
{ 583, 0, "Vineland", "NJ", "Cellular One", "609 272 0900", "GTEDS" },
|
||||
{ 587, 0, "Waco", "TX", "Cellular One", "817 776 3933", "APPEX" },
|
||||
{ 589, 0, "Waterloo", "IA", "Cellular One", "319 234 4000", "GTEDS" },
|
||||
{ 591, 0, "Wausau", "WI", "Cellular One", "715 842 7900", "GTEDS" },
|
||||
{ 595, 0, "Wichita Falls", "TX", "Cellular One", "817 691 9100", "Cell-T" },
|
||||
{ 599, 0, "Wilmington", "NC", "Cellular One", "919 799 5000", "GTEDS" },
|
||||
{ 601, 0, "Yakima", "WA", "Cellular One", "509 454 2663", "APPEX" },
|
||||
{ 607, 0, "Fayetteville", "AR", "Cellular One", "501 783 4600", "Cell-T" },
|
||||
{ 1161, 0, "Hawaii", "HI", "US Cellular", "", "GTEDS" },
|
||||
{ 1177, 0, "Lasalle", "IL", "Cellular One", "815 224 4470", "GTEDS" },
|
||||
{ 1216, 0, "Batavia", "IA", "US Cellular", "515 662 7000", "GTEDS" },
|
||||
{ 1704, 0, "Gainesville", "TX", "Southwestern Bell Mobile", "214 988 8484", "GTEDS" },
|
||||
{ 1774, 0, "North Sound", "WA", "US West", "800 238 7848", "GTEDS" },
|
||||
{ 1784, 0, "Longview", "WA", "US Cellular", "", "GTEDS" },
|
||||
{ 16384, 0, "Calgary", "AB", "AGT Cellular", "403 248 2355", "GTEDS" },
|
||||
{ 16384, 0, "Lethbridge", "AB", "AGT Cellular", "403 248 2355", "GTEDS" },
|
||||
{ 16384, 0, "Medicine Hat", "AB", "AGT Cellular", "403 248 2355", "GTEDS" },
|
||||
{ 16387, 0, "Calgary", "AB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16389, 0, "Chicoutimi", "QU", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16390, 0, "Amherst", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Bridgewater", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Chester", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Halifax", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Hantsport", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Kentville", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Moncton", "NB", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Sydney", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Truro", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16390, 0, "Windsor", "NS", "MT&T Cellular", "902 421 2355", "GTEDS" },
|
||||
{ 16391, 0, "Edmonton", "AB", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16393, 0, "Halifax", "NS", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16395, 0, "Hamilton", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16397, 0, "Hespler", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16397, 0, "Kitchener", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16399, 0, "London", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16401, 0, "Montreal", "QU", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16403, 0, "Oshawa", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16405, 0, "Ottawa", "ON", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16407, 0, "Quebec City", "QU", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16408, 0, "Bathurst", "NB", "MT&T Cellular", "", "GTEDS" },
|
||||
{ 16408, 0, "Newcastle", "NB", "MT&T Cellular", "", "GTEDS" },
|
||||
{ 16409, 0, "Regina", "SK", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16411, 0, "St. John", "NB", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16413, 0, "Saskatoon", "SK", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16415, 0, "St. Catharines", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16419, 0, "Sudbury", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16423, 0, "Newmarket", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16423, 0, "Toronto", "ON", "Cantel, Inc.", "416", ":GTEDS" },
|
||||
{ 16425, 0, "Abbotsford", "BC", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16427, 0, "Vancouver", "BC", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16428, 0, "Winnipeg", "MB", "MTS Cellular", "204 941 7910", "GTEDS" },
|
||||
{ 16431, 0, "Windsor", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16431, 0, "Winnipeg", "MB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16433, 0, "Trois Rivieres", "QU", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16435, 0, "Barrie", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16437, 0, "Brantford", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16439, 0, "Sherbrooke", "QU", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16441, 0, "Peterborough", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16443, 0, "Kingston", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16445, 0, "Red Deer", "AB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16447, 0, "Nanaimo", "BC", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16449, 0, "Belleville", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16451, 0, "Cornwall", "ON", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16453, 0, "Portage", "AB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16455, 0, "Selkirk", "AB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16457, 0, "Chatham", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16459, 0, "Sarnia", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16461, 0, "Chiliwack", "BC", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16463, 0, "Whistler", "BC", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16465, 0, "Steinbach", "MB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16467, 0, "Moncton", "NB", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16469, 0, "Fredericton", "NB", "Cantel, Inc.", "", "GTEDS" },
|
||||
{ 16471, 0, "Brandon", "MB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16473, 0, "Lethbridge", "AB", "Cantel, Inc.", "403 266 1300", "GTEDS" },
|
||||
{ 16475, 0, "Truro", "NS", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16477, 0, "Collingwood", "ON", "Cantel, Inc.", "", "GTEDS" },
|
||||
{ 16481, 0, "St. Marie", "QU", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16485, 0, "Coburg", "ON", "Cantel, Inc.", "415 440 1300", "GTEDS" },
|
||||
{ 16485, 0, "Newtonville", "ON", "Cantel, Inc.", "415 440 1300", "GTEDS" },
|
||||
{ 16487, 0, "Brockville", "QU", "Cantel, Inc.", "514 340 9220", "GTEDS" },
|
||||
{ 16491, 0, "Ponoka", "AB", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16493, 0, "Bowden", "QU", "Cantel, Inc.", "604 687 1440", "GTEDS" },
|
||||
{ 16509, 0, "Orillia", "ON", "Cantel, Inc.", "416 440 1300", "GTEDS" },
|
||||
{ 16521, 0, "Kelowna", "BC", "Cantel, Inc.", "", "GTEDS" },
|
||||
{ 16525, 0, "Penticton", "BC", "Cantel, Inc.", "", "GTEDS" },
|
||||
{ 16527, 0, "Kamloops", "BC", "Cantel, Inc.", "", "GTEDS" },
|
||||
{ 16531, 0, "Canmore", "ON", "Cantel, Inc.", "", "GTEDS" },
|
||||
{ 32752, 0, "Nassau", "Bahamas","Batelco", "809 322 4848", "GTEDS" },
|
||||
{ 0, 0, NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
void list_stations(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; amps_stations[i].city; i++) {
|
||||
printf("SID: %d City: %s, %s (%s)\n", amps_stations[i].sid, amps_stations[i].city, amps_stations[i].state, amps_stations[i].company);
|
||||
}
|
||||
}
|
||||
|
||||
void sid_stations(int sid)
|
||||
{
|
||||
int i, first = 1;
|
||||
|
||||
for (i = 0; amps_stations[i].city; i++) {
|
||||
if (sid == amps_stations[i].sid) {
|
||||
if (first)
|
||||
printf("Selected System ID (SID) %d belongs to:\n", amps_stations[i].sid);
|
||||
first = 0;
|
||||
printf("\t%s, %s (%s)\n", amps_stations[i].city, amps_stations[i].state, amps_stations[i].company);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
void list_stations(void);
|
||||
void sid_stations(int sid);
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "../common/timer.h"
|
||||
#include "amps.h"
|
||||
#include "frame.h"
|
||||
|
||||
static struct sysinfo_reg_incr default_reg_incr = {
|
||||
450,
|
||||
};
|
||||
|
||||
static struct sysinfo_loc_area default_loc_area = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
static struct sysinfo_new_acc default_new_acc = {
|
||||
0,
|
||||
};
|
||||
|
||||
static struct sysinfo_overload default_overload = {
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||
};
|
||||
|
||||
static struct sysinfo_acc_type default_acc_type = {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
static struct sysinfo_acc_attempt default_acc_attempt = {
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
};
|
||||
|
||||
void init_sysinfo(amps_si *si, int cmac, int vmac, int dcc, int sid1, int regh, int regr, int pureg, int pdreg, int locaid, int regincr)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(si, 0, sizeof(*si));
|
||||
|
||||
/* all words */
|
||||
si->dcc = dcc;
|
||||
/* VC assginment */
|
||||
si->vmac = vmac;
|
||||
|
||||
/* filler */
|
||||
si->filler.cmac = cmac;
|
||||
si->filler.sdcc1 = 0;
|
||||
si->filler.sdcc2 = 0;
|
||||
si->filler.wfom = 1; /* must be set to ignore B/I bit */
|
||||
|
||||
/* Word 1 */
|
||||
si->word1.sid1 = sid1;
|
||||
si->word1.ep = 1; /* shall be 0 */
|
||||
si->word1.auth = 0;
|
||||
si->word1.pci = 0;
|
||||
|
||||
/* Word 2 */
|
||||
si->word2.s = 1;
|
||||
si->word2.e = 1;
|
||||
si->word2.regh = regh;
|
||||
si->word2.regr = regr;
|
||||
si->word2.dtx = 0;
|
||||
si->word2.n_1 = 20;
|
||||
si->word2.rcf = 1; /* must be set to ignore B/I bit */
|
||||
si->word2.cpa = 1; /* must be set for combined CC+PC */
|
||||
si->word2.cmax_1 = 20;
|
||||
|
||||
/* registration increment */
|
||||
si->reg_incr.regincr = regincr;
|
||||
|
||||
/* location area */
|
||||
si->loc_area.pureg = pureg;
|
||||
si->loc_area.pdreg = pdreg;
|
||||
if (locaid >= 0) {
|
||||
si->loc_area.lreg = 1;
|
||||
si->loc_area.locaid = locaid;
|
||||
}
|
||||
|
||||
/* new access channel set */
|
||||
si->new_acc.newacc = 0;
|
||||
|
||||
/* overload control */
|
||||
for (i = 0; i < 16; i++)
|
||||
si->overload.olc[i] = 1;
|
||||
|
||||
/* Acces Tyoe */
|
||||
/* 'bis' must be 0, so the phone does not wait for busy bit.
|
||||
* We cannot respond with B/I fast enough due to processing delay.
|
||||
* So we don't set the B/I bit to busy on reception of message.
|
||||
* The access type message (including this 'bis') must also be included.
|
||||
*/
|
||||
si->acc_type.bis = 0; /* must be clear to ignore B/I bit */
|
||||
si->acc_type.pci_home = 0; /* if set, bscap must allso be set */
|
||||
si->acc_type.pci_roam = 0; /* if set, bscap must allso be set */
|
||||
si->acc_type.bspc = 0;
|
||||
si->acc_type.bscap = 0;
|
||||
|
||||
/* access attempt parameters */
|
||||
si->acc_attempt.maxbusy_pgr = 10;
|
||||
si->acc_attempt.maxsztr_pgr = 10;
|
||||
si->acc_attempt.maxbusy_other = 10;
|
||||
si->acc_attempt.maxsztr_other = 10;
|
||||
|
||||
/* registration ID */
|
||||
si->reg_id.regid = 1000;
|
||||
}
|
||||
|
||||
void prepare_sysinfo(amps_si *si)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
si->type[i++] = SYSINFO_WORD1;
|
||||
si->type[i++] = SYSINFO_WORD2;
|
||||
si->type[i++] = SYSINFO_REG_ID;
|
||||
/* include only messages that differ from default */
|
||||
if (!!memcmp(&si->reg_incr, &default_reg_incr, sizeof(si->reg_incr)))
|
||||
si->type[i++] = SYSINFO_REG_INCR;
|
||||
if (!!memcmp(&si->loc_area, &default_loc_area, sizeof(si->loc_area)))
|
||||
si->type[i++] = SYSINFO_LOC_AREA;
|
||||
if (!!memcmp(&si->new_acc, &default_new_acc, sizeof(si->new_acc)))
|
||||
si->type[i++] = SYSINFO_NEW_ACC;
|
||||
if (!!memcmp(&si->overload, &default_overload, sizeof(si->overload)))
|
||||
si->type[i++] = SYSINFO_OVERLOAD;
|
||||
if (!!memcmp(&si->acc_type, &default_acc_type, sizeof(si->acc_type)))
|
||||
si->type[i++] = SYSINFO_ACC_TYPE;
|
||||
if (!!memcmp(&si->acc_attempt, &default_acc_attempt, sizeof(si->acc_attempt)))
|
||||
si->type[i++] = SYSINFO_ACC_ATTEMPT;
|
||||
si->num = i; /* train is running */
|
||||
si->count = 0; /* first message in train */
|
||||
if (i > sizeof(si->type) / sizeof(si->type[0])) {
|
||||
fprintf(stderr, "si type array overflow, pleas fix!\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t get_sysinfo(amps_si *si)
|
||||
{
|
||||
int count, nawc, end = 0;
|
||||
time_t ti = time(NULL);
|
||||
|
||||
count = si->count;
|
||||
|
||||
if (++si->count == si->num) {
|
||||
end = 1;
|
||||
si->num = 0; /* train is over */
|
||||
}
|
||||
|
||||
switch (si->type[count]) {
|
||||
case SYSINFO_WORD1:
|
||||
nawc = si->num - 1;
|
||||
return amps_encode_word1_system(si->dcc, si->word1.sid1, si->word1.ep, si->word1.auth, si->word1.pci, nawc);
|
||||
case SYSINFO_WORD2:
|
||||
return amps_encode_word2_system(si->dcc, si->word2.s, si->word2.e, si->word2.regh, si->word2.regr, si->word2.dtx, si->word2.n_1, si->word2.rcf, si->word2.cpa, si->word2.cmax_1, end);
|
||||
case SYSINFO_REG_ID:
|
||||
/* use time stamp to generate regid */
|
||||
si->reg_id.regid = ti & 0xfffff;
|
||||
return amps_encode_registration_id(si->dcc, si->reg_id.regid, end);
|
||||
case SYSINFO_REG_INCR:
|
||||
return amps_encode_registration_increment(si->dcc, si->reg_incr.regincr, end);
|
||||
case SYSINFO_LOC_AREA:
|
||||
return amps_encode_location_area(si->dcc, si->loc_area.pureg, si->loc_area.pdreg, si->loc_area.lreg, si->loc_area.locaid, end);
|
||||
case SYSINFO_NEW_ACC:
|
||||
return amps_encode_new_access_channel_set(si->dcc, si->new_acc.newacc, end);
|
||||
case SYSINFO_OVERLOAD:
|
||||
return amps_encode_overload_control(si->dcc, si->overload.olc, end);
|
||||
case SYSINFO_ACC_TYPE:
|
||||
return amps_encode_access_type(si->dcc, si->acc_type.bis, si->acc_type.pci_home, si->acc_type.pci_roam, si->acc_type.bspc, si->acc_type.bscap, end);
|
||||
case SYSINFO_ACC_ATTEMPT:
|
||||
return amps_encode_access_attempt(si->dcc, si->acc_attempt.maxbusy_pgr, si->acc_attempt.maxsztr_pgr, si->acc_attempt.maxbusy_other, si->acc_attempt.maxsztr_other, end);
|
||||
}
|
||||
|
||||
fprintf(stderr, "get_sysinfo unknown type, please fix!\n");
|
||||
abort();
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
|
||||
/* filler */
|
||||
struct sysinfo_filler {
|
||||
uint8_t cmac;
|
||||
uint8_t sdcc1;
|
||||
uint8_t sdcc2;
|
||||
uint8_t wfom;
|
||||
};
|
||||
|
||||
enum amps_sysinfo_type {
|
||||
SYSINFO_WORD1,
|
||||
SYSINFO_WORD2,
|
||||
SYSINFO_REG_ID,
|
||||
SYSINFO_REG_INCR,
|
||||
SYSINFO_LOC_AREA,
|
||||
SYSINFO_NEW_ACC,
|
||||
SYSINFO_OVERLOAD,
|
||||
SYSINFO_ACC_TYPE,
|
||||
SYSINFO_ACC_ATTEMPT,
|
||||
};
|
||||
|
||||
/* Word 1 */
|
||||
struct sysinfo_word1 {
|
||||
uint16_t sid1;
|
||||
uint8_t ep;
|
||||
uint8_t auth;
|
||||
uint8_t pci;
|
||||
};
|
||||
|
||||
/* Word 2 */
|
||||
struct sysinfo_word2 {
|
||||
uint8_t s;
|
||||
uint8_t e;
|
||||
uint8_t regh;
|
||||
uint8_t regr;
|
||||
uint8_t dtx;
|
||||
uint8_t n_1;
|
||||
uint8_t rcf;
|
||||
uint8_t cpa;
|
||||
uint8_t cmax_1;
|
||||
};
|
||||
|
||||
/* registration increment */
|
||||
struct sysinfo_reg_incr {
|
||||
uint16_t regincr;
|
||||
};
|
||||
|
||||
/* location area */
|
||||
struct sysinfo_loc_area {
|
||||
uint8_t pureg;
|
||||
uint8_t pdreg;
|
||||
uint8_t lreg;
|
||||
uint16_t locaid;
|
||||
};
|
||||
|
||||
/* new access channel set */
|
||||
struct sysinfo_new_acc {
|
||||
uint16_t newacc;
|
||||
};
|
||||
|
||||
/* overload control */
|
||||
struct sysinfo_overload {
|
||||
uint8_t olc[16];
|
||||
};
|
||||
|
||||
/* Acces Tyoe */
|
||||
struct sysinfo_acc_type {
|
||||
uint8_t bis;
|
||||
uint8_t pci_home;
|
||||
uint8_t pci_roam;
|
||||
uint8_t bspc;
|
||||
uint8_t bscap;
|
||||
};
|
||||
|
||||
/* access attempt parameters */
|
||||
struct sysinfo_acc_attempt {
|
||||
uint8_t maxbusy_pgr;
|
||||
uint8_t maxsztr_pgr;
|
||||
uint8_t maxbusy_other;
|
||||
uint8_t maxsztr_other;
|
||||
};
|
||||
|
||||
/* registration ID */
|
||||
struct sysinfo_reg_id {
|
||||
uint32_t regid;
|
||||
};
|
||||
|
||||
typedef struct system_information {
|
||||
/* all words */
|
||||
uint8_t dcc;
|
||||
/* VC assginment */
|
||||
uint8_t vmac;
|
||||
/* broadcast */
|
||||
struct sysinfo_filler filler;
|
||||
struct sysinfo_word1 word1;
|
||||
struct sysinfo_word2 word2;
|
||||
struct sysinfo_reg_incr reg_incr;
|
||||
struct sysinfo_loc_area loc_area;
|
||||
struct sysinfo_new_acc new_acc;
|
||||
struct sysinfo_overload overload;
|
||||
struct sysinfo_acc_type acc_type;
|
||||
struct sysinfo_acc_attempt acc_attempt;
|
||||
struct sysinfo_reg_id reg_id;
|
||||
|
||||
/* tx state */
|
||||
enum amps_sysinfo_type type[16]; /* list of messages in train */
|
||||
int num; /* number of messages in train */
|
||||
int count; /* count message train */
|
||||
} amps_si;
|
||||
|
||||
void init_sysinfo(amps_si *si, int cmac, int vmac, int dcc, int sid1, int regh, int regr, int pureg, int pdreg, int locaid, int regincr);
|
||||
void prepare_sysinfo(amps_si *si);
|
||||
uint64_t get_sysinfo(amps_si *si);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
|
||||
void init_tones(void);
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/* C-Netz transaction handling
|
||||
*
|
||||
* (C) 2016 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../common/debug.h"
|
||||
#include "../common/timer.h"
|
||||
#include "amps.h"
|
||||
//#include "database.h"
|
||||
|
||||
static const char *trans_state_name(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case 0:
|
||||
return "IDLE";
|
||||
case TRANS_REGISTER_ACK:
|
||||
return "REGISTER ACK";
|
||||
case TRANS_REGISTER_ACK_SEND:
|
||||
return "REGISTER ACK SEND";
|
||||
case TRANS_CALL_MO_ASSIGN:
|
||||
return "CALL ASSIGN MOBILE ORIGINATING";
|
||||
case TRANS_CALL_MO_ASSIGN_SEND:
|
||||
return "CALL ASSIGN MOBILE ORIGINATING SEND";
|
||||
case TRANS_CALL_MT_ASSIGN:
|
||||
return "CALL ASSIGN MOBILE TERMINATING";
|
||||
case TRANS_CALL_MT_ASSIGN_SEND:
|
||||
return "CALL ASSIGN MOBILE TERMINATING SEND";
|
||||
case TRANS_CALL_MT_ALERT:
|
||||
return "CALL ALERT MOBILE TERMINATING";
|
||||
case TRANS_CALL_REJECT:
|
||||
return "CALL REJECT";
|
||||
case TRANS_CALL_REJECT_SEND:
|
||||
return "CALL REJECT SEND";
|
||||
case TRANS_CALL:
|
||||
return "CALL";
|
||||
case TRANS_CALL_RELEASE:
|
||||
return "CALL RELEASE";
|
||||
case TRANS_CALL_RELEASE_SEND:
|
||||
return "CALL RELEASE SEND";
|
||||
case TRANS_PAGE:
|
||||
return "PAGE";
|
||||
case TRANS_PAGE_SEND:
|
||||
return "PAGE SEND";
|
||||
case TRANS_PAGE_REPLY:
|
||||
return "PAGE REPLY";
|
||||
default:
|
||||
return "<invald transaction state>";
|
||||
}
|
||||
}
|
||||
|
||||
/* create transaction */
|
||||
transaction_t *create_transaction(amps_t *amps, enum amps_trans_state state, uint32_t min1, uint16_t min2, uint8_t msg_type, uint8_t ordq, uint8_t order, uint16_t chan)
|
||||
{
|
||||
transaction_t *trans;
|
||||
|
||||
/* search transaction for this subsriber */
|
||||
trans = search_transaction_number(amps, min1, min2);
|
||||
if (trans) {
|
||||
const char *number = amps_min2number(trans->min1, trans->min2);
|
||||
PDEBUG(DTRANS, DEBUG_NOTICE, "Found alredy pending transaction for subscriber '%s', deleting!\n", number);
|
||||
destroy_transaction(trans);
|
||||
}
|
||||
|
||||
trans = calloc(1, sizeof(*trans));
|
||||
if (!trans) {
|
||||
PDEBUG(DTRANS, DEBUG_ERROR, "No memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timer_init(&trans->timer, transaction_timeout, trans);
|
||||
|
||||
trans_new_state(trans, state);
|
||||
trans->min1 = min1;
|
||||
trans->min2 = min2;
|
||||
trans->msg_type = msg_type;
|
||||
trans->ordq = ordq;
|
||||
trans->order = order;
|
||||
trans->chan = chan;
|
||||
|
||||
const char *number = amps_min2number(trans->min1, trans->min2);
|
||||
PDEBUG(DTRANS, DEBUG_INFO, "Created transaction '%s' for subscriber '%s'\n", number, trans_state_name(state));
|
||||
|
||||
link_transaction(trans, amps);
|
||||
|
||||
/* update database: now busy */
|
||||
// update_db(amps, min1, min2, 1, 0);
|
||||
|
||||
return trans;
|
||||
}
|
||||
|
||||
/* destroy transaction */
|
||||
void destroy_transaction(transaction_t *trans)
|
||||
{
|
||||
/* update database: now idle */
|
||||
// update_db(trans->amps, trans->min1, trans->min2, 0, trans->ma_failed);
|
||||
|
||||
unlink_transaction(trans);
|
||||
|
||||
const char *number = amps_min2number(trans->min1, trans->min2);
|
||||
PDEBUG(DTRANS, DEBUG_INFO, "Destroying transaction for subscriber '%s'\n", number);
|
||||
|
||||
timer_exit(&trans->timer);
|
||||
|
||||
trans_new_state(trans, 0);
|
||||
|
||||
free(trans);
|
||||
}
|
||||
|
||||
/* link transaction to list */
|
||||
void link_transaction(transaction_t *trans, amps_t *amps)
|
||||
{
|
||||
transaction_t **transp;
|
||||
|
||||
/* attach to end of list, so first transaction is served first */
|
||||
trans->amps = amps;
|
||||
transp = &s->trans_list;
|
||||
while (*transp)
|
||||
transp = &((*transp)->next);
|
||||
*transp = trans;
|
||||
}
|
||||
|
||||
/* unlink transaction from list */
|
||||
void unlink_transaction(transaction_t *trans)
|
||||
{
|
||||
transaction_t **transp;
|
||||
|
||||
/* unlink */
|
||||
transp = &trans->amps->trans_list;
|
||||
while (*transp && *transp != trans)
|
||||
transp = &((*transp)->next);
|
||||
if (!(*transp)) {
|
||||
PDEBUG(DTRANS, DEBUG_ERROR, "Transaction not in list, please fix!!\n");
|
||||
abort();
|
||||
}
|
||||
*transp = trans->next;
|
||||
trans->amps = NULL;
|
||||
}
|
||||
|
||||
transaction_t *search_transaction_number(amps_t *amps, uint32_t min1, uint16_t min2)
|
||||
{
|
||||
transaction_t *trans = amps->trans_list;
|
||||
|
||||
while (trans) {
|
||||
if (trans->min1 == min1
|
||||
&& trans->min2 == min2) {
|
||||
const char *number = amps_min2number(trans->min1, trans->min2);
|
||||
PDEBUG(DTRANS, DEBUG_DEBUG, "Found transaction for subscriber '%s'\n", number);
|
||||
return trans;
|
||||
}
|
||||
trans = trans->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void trans_new_state(transaction_t *trans, int state)
|
||||
{
|
||||
PDEBUG(DTRANS, DEBUG_INFO, "Transaction state %s -> %s\n", trans_state_name(trans->state), trans_state_name(state));
|
||||
trans->state = state;
|
||||
}
|
||||
|
||||
void amps_flush_other_transactions(amps_t *amps, transaction_t *trans)
|
||||
{
|
||||
/* flush after this very trans */
|
||||
while (trans->next) {
|
||||
PDEBUG(DTRANS, DEBUG_NOTICE, "Kicking other pending transaction\n");
|
||||
destroy_transaction(trans);
|
||||
}
|
||||
/* flush before this very trans */
|
||||
while (amps->trans_list != trans) {
|
||||
PDEBUG(DTRANS, DEBUG_NOTICE, "Kicking other pending transaction\n");
|
||||
destroy_transaction(amps->trans_list);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
typedef struct amps amps_t;
|
||||
|
||||
enum amps_trans_state {
|
||||
TRANS_NULL = 0,
|
||||
TRANS_REGISTER_ACK, /* attach request received, waiting to ack */
|
||||
TRANS_REGISTER_ACK_SEND, /* attach request received, sending ack */
|
||||
TRANS_CALL_MO_ASSIGN, /* assigning channel, waiting to send */
|
||||
TRANS_CALL_MO_ASSIGN_SEND, /* assigning channel, sending assignment */
|
||||
TRANS_CALL_MT_ASSIGN, /* assigning channel, waiting to send */
|
||||
TRANS_CALL_MT_ASSIGN_SEND, /* assigning channel, sending assignment */
|
||||
TRANS_CALL_MT_ALERT, /* ringing the phone, sending alert order until signalling tone is received */
|
||||
TRANS_CALL_MT_ALERT_SEND, /* ringing the phone, signalling tone is received */
|
||||
TRANS_CALL_REJECT, /* rejecting channel, waiting to send */
|
||||
TRANS_CALL_REJECT_SEND, /* rejecting channel, sending reject */
|
||||
TRANS_CALL, /* active call */
|
||||
TRANS_CALL_RELEASE, /* release call towards phone, waiting to send */
|
||||
TRANS_CALL_RELEASE_SEND, /* release call towards phone, sending release */
|
||||
TRANS_PAGE, /* paging phone, waiting to send */
|
||||
TRANS_PAGE_SEND, /* paging phone, sending page order */
|
||||
TRANS_PAGE_REPLY, /* waitring for paging reply */
|
||||
};
|
||||
|
||||
typedef struct transaction {
|
||||
struct transaction *next; /* pointer to next node in list */
|
||||
amps_t *amps; /* pointer to amps instance */
|
||||
uint32_t min1; /* current station ID (2 values) */
|
||||
uint16_t min2;
|
||||
uint8_t msg_type; /* message type (3 values) */
|
||||
uint8_t ordq;
|
||||
uint8_t order;
|
||||
uint16_t chan; /* channel to assign */
|
||||
char dialing[33]; /* number dialed by the phone */
|
||||
enum amps_trans_state state; /* state of transaction */
|
||||
struct timer timer; /* for varous timeouts */
|
||||
int sat_detected; /* state if we detected SAT */
|
||||
} transaction_t;
|
||||
|
||||
transaction_t *create_transaction(amps_t *amps, enum amps_trans_state trans_state, uint32_t min1, uint16_t min2, uint8_t msg_type, uint8_t ordq, uint8_t order, uint16_t chan);
|
||||
void destroy_transaction(transaction_t *trans);
|
||||
void link_transaction(transaction_t *trans, amps_t *amps);
|
||||
void unlink_transaction(transaction_t *trans);
|
||||
transaction_t *search_transaction(amps_t *amps, uint32_t state_mask);
|
||||
transaction_t *search_transaction_number(amps_t *amps, uint32_t min1, uint16_t min2);
|
||||
void trans_new_state(transaction_t *trans, int state);
|
||||
void amps_flush_other_transactions(amps_t *amps, transaction_t *trans);
|
||||
void transaction_timeout(struct timer *timer);
|
||||
|
|
@ -34,17 +34,26 @@ extern int use_mncc_sock;
|
|||
extern int send_patterns;
|
||||
|
||||
/* stream patterns/announcements */
|
||||
int16_t *outoforder_spl = NULL;
|
||||
int16_t *ringback_spl = NULL;
|
||||
int16_t *hangup_spl = NULL;
|
||||
int16_t *busy_spl = NULL;
|
||||
int16_t *noanswer_spl = NULL;
|
||||
int16_t *outoforder_spl = NULL;
|
||||
int16_t *invalidnumber_spl = NULL;
|
||||
int16_t *congestion_spl = NULL;
|
||||
int outoforder_size = 0;
|
||||
int ringback_size = 0;
|
||||
int hangup_size = 0;
|
||||
int busy_size = 0;
|
||||
int noanswer_size = 0;
|
||||
int outoforder_size = 0;
|
||||
int invalidnumber_size = 0;
|
||||
int congestion_size = 0;
|
||||
int outoforder_max = 0;
|
||||
int ringback_max = 0;
|
||||
int hangup_max = 0;
|
||||
int busy_max = 0;
|
||||
int noanswer_max = 0;
|
||||
int outoforder_max = 0;
|
||||
int invalidnumber_max = 0;
|
||||
int congestion_max = 0;
|
||||
|
||||
enum call_state {
|
||||
|
@ -59,9 +68,12 @@ enum call_state {
|
|||
enum audio_pattern {
|
||||
PATTERN_NONE = 0,
|
||||
PATTERN_RINGBACK,
|
||||
PATTERN_HANGUP,
|
||||
PATTERN_BUSY,
|
||||
PATTERN_CONGESTION,
|
||||
PATTERN_NOANSWER,
|
||||
PATTERN_OUTOFORDER,
|
||||
PATTERN_INVALIDNUMBER,
|
||||
PATTERN_CONGESTION,
|
||||
};
|
||||
|
||||
void get_pattern(const int16_t **spl, int *size, int *max, enum audio_pattern pattern)
|
||||
|
@ -76,16 +88,26 @@ void get_pattern(const int16_t **spl, int *size, int *max, enum audio_pattern pa
|
|||
*size = ringback_size;
|
||||
*max = ringback_max;
|
||||
break;
|
||||
case PATTERN_HANGUP:
|
||||
if (!hangup_spl)
|
||||
goto no_hangup;
|
||||
*spl = hangup_spl;
|
||||
*size = hangup_size;
|
||||
*max = hangup_max;
|
||||
break;
|
||||
case PATTERN_BUSY:
|
||||
no_hangup:
|
||||
no_noanswer:
|
||||
*spl = busy_spl;
|
||||
*size = busy_size;
|
||||
*max = busy_max;
|
||||
break;
|
||||
case PATTERN_CONGESTION:
|
||||
no_outoforder:
|
||||
*spl = congestion_spl;
|
||||
*size = congestion_size;
|
||||
*max = congestion_max;
|
||||
case PATTERN_NOANSWER:
|
||||
if (!noanswer_spl)
|
||||
goto no_noanswer;
|
||||
*spl = noanswer_spl;
|
||||
*size = noanswer_size;
|
||||
*max = noanswer_max;
|
||||
break;
|
||||
case PATTERN_OUTOFORDER:
|
||||
if (!outoforder_spl)
|
||||
|
@ -94,6 +116,20 @@ no_outoforder:
|
|||
*size = outoforder_size;
|
||||
*max = outoforder_max;
|
||||
break;
|
||||
case PATTERN_INVALIDNUMBER:
|
||||
if (!invalidnumber_spl)
|
||||
goto no_invalidnumber;
|
||||
*spl = invalidnumber_spl;
|
||||
*size = invalidnumber_size;
|
||||
*max = invalidnumber_max;
|
||||
break;
|
||||
case PATTERN_CONGESTION:
|
||||
no_outoforder:
|
||||
no_invalidnumber:
|
||||
*spl = congestion_spl;
|
||||
*size = congestion_size;
|
||||
*max = congestion_max;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
@ -150,14 +186,26 @@ static enum audio_pattern cause2pattern(int cause)
|
|||
int pattern;
|
||||
|
||||
switch (cause) {
|
||||
case CAUSE_NORMAL:
|
||||
pattern = PATTERN_HANGUP;
|
||||
break;
|
||||
case CAUSE_BUSY:
|
||||
pattern = PATTERN_BUSY;
|
||||
break;
|
||||
case CAUSE_NOANSWER:
|
||||
pattern = PATTERN_NOANSWER;
|
||||
break;
|
||||
case CAUSE_OUTOFORDER:
|
||||
pattern = PATTERN_OUTOFORDER;
|
||||
break;
|
||||
default:
|
||||
case CAUSE_INVALNUMBER:
|
||||
pattern = PATTERN_INVALIDNUMBER;
|
||||
break;
|
||||
case CAUSE_NOCHANNEL:
|
||||
pattern = PATTERN_CONGESTION;
|
||||
break;
|
||||
default:
|
||||
pattern = PATTERN_HANGUP;
|
||||
}
|
||||
|
||||
return pattern;
|
||||
|
|
|
@ -44,6 +44,7 @@ struct debug_cat {
|
|||
{ "bnetz", "\033[1;34m" },
|
||||
{ "cnetz", "\033[1;34m" },
|
||||
{ "nmt", "\033[1;34m" },
|
||||
{ "amps", "\033[1;34m" },
|
||||
{ "frame", "\033[0;36m" },
|
||||
{ "call", "\033[1;37m" },
|
||||
{ "mncc", "\033[1;32m" },
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
#define DBNETZ 4
|
||||
#define DCNETZ 5
|
||||
#define DNMT 6
|
||||
#define DFRAME 7
|
||||
#define DCALL 8
|
||||
#define DMNCC 9
|
||||
#define DDB 10
|
||||
#define DTRANS 11
|
||||
#define DAMPS 7
|
||||
#define DFRAME 8
|
||||
#define DCALL 9
|
||||
#define DMNCC 10
|
||||
#define DDB 11
|
||||
#define DTRANS 12
|
||||
|
||||
#define PDEBUG(cat, level, fmt, arg...) _printdebug(__FILE__, __FUNCTION__, __LINE__, cat, level, fmt, ## arg)
|
||||
void _printdebug(const char *file, const char *function, int line, int cat, int level, const char *fmt, ...);
|
||||
|
|
Loading…
Reference in New Issue