AMPS: Add option to use the BUSY/IDLE bit on FOCC
This commit is contained in:
@@ -31,7 +31,7 @@ enum fsk_rx_sync {
|
|||||||
FSK_SYNC_NEGATIVE, /* as above, but negative sync (high frequency deviation detected as low signal) */
|
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 */
|
#define FSK_MAX_BITS 1032 /* maximum number of bits to process (FVC with dotting+sync) */
|
||||||
|
|
||||||
typedef struct amps {
|
typedef struct amps {
|
||||||
sender_t sender;
|
sender_t sender;
|
||||||
@@ -44,6 +44,7 @@ typedef struct amps {
|
|||||||
enum amps_chan_type chan_type;
|
enum amps_chan_type chan_type;
|
||||||
enum amps_state state;
|
enum amps_state state;
|
||||||
int page_retry; /* current number of paging (re)try */
|
int page_retry; /* current number of paging (re)try */
|
||||||
|
int channel_busy; /* indicate channel is busy while receiving */
|
||||||
|
|
||||||
/* system info */
|
/* system info */
|
||||||
amps_si si;
|
amps_si si;
|
||||||
@@ -60,6 +61,8 @@ typedef struct amps {
|
|||||||
double fsk_bitduration; /* duration of one bit in samples */
|
double fsk_bitduration; /* duration of one bit in samples */
|
||||||
double fsk_bitstep; /* fraction of one bit each sample */
|
double fsk_bitstep; /* fraction of one bit each sample */
|
||||||
/* tx bits generation */
|
/* tx bits generation */
|
||||||
|
char fsk_tx_frame[FSK_MAX_BITS + 1]; /* +1 because 0-termination */
|
||||||
|
int fsk_tx_frame_pos; /* current position sending bits */
|
||||||
int16_t *fsk_tx_buffer; /* tx buffer for one data block */
|
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_size; /* size of tx buffer (in samples) */
|
||||||
int fsk_tx_buffer_length; /* usage of buffer (in samples) */
|
int fsk_tx_buffer_length; /* usage of buffer (in samples) */
|
||||||
|
@@ -158,7 +158,7 @@ int dsp_init_sender(amps_t *amps, int high_pass)
|
|||||||
amps->fsk_bitstep = 1.0 / amps->fsk_bitduration;
|
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);
|
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_size = amps->fsk_bitduration + 10; /* 10 extra to avoid overflow due to rounding */
|
||||||
amps->fsk_tx_buffer = calloc(sizeof(int16_t), amps->fsk_tx_buffer_size);
|
amps->fsk_tx_buffer = calloc(sizeof(int16_t), amps->fsk_tx_buffer_size);
|
||||||
if (!amps->fsk_tx_buffer) {
|
if (!amps->fsk_tx_buffer) {
|
||||||
PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n");
|
PDEBUG(DDSP, DEBUG_DEBUG, "No memory!\n");
|
||||||
@@ -237,28 +237,21 @@ void dsp_cleanup_sender(amps_t *amps)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fsk_encode(amps_t *amps, const char *bits)
|
static int fsk_encode(amps_t *amps, char bit)
|
||||||
{
|
{
|
||||||
int16_t *spl;
|
int16_t *spl;
|
||||||
double phase, bitstep, deviation;
|
double phase, bitstep, deviation;
|
||||||
int count;
|
int count;
|
||||||
char last;
|
char last;
|
||||||
|
|
||||||
if (strlen(bits) > FSK_MAX_BITS) {
|
|
||||||
fprintf(stderr, "FSK buffer too small\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
deviation = amps->fsk_deviation;
|
deviation = amps->fsk_deviation;
|
||||||
spl = amps->fsk_tx_buffer;
|
spl = amps->fsk_tx_buffer;
|
||||||
phase = amps->fsk_tx_phase;
|
phase = amps->fsk_tx_phase;
|
||||||
last = amps->fsk_tx_last_bit;
|
last = amps->fsk_tx_last_bit;
|
||||||
bitstep = amps->fsk_bitstep * 256.0 * 2.0; /* half bit ramp */
|
bitstep = amps->fsk_bitstep * 256.0 * 2.0; /* half bit ramp */
|
||||||
|
|
||||||
//printf("%s\n", bits);
|
//printf("%d %d\n", (bit) & 1, last & 1);
|
||||||
while (*bits) {
|
if ((bit & 1)) {
|
||||||
//printf("%d %d\n", (*bits) & 1, last & 1);
|
|
||||||
if (((*bits) & 1)) {
|
|
||||||
if ((last & 1)) {
|
if ((last & 1)) {
|
||||||
/* last bit was 1, this bit is 1, so we ramp down first */
|
/* last bit was 1, this bit is 1, so we ramp down first */
|
||||||
do {
|
do {
|
||||||
@@ -303,10 +296,7 @@ static int fsk_encode(amps_t *amps, const char *bits)
|
|||||||
} while (phase < 256.0);
|
} while (phase < 256.0);
|
||||||
phase -= 256.0;
|
phase -= 256.0;
|
||||||
}
|
}
|
||||||
last = *bits;
|
last = bit;
|
||||||
bits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* depending on the number of samples, return the number */
|
/* depending on the number of samples, return the number */
|
||||||
count = ((uintptr_t)spl - (uintptr_t)amps->fsk_tx_buffer) / sizeof(*spl);
|
count = ((uintptr_t)spl - (uintptr_t)amps->fsk_tx_buffer) / sizeof(*spl);
|
||||||
|
|
||||||
@@ -319,46 +309,60 @@ static int fsk_encode(amps_t *amps, const char *bits)
|
|||||||
|
|
||||||
int fsk_frame(amps_t *amps, int16_t *samples, int length)
|
int fsk_frame(amps_t *amps, int16_t *samples, int length)
|
||||||
{
|
{
|
||||||
int count = 0, pos, copy, i;
|
int count = 0, len, pos, copy, i;
|
||||||
int16_t *spl;
|
int16_t *spl;
|
||||||
const char *bits;
|
int rc;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
len = amps->fsk_tx_buffer_length;
|
||||||
|
pos = amps->fsk_tx_buffer_pos;
|
||||||
|
spl = amps->fsk_tx_buffer;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
/* there must be length, otherwise we would skip blocks */
|
/* there must be length, otherwise we would skip blocks */
|
||||||
if (count == length)
|
if (count == length)
|
||||||
return count;
|
goto done;
|
||||||
|
|
||||||
pos = amps->fsk_tx_buffer_pos;
|
/* start of new bit, so generate buffer for one bit */
|
||||||
spl = amps->fsk_tx_buffer + pos;
|
|
||||||
|
|
||||||
/* start new frame, so we generate one */
|
|
||||||
if (pos == 0) {
|
if (pos == 0) {
|
||||||
|
c = amps->fsk_tx_frame[amps->fsk_tx_frame_pos];
|
||||||
|
/* start new frame, so we generate one */
|
||||||
|
if (c == '\0') {
|
||||||
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_FRAME_TX)
|
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_FRAME_TX)
|
||||||
bits = amps_encode_frame_fvc(amps);
|
rc = amps_encode_frame_fvc(amps, amps->fsk_tx_frame);
|
||||||
else
|
else
|
||||||
bits = amps_encode_frame_focc(amps);
|
rc = amps_encode_frame_focc(amps, amps->fsk_tx_frame);
|
||||||
if (!bits)
|
/* check if we have not bit string (change to tx audio)
|
||||||
return 0;
|
* we may not store fsk_tx_buffer_pos, because is was reset on a mode achange */
|
||||||
fsk_encode(amps, bits);
|
if (rc)
|
||||||
|
return count;
|
||||||
|
amps->fsk_tx_frame_pos = 0;
|
||||||
|
c = amps->fsk_tx_frame[0];
|
||||||
|
}
|
||||||
|
if (c == 'i')
|
||||||
|
c = (amps->channel_busy) ? '0' : '1';
|
||||||
|
len = fsk_encode(amps, c);
|
||||||
|
amps->fsk_tx_frame_pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy = amps->fsk_tx_buffer_length - pos;
|
copy = len - pos;
|
||||||
if (length - count < copy)
|
if (length - count < copy)
|
||||||
copy = length - count;
|
copy = length - count;
|
||||||
//printf("pos=%d length=%d copy=%d\n", pos, length, copy);
|
//printf("pos=%d length=%d copy=%d\n", pos, length, copy);
|
||||||
for (i = 0; i < copy; i++) {
|
for (i = 0; i < copy; i++) {
|
||||||
#ifdef DEBUG_ENCODER
|
#ifdef DEBUG_ENCODER
|
||||||
puts(debug_amplitude((double)(*spl) / 32767.0));
|
puts(debug_amplitude((double)spl[pos] / 32767.0));
|
||||||
#endif
|
#endif
|
||||||
*samples++ = *spl++;
|
*samples++ = spl[pos++];
|
||||||
}
|
}
|
||||||
pos += copy;
|
|
||||||
count += copy;
|
count += copy;
|
||||||
if (pos ==amps->fsk_tx_buffer_length) {
|
if (pos == len) {
|
||||||
amps->fsk_tx_buffer_pos = 0;
|
pos = 0;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
amps->fsk_tx_buffer_length = len;
|
||||||
amps->fsk_tx_buffer_pos = pos;
|
amps->fsk_tx_buffer_pos = pos;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -399,12 +403,10 @@ void sender_send(sender_t *sender, int16_t *samples, int length)
|
|||||||
again:
|
again:
|
||||||
switch (amps->dsp_mode) {
|
switch (amps->dsp_mode) {
|
||||||
case DSP_MODE_OFF:
|
case DSP_MODE_OFF:
|
||||||
off:
|
|
||||||
/* silence, if transmitter is off */
|
/* silence, if transmitter is off */
|
||||||
memset(samples, 0, length * sizeof(*samples));
|
memset(samples, 0, length * sizeof(*samples));
|
||||||
break;
|
break;
|
||||||
case DSP_MODE_AUDIO_RX_AUDIO_TX:
|
case DSP_MODE_AUDIO_RX_AUDIO_TX:
|
||||||
audio:
|
|
||||||
jitter_load(&s->sender.audio, samples, length);
|
jitter_load(&s->sender.audio, samples, length);
|
||||||
/* pre-emphasis */
|
/* pre-emphasis */
|
||||||
if (amps->pre_emphasis)
|
if (amps->pre_emphasis)
|
||||||
@@ -417,21 +419,10 @@ audio:
|
|||||||
/* Encode frame into audio stream. If frames have
|
/* Encode frame into audio stream. If frames have
|
||||||
* stopped, process again for rest of stream. */
|
* stopped, process again for rest of stream. */
|
||||||
count = fsk_frame(amps, samples, length);
|
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;
|
samples += count;
|
||||||
length -= count;
|
length -= count;
|
||||||
|
if (length)
|
||||||
goto again;
|
goto again;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,6 +503,7 @@ prepare_frame:
|
|||||||
printf("No Sync detected after dotting\n");
|
printf("No Sync detected after dotting\n");
|
||||||
#endif
|
#endif
|
||||||
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
||||||
|
amps->channel_busy = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -549,6 +541,7 @@ prepare_frame:
|
|||||||
if (amps->fsk_rx_frame_length == 240)
|
if (amps->fsk_rx_frame_length == 240)
|
||||||
amps->fsk_rx_frame_length = 247;
|
amps->fsk_rx_frame_length = 247;
|
||||||
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
||||||
|
amps->channel_busy = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,6 +592,8 @@ void fsk_rx_dotting(amps_t *amps, double _elapsed, int dir)
|
|||||||
amps->fsk_rx_sync = FSK_SYNC_DOTTING;
|
amps->fsk_rx_sync = FSK_SYNC_DOTTING;
|
||||||
amps->fsk_rx_dotting_average = fabs(average);
|
amps->fsk_rx_dotting_average = fabs(average);
|
||||||
amps->fsk_rx_bitcount = 0.5 + average;
|
amps->fsk_rx_bitcount = 0.5 + average;
|
||||||
|
if (amps->si.acc_type.bis)
|
||||||
|
amps->channel_busy = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,9 +854,12 @@ void amps_set_dsp_mode(amps_t *amps, enum dsp_mode mode, int frame_length)
|
|||||||
|
|
||||||
/* reset detection process */
|
/* reset detection process */
|
||||||
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
amps->fsk_rx_sync = FSK_SYNC_NONE;
|
||||||
|
amps->channel_busy = 0;
|
||||||
amps->fsk_rx_sync_register = 0x555;
|
amps->fsk_rx_sync_register = 0x555;
|
||||||
|
|
||||||
/* reset transmitter */
|
/* reset transmitter */
|
||||||
amps->fsk_tx_buffer_pos = 0;
|
amps->fsk_tx_buffer_pos = 0;
|
||||||
|
amps->fsk_tx_frame[0] = '\0';
|
||||||
|
amps->fsk_tx_frame_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3285,22 +3285,21 @@ static uint64_t string2bin(const char *string)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *amps_encode_focc_bits(amps_t *amps, uint64_t word_a, uint64_t word_b, int busy_idle)
|
void amps_encode_focc_bits(amps_t *amps, uint64_t word_a, uint64_t word_b, char *bits)
|
||||||
{
|
{
|
||||||
static char bits[463 + 1];
|
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
strncpy(bits + 0, dotting, 10);
|
strncpy(bits + 0, dotting, 10);
|
||||||
bits[10] = (busy_idle) ? '1' : '0';
|
bits[10] = 'i';
|
||||||
strcpy(bits + 11, sync_word);
|
strcpy(bits + 11, sync_word);
|
||||||
bits[22] = (busy_idle) ? '1' : '0';
|
bits[22] = 'i';
|
||||||
/* WORD A (msb first) */
|
/* WORD A (msb first) */
|
||||||
k = 23;
|
k = 23;
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
for (j = 39; j >= 0; j--) {
|
for (j = 39; j >= 0; j--) {
|
||||||
bits[k++] = ((word_a >> j) & 1) + '0';
|
bits[k++] = ((word_a >> j) & 1) + '0';
|
||||||
if ((j % 10) == 0)
|
if ((j % 10) == 0)
|
||||||
bits[k++] = (busy_idle) ? '1' : '0';
|
bits[k++] = 'i';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* WORD B (msb first) */
|
/* WORD B (msb first) */
|
||||||
@@ -3308,7 +3307,7 @@ static char *amps_encode_focc_bits(amps_t *amps, uint64_t word_a, uint64_t word_
|
|||||||
for (j = 39; j >= 0; j--) {
|
for (j = 39; j >= 0; j--) {
|
||||||
bits[k++] = ((word_b >> j) & 1) + '0';
|
bits[k++] = ((word_b >> j) & 1) + '0';
|
||||||
if ((j % 10) == 0)
|
if ((j % 10) == 0)
|
||||||
bits[k++] = (busy_idle) ? '1' : '0';
|
bits[k++] = 'i';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3335,13 +3334,10 @@ static char *amps_encode_focc_bits(amps_t *amps, uint64_t word_a, uint64_t word_
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return bits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *amps_encode_fvc_bits(amps_t *amps, uint64_t word_a)
|
void amps_encode_fvc_bits(amps_t *amps, uint64_t word_a, char *bits)
|
||||||
{
|
{
|
||||||
static char bits[1032 + 1];
|
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
|
|
||||||
@@ -3369,13 +3365,10 @@ static char *amps_encode_fvc_bits(amps_t *amps, uint64_t word_a)
|
|||||||
PDEBUG(DFRAME, DEBUG_INFO, "TX FVC: %s\n", bits);
|
PDEBUG(DFRAME, DEBUG_INFO, "TX FVC: %s\n", bits);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return bits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *amps_encode_frame_focc(amps_t *amps)
|
int amps_encode_frame_focc(amps_t *amps, char *bits)
|
||||||
{
|
{
|
||||||
char *bits;
|
|
||||||
uint64_t word;
|
uint64_t word;
|
||||||
|
|
||||||
/* init overhead train */
|
/* init overhead train */
|
||||||
@@ -3406,7 +3399,7 @@ const char *amps_encode_frame_focc(amps_t *amps)
|
|||||||
}
|
}
|
||||||
/* on change of dsp mode */
|
/* on change of dsp mode */
|
||||||
if (amps->dsp_mode != DSP_MODE_FRAME_RX_FRAME_TX)
|
if (amps->dsp_mode != DSP_MODE_FRAME_RX_FRAME_TX)
|
||||||
return NULL;
|
return 1;
|
||||||
}
|
}
|
||||||
/* send scheduled mobile control message */
|
/* send scheduled mobile control message */
|
||||||
if (amps->tx_focc_send) {
|
if (amps->tx_focc_send) {
|
||||||
@@ -3439,7 +3432,7 @@ const char *amps_encode_frame_focc(amps_t *amps)
|
|||||||
amps->tx_focc_frame_count = 0;
|
amps->tx_focc_frame_count = 0;
|
||||||
|
|
||||||
send:
|
send:
|
||||||
bits = amps_encode_focc_bits(amps, word, word, 1);
|
amps_encode_focc_bits(amps, word, word, bits);
|
||||||
|
|
||||||
/* invert, if polarity of the cell is negative */
|
/* invert, if polarity of the cell is negative */
|
||||||
if (amps->flip_polarity) {
|
if (amps->flip_polarity) {
|
||||||
@@ -3449,12 +3442,11 @@ send:
|
|||||||
bits[i] ^= 1;
|
bits[i] ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bits;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *amps_encode_frame_fvc(amps_t *amps)
|
int amps_encode_frame_fvc(amps_t *amps, char *bits)
|
||||||
{
|
{
|
||||||
char *bits;
|
|
||||||
uint64_t word;
|
uint64_t word;
|
||||||
|
|
||||||
/* see if we can schedule a mobile control message */
|
/* see if we can schedule a mobile control message */
|
||||||
@@ -3470,7 +3462,7 @@ const char *amps_encode_frame_fvc(amps_t *amps)
|
|||||||
}
|
}
|
||||||
/* on change of dsp mode */
|
/* on change of dsp mode */
|
||||||
if (amps->dsp_mode != DSP_MODE_AUDIO_RX_FRAME_TX)
|
if (amps->dsp_mode != DSP_MODE_AUDIO_RX_FRAME_TX)
|
||||||
return NULL;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send scheduled mobile control message */
|
/* send scheduled mobile control message */
|
||||||
@@ -3481,9 +3473,9 @@ const char *amps_encode_frame_fvc(amps_t *amps)
|
|||||||
else
|
else
|
||||||
word = amps_encode_mobile_station_control_message_word1_a(amps->sat, amps->tx_fvc_msg_type, amps->tx_fvc_ordq, amps->tx_fvc_order);
|
word = amps_encode_mobile_station_control_message_word1_a(amps->sat, amps->tx_fvc_msg_type, amps->tx_fvc_ordq, amps->tx_fvc_order);
|
||||||
} else
|
} else
|
||||||
return NULL;
|
return 1;
|
||||||
|
|
||||||
bits = amps_encode_fvc_bits(amps, word);
|
amps_encode_fvc_bits(amps, word, bits);
|
||||||
|
|
||||||
/* invert, if polarity of the cell is negative */
|
/* invert, if polarity of the cell is negative */
|
||||||
if (amps->flip_polarity) {
|
if (amps->flip_polarity) {
|
||||||
@@ -3493,7 +3485,7 @@ const char *amps_encode_frame_fvc(amps_t *amps)
|
|||||||
bits[i] ^= 1;
|
bits[i] ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bits;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assemble FOCC bits */
|
/* assemble FOCC bits */
|
||||||
|
@@ -219,7 +219,7 @@ uint64_t amps_encode_new_access_channel_set(uint8_t dcc, uint16_t newacc, uint8_
|
|||||||
uint64_t amps_encode_overload_control(uint8_t dcc, uint8_t *olc, 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_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);
|
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);
|
int amps_encode_frame_focc(amps_t *amps, char *bits);
|
||||||
const char *amps_encode_frame_fvc(amps_t *amps);
|
int amps_encode_frame_fvc(amps_t *amps, char *bits);
|
||||||
int amps_decode_frame(amps_t *amps, const char *bits, int count, double level, double quality, int negative);
|
int amps_decode_frame(amps_t *amps, const char *bits, int count, double level, double quality, int negative);
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@
|
|||||||
int num_chan_type = 0;
|
int num_chan_type = 0;
|
||||||
enum amps_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_CC_PC_VC };
|
enum amps_chan_type chan_type[MAX_SENDER] = { CHAN_TYPE_CC_PC_VC };
|
||||||
const char *flip_polarity = "";
|
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;
|
int ms_power = 4, dcc = 0, scc = 0, sid = 40, regh = 1, regr = 1, pureg = 1, pdreg = 1, locaid = -1, regincr = 300, bis = 0;
|
||||||
|
|
||||||
void print_help(const char *arg0)
|
void print_help(const char *arg0)
|
||||||
{
|
{
|
||||||
@@ -83,6 +83,9 @@ void print_help(const char *arg0)
|
|||||||
printf(" If 1, phone registers only if System ID matches (default = '%d')\n", regh);
|
printf(" If 1, phone registers only if System ID matches (default = '%d')\n", regh);
|
||||||
printf(" -S --sysinfo regr=0 | regr=1\n");
|
printf(" -S --sysinfo regr=0 | regr=1\n");
|
||||||
printf(" If 1, phone registers only if System ID is different (default = '%d')\n", regr);
|
printf(" If 1, phone registers only if System ID is different (default = '%d')\n", regr);
|
||||||
|
printf(" -S --sysinfo bis=0 | bis=1\n");
|
||||||
|
printf(" If 0, phone ignores BUSY/IDLE bit on FOCC (default = '%d')\n", bis);
|
||||||
|
printf(" If 1, be sure to have a round-trip delay (latency) not more than 5 ms\n");
|
||||||
printf("\nstation-id: Give 10 digit station-id, you don't need to enter it for every\n");
|
printf("\nstation-id: Give 10 digit station-id, you don't need to enter it for every\n");
|
||||||
printf(" start of this program.\n");
|
printf(" start of this program.\n");
|
||||||
}
|
}
|
||||||
@@ -151,7 +154,7 @@ static int handle_options(int argc, char **argv)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
if (!strncasecmp(optarg, "sid=", 4)) {
|
if (!strncasecmp(optarg, "sid=", p - optarg)) {
|
||||||
if (!strcasecmp(p, "list")) {
|
if (!strcasecmp(p, "list")) {
|
||||||
list_stations();
|
list_stations();
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -162,39 +165,42 @@ static int handle_options(int argc, char **argv)
|
|||||||
if (sid < 0)
|
if (sid < 0)
|
||||||
sid = 0;
|
sid = 0;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "dcc=", 4)) {
|
if (!strncasecmp(optarg, "dcc=", p - optarg)) {
|
||||||
dcc = atoi(p);
|
dcc = atoi(p);
|
||||||
if (dcc > 3)
|
if (dcc > 3)
|
||||||
dcc = 3;
|
dcc = 3;
|
||||||
if (dcc < 0)
|
if (dcc < 0)
|
||||||
dcc = 0;
|
dcc = 0;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "scc=", 4)) {
|
if (!strncasecmp(optarg, "scc=", p - optarg)) {
|
||||||
scc = atoi(p);
|
scc = atoi(p);
|
||||||
if (scc > 2)
|
if (scc > 2)
|
||||||
scc = 2;
|
scc = 2;
|
||||||
if (scc < 0)
|
if (scc < 0)
|
||||||
scc = 0;
|
scc = 0;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "regincr=", 4)) {
|
if (!strncasecmp(optarg, "regincr=", p - optarg)) {
|
||||||
regincr = atoi(p);
|
regincr = atoi(p);
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "pureg=", 4)) {
|
if (!strncasecmp(optarg, "pureg=", p - optarg)) {
|
||||||
pureg = atoi(p) & 1;
|
pureg = atoi(p) & 1;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "pdreg=", 4)) {
|
if (!strncasecmp(optarg, "pdreg=", p - optarg)) {
|
||||||
pdreg = atoi(p) & 1;
|
pdreg = atoi(p) & 1;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "locaid=", 4)) {
|
if (!strncasecmp(optarg, "locaid=", p - optarg)) {
|
||||||
locaid = atoi(p);
|
locaid = atoi(p);
|
||||||
if (locaid > 4095)
|
if (locaid > 4095)
|
||||||
locaid = 4095;
|
locaid = 4095;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "regh=", 4)) {
|
if (!strncasecmp(optarg, "regh=", p - optarg)) {
|
||||||
regh = atoi(p) & 1;
|
regh = atoi(p) & 1;
|
||||||
} else
|
} else
|
||||||
if (!strncasecmp(optarg, "regr=", 4)) {
|
if (!strncasecmp(optarg, "regr=", p - optarg)) {
|
||||||
regr = atoi(p) & 1;
|
regr = atoi(p) & 1;
|
||||||
|
} else
|
||||||
|
if (!strncasecmp(optarg, "bis=", p - optarg)) {
|
||||||
|
bis = atoi(p) & 1;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
|
fprintf(stderr, "Given sysinfo parameter '%s' unknown, see help!\n", optarg);
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -259,6 +265,11 @@ int main(int argc, char *argv[])
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bis && latency > 5) {
|
||||||
|
fprintf(stdout, "If you use BUSY/IDLE bit, you need to lower the round-trip delay to 5 ms (--latenc 5).\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!loopback)
|
if (!loopback)
|
||||||
print_image();
|
print_image();
|
||||||
sid_stations(sid);
|
sid_stations(sid);
|
||||||
@@ -329,7 +340,7 @@ int main(int argc, char *argv[])
|
|||||||
for (i = 0; i < num_kanal; i++) {
|
for (i = 0; i < num_kanal; i++) {
|
||||||
amps_si si;
|
amps_si si;
|
||||||
|
|
||||||
init_sysinfo(&si, ms_power, ms_power, dcc, sid >> 1, regh, regr, pureg, pdreg, locaid, regincr);
|
init_sysinfo(&si, ms_power, ms_power, dcc, sid >> 1, regh, regr, pureg, pdreg, locaid, regincr, bis);
|
||||||
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);
|
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) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
||||||
|
@@ -41,7 +41,7 @@ static struct sysinfo_acc_attempt default_acc_attempt = {
|
|||||||
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)
|
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 bis)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ void init_sysinfo(amps_si *si, int cmac, int vmac, int dcc, int sid1, int regh,
|
|||||||
si->filler.cmac = cmac;
|
si->filler.cmac = cmac;
|
||||||
si->filler.sdcc1 = 0;
|
si->filler.sdcc1 = 0;
|
||||||
si->filler.sdcc2 = 0;
|
si->filler.sdcc2 = 0;
|
||||||
si->filler.wfom = 1; /* must be set to ignore B/I bit */
|
si->filler.wfom = (bis) ? 0 : 1; /* must be set to ignore B/I bit */
|
||||||
|
|
||||||
/* Word 1 */
|
/* Word 1 */
|
||||||
si->word1.sid1 = sid1;
|
si->word1.sid1 = sid1;
|
||||||
@@ -71,7 +71,7 @@ void init_sysinfo(amps_si *si, int cmac, int vmac, int dcc, int sid1, int regh,
|
|||||||
si->word2.regr = regr;
|
si->word2.regr = regr;
|
||||||
si->word2.dtx = 0;
|
si->word2.dtx = 0;
|
||||||
si->word2.n_1 = 20;
|
si->word2.n_1 = 20;
|
||||||
si->word2.rcf = 1; /* must be set to ignore B/I bit */
|
si->word2.rcf = (bis) ? 0 : 1; /* must be set to ignore B/I bit */
|
||||||
si->word2.cpa = 1; /* must be set for combined CC+PC */
|
si->word2.cpa = 1; /* must be set for combined CC+PC */
|
||||||
si->word2.cmax_1 = 20;
|
si->word2.cmax_1 = 20;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ void init_sysinfo(amps_si *si, int cmac, int vmac, int dcc, int sid1, int regh,
|
|||||||
* So we don't set the B/I bit to busy on reception of message.
|
* 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.
|
* 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.bis = bis; /* 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_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.pci_roam = 0; /* if set, bscap must allso be set */
|
||||||
si->acc_type.bspc = 0;
|
si->acc_type.bspc = 0;
|
||||||
|
@@ -108,7 +108,7 @@ typedef struct system_information {
|
|||||||
int count; /* count message train */
|
int count; /* count message train */
|
||||||
} amps_si;
|
} 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 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 bis);
|
||||||
void prepare_sysinfo(amps_si *si);
|
void prepare_sysinfo(amps_si *si);
|
||||||
uint64_t get_sysinfo(amps_si *si);
|
uint64_t get_sysinfo(amps_si *si);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user