B-Netz: Fixes call procedure according to the standard FTZ 171 R 4

This commit is contained in:
Andreas Eversberg 2016-11-27 07:17:26 +01:00
parent b1c452cf12
commit 938fb74bae
2 changed files with 56 additions and 47 deletions

View File

@ -306,7 +306,8 @@ Call from mobile station:
<p>
The mobile station starts scanning all traffic channels one time.
If there is a signal on the channel, the mobile station tries to decode it for 400 ms max.
If there is no radio signal on the channel, the mobile stations continues with next channel.
If there is a signal on the channel, the mobile station tries to decode it for 320 ms max.
If there is no signal or if there is no idle pattern or if the idle pattern does not match the selected one, the mobile station continues with the next channel.
If no channel is found, a busy signal is indicated to the mobile subscriber.
</p>
@ -320,7 +321,11 @@ When the base station receives the channel allocation signal, it stops idle patt
</p>
<p>
If no dial request signal is received within *TBD* seconds, the mobile station will *TBD*.
If no dial request signal is received within 640 milliseconds, the mobile station will continue searching channel.
</p>
<p>
If no dialing is received from mobile station within 3.8 seconds, the base station will send the disconnect signal for at least 350 ms and return idle.
</p>
<p>
@ -348,7 +353,7 @@ The mobile station can send two different start signals.
One indicates to the base station to send metering pulses.
If metering is selected, the bandwidth is reduced from 3000 Hz down to 2700 Hz.
The metering pulse is then sent as a 2900 Hz tone.
The duration is *TBD* ms and the frequency deviation *TBD* KHz.
The duration is 140 ms and the frequency deviation *TBD* KHz.
</p>
<p>
@ -359,7 +364,9 @@ Only the (bare) 5 digits of the mobile identity are repeated, not the other digi
<p>
The mobile station compares the repeated identity and turns transmitter off, if it mismatches.
Also if the digits are not received by the mobile station while dialing and up to 960 ms after dialing, the transmitter is turned off.
No clear signal is sent.
The mobile station then continues searching for another channel.
If another mobile station dials at the same time, this wrong identity indicates that the base station receives the other mobile station and not our mobile station.
</p>
@ -373,7 +380,7 @@ If the dial string is received correctly once again by the base station, it conn
</p>
<p>
If the base station receives different repeated dialing or different mobile identity, it sends clear signal ("Trennsignal") for 12 seconds and returns to idle state.
If the base station receives different repeated dialing or different mobile identity or misses a digit, it sends clear signal ("Trennsignal") for at least 350 ms and returns to idle state.
</p>
<p>
@ -407,9 +414,9 @@ The transceiver of the base station switches to channel 19 and sends a paging se
</p>
<p>
Then the base station returns to the ordered channel and waits 2 seconds for the mobile station to send the call acknowledge signal ("Rufbest&auml;tigung").
Then the base station returns to the ordered channel and waits 700 ms to 2.1 seconds for the mobile station to send the call acknowledge signal ("Rufbest&auml;tigung").
If it is not received, the base station repeats the paging sequence again.
If there is still no call acknowledge signal, it returns to idle state and indicates announcement to the calling party that the mobile station is (currently) not available.
If there is still no call acknowledge signal, it sends a clear signal ("Trennsignal") for at lease 350 ms and returns to idle state and indicates announcement to the calling party that the mobile station is (currently) not available.
(German announcement sais: "Dieser Anschlu&szlig; ist vorr&uuml;bergehend nicht erreichbar!")
</p>
@ -458,11 +465,11 @@ Release by the mobile station:
</p>
<p>
When the mobile subscriber hangs up, the mobile station sends 4 times the hangup signal ("Schlu&szlig;signal") and returns to idle state.
When the mobile subscriber hangs up, the mobile station sends up to 4 times the hangup signal ("Schlu&szlig;signal") and returns to idle state. If it receives the clear signal ("Trennsignal") from base station, it stops sending hangup signal and returns to idle state.
</p>
<p>
When the base station receives the hangup signal, it releases the call and returns to idle state.
When the base station receives the hangup signal ("Schlu&szlig;signal"), it releases the call, sends clear signal ("Trennsignal") and returns to idle state.
</p>
<br>
@ -472,12 +479,11 @@ Release by the base station:
</p>
<p>
When the party on the fixed network hangs up, base station sends the clear signal ("Trennsignal") for 12 seconds and returns to idle state.
When the party on the fixed network hangs up, base station sends the clear signal ("Trennsignal") for at least 350 ms and returns to idle state.
</p>
<p>
When the mobile station receives the clear signal, it returns to idle
state.
At any time: When the mobile station receives the clear signal ("Trennsignal"), it returns to idle state.
</p>
<br>
@ -488,7 +494,7 @@ Signal loss:
<p>
When the signal gets lost for more than 9,6 seconds, the mobile station will return to idle and indicates busy signal to the mobile subscriber.
The base station will *TBD*, clears the call and returns to idle state.
When the signal gets lost for more than 12.5 seconds, the base station will clears the call, send ("Trennsignal") for at least 350 ms and returns to idle state.
</p>
<p>

View File

@ -39,19 +39,22 @@ static int new_callref = 0x40000000;
/* mobile originating call */
#define CARRIER_TO 0.08 /* 80 ms search for carrier */
#define GRUPPE_TO 0.4 /* 400 ms search for "Gruppensignal" */
#define DIALING_TO 1.00 /* FIXME: get real value */
#define DIALING_TO 3.8 /* timeout after channel allocation "Kanalbelegung" */
#define DIALING_TO2 0.5 /* timeout while receiving digits */
/* radio loss condition */
#define LOSS_OF_SIGNAL 9.6 /* duration of carrier loss until release: 9.6 s */
#define LOSS_OF_SIGNAL 12.5 /* duration of carrier loss until release */
/* mobile terminating call */
#define ALERTING_TO 60 /* timeout after 60 seconds alerting the MS */
#define PAGING_TO 4 /* timeout 4 seconds after "Selektivruf" */
#define PAGING_TO 2.1 /* 700..2100 ms timeout after paging "Selektivruf" */
#define PAGE_TRIES 2 /* two tries */
#define SWITCH19_TIME 1.0 /* time to switch channel (radio should be tansmitting after that) */
#define SWITCHBACK_TIME 0.1 /* time to wait until switching back (latency of sound device shall be lower) */
#define TRENN_COUNT 4 /* min. 350 ms disconnect "Trennsignal" */
#define TRENN_COUNT_NA 96 /* 12 s disconnect "Trennsignal" if no answer */
/* Convert channel number to frequency number of base station.
Set 'unterband' to 1 to get frequency of mobile station. */
double bnetz_kanal2freq(int kanal, int unterband)
@ -222,15 +225,15 @@ static void bnetz_go_idle(bnetz_t *bnetz)
}
/* Release connection towards mobile station by sending release digits. */
static void bnetz_release(bnetz_t *bnetz)
static void bnetz_release(bnetz_t *bnetz, int trenn_count)
{
timer_stop(&bnetz->timer);
PDEBUG(DBNETZ, DEBUG_INFO, "Entering release state, sending 'Trennsignal'.\n");
PDEBUG(DBNETZ, DEBUG_INFO, "Entering release state, sending 'Trennsignal' (%d times).\n", trenn_count);
bnetz->state = BNETZ_TRENNEN;
bnetz_set_dsp_mode(bnetz, DSP_MODE_TELEGRAMM);
switch_channel_19(bnetz, 0);
bnetz->trenn_count = 0;
bnetz->trenn_count = trenn_count;
bnetz->station_id[0] = '\0';
}
@ -298,7 +301,7 @@ const char *bnetz_get_telegramm(bnetz_t *bnetz)
it = bnetz_digit2telegramm(bnetz->station_id[bnetz->station_id_pos++]);
break;
case BNETZ_TRENNEN:
if (bnetz->trenn_count++ == 75) {
if (bnetz->trenn_count-- == 0) {
PDEBUG(DBNETZ, DEBUG_DEBUG, "Maximum number of release digits sent, going idle.\n");
bnetz_go_idle(bnetz);
return NULL;
@ -322,7 +325,7 @@ void bnetz_loss_indication(bnetz_t *bnetz)
if (bnetz->state == BNETZ_GESPRAECH
|| bnetz->state == BNETZ_RUFHALTUNG) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Detected loss of signal, releasing.\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
call_in_release(bnetz->callref, CAUSE_TEMPFAIL);
bnetz->callref = 0;
}
@ -404,7 +407,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
switch (bnetz->state) {
case BNETZ_WAHLABRUF:
timer_start(&bnetz->timer, DIALING_TO);
timer_start(&bnetz->timer, DIALING_TO2);
switch (bnetz->dial_mode) {
case DIAL_MODE_START:
switch (digit) {
@ -419,7 +422,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
break;
default:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received digit that is not a start digit ('Funkwahl'), aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
bnetz->dial_mode = DIAL_MODE_STATIONID;
@ -429,7 +432,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
case DIAL_MODE_STATIONID:
if (digit < '0' || digit > '9') {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received message that is not a valid station id digit, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
bnetz->station_id[bnetz->dial_pos++] = digit;
@ -452,12 +455,12 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
}
if (digit < '0' || digit > '9') {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received message that is not a valid number digit, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
if (bnetz->dial_pos == sizeof(bnetz->dial_number) - 1) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received too many number digits, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
bnetz->dial_number[bnetz->dial_pos++] = digit;
@ -467,27 +470,27 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
case 's':
if (bnetz->dial_type != DIAL_TYPE_NOMETER) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Second received start message('Funkwahl') does not match first one (no metering support), aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
break;
case 'S':
if (bnetz->dial_type != DIAL_TYPE_METER) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Second received start message('Funkwahl') does not match first one (metering support), aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
break;
case 'U':
if (bnetz->dial_type != DIAL_TYPE_METER_MUENZ) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Second received start message('Funkwahl') does not match first one (metering support, payphone), aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
break;
default:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received digit that is not a start digit ('Funkwahl'), aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
bnetz->dial_mode = DIAL_MODE_STATIONID2;
@ -496,12 +499,12 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
case DIAL_MODE_STATIONID2:
if (digit < '0' || digit > '9') {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received message that is not a valid station id digit, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
if (bnetz->station_id[bnetz->dial_pos++] != digit) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Second received station id does not match first one, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
if (bnetz->dial_pos == 5) {
@ -519,7 +522,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
if (bnetz->dial_pos != (int)strlen(bnetz->dial_number)) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received too few number digits the second time, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
PDEBUG(DBNETZ, DEBUG_INFO, "Dialing complete %s->%s, call established.\n", bnetz->station_id, dialing);
@ -532,7 +535,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
rc = call_in_setup(callref, bnetz->station_id, dialing);
if (rc < 0) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", -rc);
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
bnetz->callref = callref;
@ -540,17 +543,17 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
}
if (digit < '0' || digit > '9') {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received message that is not a valid number digit, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
if (bnetz->dial_pos == (int)strlen(bnetz->dial_number)) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received too many number digits, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
if (bnetz->dial_number[bnetz->dial_pos++] != digit) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Second received number does not match first one, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
return;
}
}
@ -561,7 +564,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level, d
return;
if (digit == 't') {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received 'Schlusssignal' from mobile station\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
call_in_release(bnetz->callref, CAUSE_NORMAL);
bnetz->callref = 0;
break;
@ -585,7 +588,7 @@ static void bnetz_timeout(struct timer *timer)
#endif
case BNETZ_WAHLABRUF:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Timeout while receiving call setup from mobile station, aborting.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
break;
case BNETZ_SELEKTIVRUF_EIN:
PDEBUG(DBNETZ, DEBUG_DEBUG, "Transmitter switched to channel 19, starting paging telegramms.\n");
@ -600,7 +603,7 @@ static void bnetz_timeout(struct timer *timer)
case BNETZ_RUFBESTAETIGUNG:
if (bnetz->page_try == PAGE_TRIES) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Timeout while waiting for call acknowledge from mobile station, going idle.\n");
bnetz_go_idle(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
call_in_release(bnetz->callref, CAUSE_OUTOFORDER);
bnetz->callref = 0;
break;
@ -610,7 +613,7 @@ static void bnetz_timeout(struct timer *timer)
break;
case BNETZ_RUFHALTUNG:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Timeout while waiting for answer of mobile station, releasing.\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT_NA);
call_in_release(bnetz->callref, CAUSE_NOANSWER);
bnetz->callref = 0;
break;
@ -629,7 +632,7 @@ int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, e
/* 1. check if number is invalid, return INVALNUMBER */
if (strlen(dialing) == 7 && dialing[0] == '0' && dialing[1] == '5')
dialing += 2;
if (strlen(dialing) != 5) {
else if (strlen(dialing) != 5) {
inval:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing call to invalid number '%s', rejecting!\n", dialing);
return -CAUSE_INVALNUMBER;
@ -700,11 +703,11 @@ void call_out_disconnect(int callref, int cause)
case BNETZ_SELEKTIVRUF_AUS:
case BNETZ_RUFBESTAETIGUNG:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing disconnect, during paging, releasing!\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
break;
case BNETZ_RUFHALTUNG:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing disconnect, during alerting, releasing!\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
break;
default:
break;
@ -739,17 +742,17 @@ void call_out_release(int callref, int __attribute__((unused)) cause)
switch (bnetz->state) {
case BNETZ_GESPRAECH:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing release, during call, releasing!\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
break;
case BNETZ_SELEKTIVRUF_EIN:
case BNETZ_SELEKTIVRUF_AUS:
case BNETZ_RUFBESTAETIGUNG:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing release, during paging, releasing!\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
break;
case BNETZ_RUFHALTUNG:
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing release, during alerting, releasing!\n");
bnetz_release(bnetz);
bnetz_release(bnetz, TRENN_COUNT);
break;
default:
break;