C-Netz: Add authentication support (process only)
No real authentication, since the algorithm and the keys inside the cards are not known. A challenge can be specified and optionally the response can be verified.
This commit is contained in:
parent
5d9a9b59c3
commit
13245c56f6
|
@ -246,7 +246,7 @@ int cnetz_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create transceiver instance and link to a list. */
|
/* Create transceiver instance and link to a list. */
|
||||||
int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int auth, int warteschlange, int metering, double dbm0_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
|
int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double dbm0_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback)
|
||||||
{
|
{
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
cnetz_t *cnetz;
|
cnetz_t *cnetz;
|
||||||
|
@ -327,7 +327,10 @@ int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev
|
||||||
}
|
}
|
||||||
|
|
||||||
cnetz->chan_type = chan_type;
|
cnetz->chan_type = chan_type;
|
||||||
cnetz->auth = auth;
|
cnetz->challenge_valid = challenge_valid;
|
||||||
|
cnetz->challenge = challenge;
|
||||||
|
cnetz->response_valid = response_valid;
|
||||||
|
cnetz->response = response;
|
||||||
cnetz->warteschlange = warteschlange;
|
cnetz->warteschlange = warteschlange;
|
||||||
cnetz->metering = metering;
|
cnetz->metering = metering;
|
||||||
cnetz->ms_power = ms_power;
|
cnetz->ms_power = ms_power;
|
||||||
|
@ -353,6 +356,7 @@ int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* send two cells and select by the first message from mobile */
|
/* send two cells and select by the first message from mobile */
|
||||||
|
cnetz->cell_nr = 0; /* use cell 0 until selected */
|
||||||
cnetz->cell_auto = 1;
|
cnetz->cell_auto = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,13 +372,13 @@ int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev
|
||||||
cnetz_go_idle(cnetz);
|
cnetz_go_idle(cnetz);
|
||||||
|
|
||||||
#ifdef DEBUG_SPK
|
#ifdef DEBUG_SPK
|
||||||
transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1);
|
transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1);
|
||||||
trans->mo_call = 1;
|
trans->mo_call = 1;
|
||||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 2);
|
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 2);
|
||||||
#else
|
#else
|
||||||
/* create transaction for speech channel loopback */
|
/* create transaction for speech channel loopback */
|
||||||
if (loopback && chan_type == CHAN_TYPE_SPK) {
|
if (loopback && chan_type == CHAN_TYPE_SPK) {
|
||||||
transaction_t *trans = create_transaction(cnetz, TRANS_VHQ, 2, 2, 22002, -1);
|
transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1);
|
||||||
trans->mo_call = 1;
|
trans->mo_call = 1;
|
||||||
cnetz_set_dsp_mode(cnetz, DSP_MODE_SPK_K);
|
cnetz_set_dsp_mode(cnetz, DSP_MODE_SPK_K);
|
||||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 0);
|
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 0);
|
||||||
|
@ -384,16 +388,16 @@ int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev
|
||||||
#if 0
|
#if 0
|
||||||
/* debug flushing transactions */
|
/* debug flushing transactions */
|
||||||
transaction_t *trans1, *trans2;
|
transaction_t *trans1, *trans2;
|
||||||
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1);
|
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
|
||||||
destroy_transaction(trans1);
|
destroy_transaction(trans1);
|
||||||
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1);
|
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
|
||||||
destroy_transaction(trans1);
|
destroy_transaction(trans1);
|
||||||
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1);
|
trans1 = create_transaction(cnetz, 99, 6, 2, 15784, -1, -1);
|
||||||
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1);
|
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1);
|
||||||
unlink_transaction(trans1);
|
unlink_transaction(trans1);
|
||||||
link_transaction(trans1, cnetz);
|
link_transaction(trans1, cnetz);
|
||||||
cnetz_flush_other_transactions(cnetz, trans1);
|
cnetz_flush_other_transactions(cnetz, trans1);
|
||||||
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1);
|
trans2 = create_transaction(cnetz, 99, 2, 2, 22002, -1, -1);
|
||||||
cnetz_flush_other_transactions(cnetz, trans2);
|
cnetz_flush_other_transactions(cnetz, trans2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -546,6 +550,7 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||||
{
|
{
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
cnetz_t *cnetz, *spk;
|
cnetz_t *cnetz, *spk;
|
||||||
|
int rc;
|
||||||
int extended;
|
int extended;
|
||||||
transaction_t *trans;
|
transaction_t *trans;
|
||||||
uint8_t futln_nat;
|
uint8_t futln_nat;
|
||||||
|
@ -575,8 +580,8 @@ inval:
|
||||||
futln_rest = atoi(dialing + 2);
|
futln_rest = atoi(dialing + 2);
|
||||||
|
|
||||||
/* 2. check if the subscriber is attached */
|
/* 2. check if the subscriber is attached */
|
||||||
extended = find_db(futln_nat, futln_fuvst, futln_rest);
|
rc = find_db(futln_nat, futln_fuvst, futln_rest, NULL, &extended);
|
||||||
if (extended < 0) {
|
if (rc < 0) {
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to not attached subscriber, rejecting!\n");
|
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing call to not attached subscriber, rejecting!\n");
|
||||||
return -CAUSE_OUTOFORDER;
|
return -CAUSE_OUTOFORDER;
|
||||||
}
|
}
|
||||||
|
@ -614,7 +619,7 @@ inval:
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Call to mobile station, paging station id '%s'\n", dialing);
|
||||||
|
|
||||||
/* 6. trying to page mobile station */
|
/* 6. trying to page mobile station */
|
||||||
trans = create_transaction(cnetz, (spk) ? TRANS_VAK : TRANS_WSK, dialing[0] - '0', dialing[1] - '0', atoi(dialing + 2), -1);
|
trans = create_transaction(cnetz, (spk) ? TRANS_VAK : TRANS_WSK, dialing[0] - '0', dialing[1] - '0', atoi(dialing + 2), -1, -1);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
||||||
return -CAUSE_TEMPFAIL;
|
return -CAUSE_TEMPFAIL;
|
||||||
|
@ -730,7 +735,7 @@ int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_res
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "'Meldeaufruf', but OgK is currently busy!\n");
|
PDEBUG(DCNETZ, DEBUG_NOTICE, "'Meldeaufruf', but OgK is currently busy!\n");
|
||||||
return -CAUSE_NOCHANNEL;
|
return -CAUSE_NOCHANNEL;
|
||||||
}
|
}
|
||||||
trans = create_transaction(cnetz, TRANS_MA, futln_nat, futln_fuvst, futln_rest, -1);
|
trans = create_transaction(cnetz, TRANS_MA, futln_nat, futln_fuvst, futln_rest, -1, -1);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
||||||
return -CAUSE_TEMPFAIL;
|
return -CAUSE_TEMPFAIL;
|
||||||
|
@ -833,7 +838,24 @@ void transaction_timeout(struct timer *timer)
|
||||||
trans_new_state(trans, TRANS_AF);
|
trans_new_state(trans, TRANS_AF);
|
||||||
trans->repeat = 0;
|
trans->repeat = 0;
|
||||||
break;
|
break;
|
||||||
case TRANS_VHQ:
|
case TRANS_ZFZ:
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after sending random number 'Zufallszahl'\n");
|
||||||
|
if (trans->callref) {
|
||||||
|
call_up_release(trans->callref, CAUSE_TEMPFAIL);
|
||||||
|
trans->callref = 0;
|
||||||
|
}
|
||||||
|
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
|
||||||
|
break;
|
||||||
|
case TRANS_AP:
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after waiting for challenge response 'Autorisierungsparameter'\n");
|
||||||
|
if (trans->callref) {
|
||||||
|
call_up_release(trans->callref, CAUSE_TEMPFAIL);
|
||||||
|
trans->callref = 0;
|
||||||
|
}
|
||||||
|
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
|
||||||
|
break;
|
||||||
|
case TRANS_VHQ_K:
|
||||||
|
case TRANS_VHQ_V:
|
||||||
if (cnetz->dsp_mode != DSP_MODE_SPK_V)
|
if (cnetz->dsp_mode != DSP_MODE_SPK_V)
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response while holding call 'Quittung Verbindung halten'\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response while holding call 'Quittung Verbindung halten'\n");
|
||||||
else
|
else
|
||||||
|
@ -929,7 +951,7 @@ const telegramm_t *cnetz_transmit_telegramm_rufblock(cnetz_t *cnetz)
|
||||||
telegramm.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
|
telegramm.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
|
||||||
telegramm.zeitschlitz_nr = cnetz->sched_ts;
|
telegramm.zeitschlitz_nr = cnetz->sched_ts;
|
||||||
telegramm.grenzwert_fuer_einbuchen_und_umbuchen = si[cnetz->cell_nr].grenz_einbuchen;
|
telegramm.grenzwert_fuer_einbuchen_und_umbuchen = si[cnetz->cell_nr].grenz_einbuchen;
|
||||||
telegramm.authentifikationsbit = cnetz->auth;
|
telegramm.authentifikationsbit = si[cnetz->cell_nr].authentifikationsbit;
|
||||||
telegramm.vermittlungstechnische_sperren = si[cnetz->cell_nr].vermittlungstechnische_sperren;
|
telegramm.vermittlungstechnische_sperren = si[cnetz->cell_nr].vermittlungstechnische_sperren;
|
||||||
telegramm.ws_kennung = si[cnetz->cell_nr].ws_kennung;
|
telegramm.ws_kennung = si[cnetz->cell_nr].ws_kennung;
|
||||||
telegramm.reduzierungsfaktor = si[cnetz->cell_nr].reduzierung;
|
telegramm.reduzierungsfaktor = si[cnetz->cell_nr].reduzierung;
|
||||||
|
@ -1114,7 +1136,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
|
||||||
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
|
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
|
||||||
break;
|
break;
|
||||||
rufnummer = telegramm2rufnummer(telegramm);
|
rufnummer = telegramm2rufnummer(telegramm);
|
||||||
if (cnetz->auth && telegramm->chipkarten_futelg_bit)
|
if (si[cnetz->cell_nr].authentifikationsbit && telegramm->chipkarten_futelg_bit)
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
|
||||||
else
|
else
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Attachment 'Einbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
|
||||||
|
@ -1124,7 +1146,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Attachment from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
|
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Attachment from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trans = create_transaction(cnetz, TRANS_EM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->erweitertes_frequenzbandbit);
|
trans = create_transaction(cnetz, TRANS_EM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
||||||
break;
|
break;
|
||||||
|
@ -1135,7 +1157,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
|
||||||
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
|
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr))
|
||||||
break;
|
break;
|
||||||
rufnummer = telegramm2rufnummer(telegramm);
|
rufnummer = telegramm2rufnummer(telegramm);
|
||||||
if (cnetz->auth && telegramm->chipkarten_futelg_bit)
|
if (si[cnetz->cell_nr].authentifikationsbit && telegramm->chipkarten_futelg_bit)
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with chip card's ID %d (vendor id %d, hardware version %d, software version %d)\n", rufnummer, telegramm->kartenkennung, telegramm->herstellerkennung, telegramm->hardware_des_futelg, telegramm->software_des_futelg);
|
||||||
else
|
else
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received Roaming 'Umbuchen' message from Subscriber '%s' with %s card's security code %d\n", rufnummer, (telegramm->chipkarten_futelg_bit) ? "chip":"magnet", telegramm->sicherungs_code);
|
||||||
|
@ -1145,7 +1167,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Roaming from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
|
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Roaming from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trans = create_transaction(cnetz, TRANS_UM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->erweitertes_frequenzbandbit);
|
trans = create_transaction(cnetz, TRANS_UM, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->chipkarten_futelg_bit, telegramm->erweitertes_frequenzbandbit);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
||||||
break;
|
break;
|
||||||
|
@ -1169,7 +1191,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
|
||||||
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Call from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
|
PDEBUG(DCNETZ, DEBUG_NOTICE, "Ignoring Call from subscriber '%s', because we are busy becoming SpK.\n", rufnummer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trans = create_transaction(cnetz, TRANS_VWG, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1);
|
trans = create_transaction(cnetz, TRANS_VWG, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, telegramm->erweitertes_frequenzbandbit);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
||||||
break;
|
break;
|
||||||
|
@ -1199,7 +1221,7 @@ void cnetz_receive_telegramm_ogk(cnetz_t *cnetz, telegramm_t *telegramm, int blo
|
||||||
trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
|
trans = search_transaction_number(cnetz, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
/* create transaction, in case the phone repeats the release after we have acked it */
|
/* create transaction, in case the phone repeats the release after we have acked it */
|
||||||
trans = create_transaction(cnetz, TRANS_ATQ, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, telegramm->erweitertes_frequenzbandbit);
|
trans = create_transaction(cnetz, TRANS_ATQ, telegramm->futln_nationalitaet, telegramm->futln_heimat_fuvst_nr, telegramm->futln_rest_nr, -1, -1);
|
||||||
if (!trans) {
|
if (!trans) {
|
||||||
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to create transaction\n");
|
||||||
break;
|
break;
|
||||||
|
@ -1262,21 +1284,46 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
|
||||||
telegramm.futln_rest_nr = trans->futln_rest;
|
telegramm.futln_rest_nr = trans->futln_rest;
|
||||||
telegramm.frequenz_nr = cnetz->sender.kanal;
|
telegramm.frequenz_nr = cnetz->sender.kanal;
|
||||||
telegramm.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
|
telegramm.bedingte_genauigkeit_der_fufst = si[cnetz->cell_nr].genauigkeit;
|
||||||
|
telegramm.zufallszahl = cnetz->challenge;
|
||||||
|
|
||||||
switch (trans->state) {
|
switch (trans->state) {
|
||||||
case TRANS_BQ:
|
case TRANS_BQ:
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Belegungsquittung' on traffic channel\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Belegungsquittung' on traffic channel\n");
|
||||||
telegramm.opcode = OPCODE_BQ_K;
|
telegramm.opcode = OPCODE_BQ_K;
|
||||||
if (++trans->repeat >= 8 && !timer_running(&trans->timer)) {
|
if (++trans->repeat >= 8 && !timer_running(&trans->timer)) {
|
||||||
trans_new_state(trans, TRANS_VHQ);
|
if (cnetz->challenge_valid) {
|
||||||
|
if (si[cnetz->cell_nr].authentifikationsbit == 0) {
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Cannot authenticate, because base station does not support it. (Authentication disabled in sysinfo.)\n");
|
||||||
|
goto no_auth;
|
||||||
|
}
|
||||||
|
if (trans->futelg_bit == 0) {
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Cannot authenticate, because mobile station does not support it. (Mobile station has magnetic card.)\n");
|
||||||
|
goto no_auth;
|
||||||
|
}
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Perform authentication with subscriber's card.\n");
|
||||||
|
trans_new_state(trans, TRANS_ZFZ);
|
||||||
|
timer_start(&trans->timer, 0.0375 * F_ZFZ); /* F_ZFZ frames */
|
||||||
|
} else {
|
||||||
|
no_auth:
|
||||||
|
trans_new_state(trans, TRANS_VHQ_K);
|
||||||
|
timer_start(&trans->timer, 0.0375 * F_VHQK); /* F_VHQK frames */
|
||||||
|
}
|
||||||
trans->repeat = 0;
|
trans->repeat = 0;
|
||||||
timer_start(&trans->timer, 0.0375 * F_VHQK); /* F_VHQK frames */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TRANS_VHQ:
|
case TRANS_ZFZ:
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Zufallszahl' on traffic channel (0x%016" PRIx64 ").\n", telegramm.zufallszahl);
|
||||||
|
telegramm.opcode = OPCODE_ZFZ_K;
|
||||||
|
break;
|
||||||
|
case TRANS_AP:
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
|
||||||
|
telegramm.opcode = OPCODE_VHQ_K;
|
||||||
|
break;
|
||||||
|
case TRANS_VHQ_K:
|
||||||
if (!cnetz->sender.loopback)
|
if (!cnetz->sender.loopback)
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten' on traffic channel\n");
|
||||||
telegramm.opcode = OPCODE_VHQ_K;
|
telegramm.opcode = OPCODE_VHQ_K;
|
||||||
|
/* continue until next sub frame, so we send DS from first block of next sub frame. */
|
||||||
if (!cnetz->sender.loopback && (cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !timer_running(&trans->timer)) {
|
if (!cnetz->sender.loopback && (cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !timer_running(&trans->timer)) {
|
||||||
/* next sub frame */
|
/* next sub frame */
|
||||||
if (trans->mo_call) {
|
if (trans->mo_call) {
|
||||||
|
@ -1304,9 +1351,10 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
|
||||||
case TRANS_DS:
|
case TRANS_DS:
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Durchschalten' on traffic channel\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Durchschalten' on traffic channel\n");
|
||||||
telegramm.opcode = OPCODE_DSB_K;
|
telegramm.opcode = OPCODE_DSB_K;
|
||||||
|
/* send exactly a sub frame (8 time slots) */
|
||||||
if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !timer_running(&trans->timer)) {
|
if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m && !timer_running(&trans->timer)) {
|
||||||
/* next sub frame */
|
/* next sub frame */
|
||||||
trans_new_state(trans, TRANS_VHQ);
|
trans_new_state(trans, TRANS_VHQ_V);
|
||||||
trans->repeat = 0;
|
trans->repeat = 0;
|
||||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
|
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
|
||||||
#ifndef DEBUG_SPK
|
#ifndef DEBUG_SPK
|
||||||
|
@ -1323,7 +1371,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
|
||||||
telegramm.opcode = OPCODE_AHQ_K;
|
telegramm.opcode = OPCODE_AHQ_K;
|
||||||
if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m) {
|
if ((cnetz->sched_ts & 7) == 7 && cnetz->sched_r_m) {
|
||||||
/* next sub frame */
|
/* next sub frame */
|
||||||
trans_new_state(trans, TRANS_VHQ);
|
trans_new_state(trans, TRANS_VHQ_V);
|
||||||
trans->repeat = 0;
|
trans->repeat = 0;
|
||||||
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
|
cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1);
|
||||||
timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */
|
timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */
|
||||||
|
@ -1431,6 +1479,38 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
|
||||||
cnetz->scrambler_switch = 0;
|
cnetz->scrambler_switch = 0;
|
||||||
timer_stop(&trans->timer);
|
timer_stop(&trans->timer);
|
||||||
break;
|
break;
|
||||||
|
case OPCODE_ZFZQ_K:
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received random number acknowledge 'Zufallszahlquittung' message.\n");
|
||||||
|
valid_frame = 1;
|
||||||
|
if (trans->state != TRANS_ZFZ)
|
||||||
|
break;
|
||||||
|
if (cnetz->challenge != telegramm->zufallszahl) {
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received random number acknowledge (0x%016" PRIx64 ") does not match the transmitted one (0x%016" PRIx64 "), ignoring!\n", telegramm->zufallszahl, cnetz->challenge);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timer_stop(&trans->timer);
|
||||||
|
trans_new_state(trans, TRANS_AP);
|
||||||
|
timer_start(&trans->timer, T_AP); /* 750 milliseconds */
|
||||||
|
break;
|
||||||
|
case OPCODE_AP_K:
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received challenge response 'Autorisierungsparameter' message (0x%016" PRIx64 ").\n", telegramm->authorisierungsparameter);
|
||||||
|
valid_frame = 1;
|
||||||
|
if (trans->state != TRANS_AP)
|
||||||
|
break;
|
||||||
|
/* if authentication response from card does not match */
|
||||||
|
if (cnetz->response_valid && telegramm->authorisierungsparameter != cnetz->response) {
|
||||||
|
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Received challenge response (0x%016" PRIx64 ") does not match the expected one (0x%016" PRIx64 "), releasing!\n", telegramm->authorisierungsparameter, cnetz->response);
|
||||||
|
if (trans->callref) {
|
||||||
|
call_up_release(trans->callref, CAUSE_TEMPFAIL); /* jolly guesses that */
|
||||||
|
trans->callref = 0;
|
||||||
|
}
|
||||||
|
cnetz_release(trans, CNETZ_CAUSE_GASSENBESETZT); /* when authentication is not valid */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timer_stop(&trans->timer);
|
||||||
|
trans_new_state(trans, TRANS_VHQ_K);
|
||||||
|
timer_start(&trans->timer, 0.0375 * F_VHQK); /* F_VHQK frames */
|
||||||
|
break;
|
||||||
case OPCODE_VH_K:
|
case OPCODE_VH_K:
|
||||||
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
|
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
|
||||||
break;
|
break;
|
||||||
|
@ -1440,7 +1520,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
|
||||||
}
|
}
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received connection hold 'Verbindung halten' message.\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received connection hold 'Verbindung halten' message.\n");
|
||||||
valid_frame = 1;
|
valid_frame = 1;
|
||||||
if (trans->state != TRANS_VHQ)
|
if (trans->state != TRANS_VHQ_K)
|
||||||
break;
|
break;
|
||||||
timer_stop(&trans->timer);
|
timer_stop(&trans->timer);
|
||||||
break;
|
break;
|
||||||
|
@ -1467,7 +1547,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received answer frame 'Abheben' message.\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Received answer frame 'Abheben' message.\n");
|
||||||
valid_frame = 1;
|
valid_frame = 1;
|
||||||
/* if already received this frame, or if we are already on VHQ or if we are releasing */
|
/* if already received this frame, or if we are already on VHQ or if we are releasing */
|
||||||
if (trans->state == TRANS_AHQ || trans->state == TRANS_VHQ || trans->state == TRANS_AF)
|
if (trans->state == TRANS_AHQ || trans->state == TRANS_VHQ_K || trans->state == TRANS_AF)
|
||||||
break;
|
break;
|
||||||
cnetz->scrambler = telegramm->betriebs_art;
|
cnetz->scrambler = telegramm->betriebs_art;
|
||||||
cnetz->scrambler_switch = 0;
|
cnetz->scrambler_switch = 0;
|
||||||
|
@ -1539,7 +1619,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
|
||||||
telegramm.ausloesegrund = trans->release_cause;
|
telegramm.ausloesegrund = trans->release_cause;
|
||||||
|
|
||||||
switch (trans->state) {
|
switch (trans->state) {
|
||||||
case TRANS_VHQ:
|
case TRANS_VHQ_V:
|
||||||
if ((cnetz->sched_ts & 8) == 0) { /* sub frame 1 and 3 */
|
if ((cnetz->sched_ts & 8) == 0) { /* sub frame 1 and 3 */
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten 1' on traffic channel\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Quittung Verbindung halten 1' on traffic channel\n");
|
||||||
telegramm.opcode = OPCODE_VHQ1_V;
|
telegramm.opcode = OPCODE_VHQ1_V;
|
||||||
|
@ -1557,7 +1637,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_v(cnetz_t *cnetz)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TRANS_AT:
|
case TRANS_AT:
|
||||||
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending 'Auslosen durch FuFst' on traffic channel\n");
|
PDEBUG_CHAN(DCNETZ, DEBUG_INFO, "Sending acknowledge to 'Ausloesen durch FuTln' on traffic channel\n");
|
||||||
telegramm.opcode = OPCODE_AF_V;
|
telegramm.opcode = OPCODE_AF_V;
|
||||||
if (++trans->repeat == 1) {
|
if (++trans->repeat == 1) {
|
||||||
destroy_transaction(trans);
|
destroy_transaction(trans);
|
||||||
|
@ -1589,7 +1669,7 @@ void cnetz_receive_telegramm_spk_v(cnetz_t *cnetz, telegramm_t *telegramm)
|
||||||
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
|
if (!match_futln(telegramm, trans->futln_nat, trans->futln_fuvst, trans->futln_rest)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (trans->state != TRANS_VHQ)
|
if (trans->state != TRANS_VHQ_V)
|
||||||
break;
|
break;
|
||||||
timer_start(&trans->timer, 0.6 * F_VHQ); /* F_VHQ frames */
|
timer_start(&trans->timer, 0.6 * F_VHQ); /* F_VHQ frames */
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ enum cnetz_state {
|
||||||
#define F_BQ 8 /* number of not received frames at BQ state */
|
#define F_BQ 8 /* number of not received frames at BQ state */
|
||||||
#define F_VHQK 16 /* number of not received frames at VHQ state during concentrated signaling */
|
#define F_VHQK 16 /* number of not received frames at VHQ state during concentrated signaling */
|
||||||
#define F_VHQ 16 /* number of not received frames at VHQ state during distributed signaling */
|
#define F_VHQ 16 /* number of not received frames at VHQ state during distributed signaling */
|
||||||
|
#define F_ZFZ 16 /* number of not received frames at ZFZ state (guessed, no documentation avail) */
|
||||||
#define F_DS 16 /* number of not received frames at DS state */
|
#define F_DS 16 /* number of not received frames at DS state */
|
||||||
#define F_RTA 16 /* number of not received frames at RTA state */
|
#define F_RTA 16 /* number of not received frames at RTA state */
|
||||||
#define N_AFKT 6 /* number of release frames to send during concentrated signaling */
|
#define N_AFKT 6 /* number of release frames to send during concentrated signaling */
|
||||||
|
@ -40,6 +41,7 @@ enum cnetz_state {
|
||||||
#define N 3 /* now many times we repeat a message on OgK */
|
#define N 3 /* now many times we repeat a message on OgK */
|
||||||
#define T_VAG2 180 /* time on outgoing queue */
|
#define T_VAG2 180 /* time on outgoing queue */
|
||||||
#define T_VAK 60 /* time on incoming queue */
|
#define T_VAK 60 /* time on incoming queue */
|
||||||
|
#define T_AP 750 /* Time to wait for SIM card's authentication reply */
|
||||||
|
|
||||||
/* clear causes */
|
/* clear causes */
|
||||||
#define CNETZ_CAUSE_GASSENBESETZT 0 /* network congested */
|
#define CNETZ_CAUSE_GASSENBESETZT 0 /* network congested */
|
||||||
|
@ -71,9 +73,12 @@ typedef struct cnetz {
|
||||||
int de_emphasis; /* use de_emphasis by this instance */
|
int de_emphasis; /* use de_emphasis by this instance */
|
||||||
emphasis_t estate;
|
emphasis_t estate;
|
||||||
|
|
||||||
/* cell config */
|
/* call config */
|
||||||
int ms_power; /* power level of MS, use 0..3 */
|
int ms_power; /* power level of MS, use 0..3 */
|
||||||
int auth; /* authentication support of the cell */
|
int challenge_valid; /* send authorizaton value */
|
||||||
|
uint64_t challenge; /* authorization value */
|
||||||
|
int response_valid; /* expect authorizaton response */
|
||||||
|
uint64_t response; /* authorization response */
|
||||||
int warteschlange; /* use queue */
|
int warteschlange; /* use queue */
|
||||||
int metering; /* use metering pulses in seconds 0 = off */
|
int metering; /* use metering pulses in seconds 0 = off */
|
||||||
|
|
||||||
|
@ -133,7 +138,7 @@ int cnetz_channel_by_short_name(const char *short_name);
|
||||||
const char *chan_type_short_name(enum cnetz_chan_type chan_type);
|
const char *chan_type_short_name(enum cnetz_chan_type chan_type);
|
||||||
const char *chan_type_long_name(enum cnetz_chan_type chan_type);
|
const char *chan_type_long_name(enum cnetz_chan_type chan_type);
|
||||||
int cnetz_init(void);
|
int cnetz_init(void);
|
||||||
int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int auth, int warteschlange, int metering, double dbm0_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback);
|
int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int challenge_valid, uint64_t challenge, int response_valid, uint64_t response, int warteschlange, int metering, double dbm0_deviation, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, const char *read_tx_wave, int loopback);
|
||||||
void cnetz_destroy(sender_t *sender);
|
void cnetz_destroy(sender_t *sender);
|
||||||
void cnetz_go_idle(cnetz_t *cnetz);
|
void cnetz_go_idle(cnetz_t *cnetz);
|
||||||
void cnetz_sync_frame(cnetz_t *cnetz, double sync, int ts);
|
void cnetz_sync_frame(cnetz_t *cnetz, double sync, int ts);
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef struct cnetz_database {
|
||||||
uint8_t futln_nat; /* who ... */
|
uint8_t futln_nat; /* who ... */
|
||||||
uint8_t futln_fuvst;
|
uint8_t futln_fuvst;
|
||||||
uint16_t futln_rest;
|
uint16_t futln_rest;
|
||||||
|
int futelg_bit; /* chip card inside */
|
||||||
int extended; /* mobile supports extended frequencies */
|
int extended; /* mobile supports extended frequencies */
|
||||||
struct timer timer; /* timer for next availability check */
|
struct timer timer; /* timer for next availability check */
|
||||||
int retry; /* counts number of retries */
|
int retry; /* counts number of retries */
|
||||||
|
@ -89,7 +90,7 @@ static void db_timeout(struct timer *timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create/update db entry */
|
/* create/update db entry */
|
||||||
int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int extended, int busy, int failed)
|
int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed)
|
||||||
{
|
{
|
||||||
cnetz_db_t *db, **dbp;
|
cnetz_db_t *db, **dbp;
|
||||||
|
|
||||||
|
@ -123,8 +124,11 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t
|
||||||
PDEBUG(DDB, DEBUG_INFO, "Adding subscriber '%d,%d,%d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
|
PDEBUG(DDB, DEBUG_INFO, "Adding subscriber '%d,%d,%d' to database.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extended >= 0)
|
if (futelg_bit && *futelg_bit >= 0)
|
||||||
db->extended = extended;
|
db->futelg_bit = *futelg_bit;
|
||||||
|
|
||||||
|
if (extended && *extended >= 0)
|
||||||
|
db->extended = *extended;
|
||||||
|
|
||||||
if (busy) {
|
if (busy) {
|
||||||
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%d' busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
|
PDEBUG(DDB, DEBUG_INFO, "Subscriber '%d,%d,%d' busy now.\n", db->futln_nat, db->futln_fuvst, db->futln_rest);
|
||||||
|
@ -143,18 +147,27 @@ int update_db(cnetz_t __attribute__((unused)) *cnetz, uint8_t futln_nat, uint8_t
|
||||||
timer_start(&db->timer, MELDE_WIEDERHOLUNG); /* when to do retry */
|
timer_start(&db->timer, MELDE_WIEDERHOLUNG); /* when to do retry */
|
||||||
}
|
}
|
||||||
|
|
||||||
return db->extended;
|
if (futelg_bit)
|
||||||
|
*futelg_bit = db->futelg_bit;
|
||||||
|
if (extended)
|
||||||
|
*extended = db->extended;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest)
|
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended)
|
||||||
{
|
{
|
||||||
cnetz_db_t *db = cnetz_db_head;
|
cnetz_db_t *db = cnetz_db_head;
|
||||||
|
|
||||||
while (db) {
|
while (db) {
|
||||||
if (db->futln_nat == futln_nat
|
if (db->futln_nat == futln_nat
|
||||||
&& db->futln_fuvst == futln_fuvst
|
&& db->futln_fuvst == futln_fuvst
|
||||||
&& db->futln_rest == futln_rest)
|
&& db->futln_rest == futln_rest) {
|
||||||
return db->extended;
|
if (futelg_bit)
|
||||||
|
*futelg_bit = db->futelg_bit;
|
||||||
|
if (extended)
|
||||||
|
*extended = db->extended;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
db = db->next;
|
db = db->next;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
int update_db(cnetz_t *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int extended, int busy, int failed);
|
int update_db(cnetz_t *cnetz, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended, int busy, int failed);
|
||||||
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
|
int find_db(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int *futelg_bit, int *extended);
|
||||||
void flush_db(void);
|
void flush_db(void);
|
||||||
void dump_db(void);
|
void dump_db(void);
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,16 @@ double clock_speed[2] = { 0.0, 0.0 };
|
||||||
int set_clock_speed = 0;
|
int set_clock_speed = 0;
|
||||||
const char *flip_polarity = "auto";
|
const char *flip_polarity = "auto";
|
||||||
int ms_power = 0; /* 0..3 */
|
int ms_power = 0; /* 0..3 */
|
||||||
int auth = 0;
|
|
||||||
int warteschlange = 1;
|
int warteschlange = 1;
|
||||||
|
int challenge_valid;
|
||||||
|
uint64_t challenge;
|
||||||
|
int response_valid;
|
||||||
|
uint64_t response;
|
||||||
uint8_t fuz_nat = 1;
|
uint8_t fuz_nat = 1;
|
||||||
uint8_t fuz_fuvst = 1;
|
uint8_t fuz_fuvst = 1;
|
||||||
uint8_t fuz_rest = 38;
|
uint8_t fuz_rest = 38;
|
||||||
uint8_t kennung_fufst = 1; /* normal prio */
|
uint8_t kennung_fufst = 1; /* normal prio */
|
||||||
|
uint8_t authentifikationsbit = 0;
|
||||||
uint8_t ws_kennung = 0; /* no queue */
|
uint8_t ws_kennung = 0; /* no queue */
|
||||||
uint8_t fuvst_sperren = 0; /* no blocking registration/calls */
|
uint8_t fuvst_sperren = 0; /* no blocking registration/calls */
|
||||||
uint8_t grenz_einbuchen = 1; /* > 15 SNR */
|
uint8_t grenz_einbuchen = 1; /* > 15 SNR */
|
||||||
|
@ -94,10 +98,16 @@ void print_help(const char *arg0)
|
||||||
printf(" -P --ms-power <power level>\n");
|
printf(" -P --ms-power <power level>\n");
|
||||||
printf(" Give power level of the mobile station 0..3. (default = '%d')\n", ms_power);
|
printf(" Give power level of the mobile station 0..3. (default = '%d')\n", ms_power);
|
||||||
printf(" 0 = 50-125 mW; 1 = 0.5-1 W; 2 = 4-8 W; 3 = 10-20 W\n");
|
printf(" 0 = 50-125 mW; 1 = 0.5-1 W; 2 = 4-8 W; 3 = 10-20 W\n");
|
||||||
printf(" -A --authentication\n");
|
printf(" -A --authentication <challenge>\n");
|
||||||
printf(" Enable authentication on the base station. Since we cannot\n");
|
printf(" Enable authorization flag on the base station and use given challenge\n");
|
||||||
printf(" authenticate, because we don't know the secret key and the algorithm,\n");
|
printf(" as autorization random. Depending on the key inside the card you will\n");
|
||||||
printf(" we just accept any card. With this we get the vendor IDs of the phone.\n");
|
printf(" get a response. Any response is accepted. Phone must have smart card!\n");
|
||||||
|
printf(" The challenge can be any 64 bit (hex) number like: 0x0123456789abcdef\n");
|
||||||
|
printf(" Note: Authentication is automatically enabled for the base station\n");
|
||||||
|
printf(" -A --authentication <challenge>,<response>\n");
|
||||||
|
printf(" Same as above, but the given response must match the response from\n");
|
||||||
|
printf(" smart card. The response can be any 64 bit (hex) number.\n");
|
||||||
|
printf(" Note: Authentication is automatically enabled for the base station\n");
|
||||||
printf(" -Q --queue | --warteschlange 1 | 0\n");
|
printf(" -Q --queue | --warteschlange 1 | 0\n");
|
||||||
printf(" Enable queue support. If no channel is available, calls will be kept\n");
|
printf(" Enable queue support. If no channel is available, calls will be kept\n");
|
||||||
printf(" in a queue for maximum of 60 seconds. (default = %d)\n", warteschlange);
|
printf(" in a queue for maximum of 60 seconds. (default = %d)\n", warteschlange);
|
||||||
|
@ -122,6 +132,13 @@ void print_help(const char *arg0)
|
||||||
printf(" 2 = Higher priority base station.\n");
|
printf(" 2 = Higher priority base station.\n");
|
||||||
printf(" 3 = Highest priority base station.\n");
|
printf(" 3 = Highest priority base station.\n");
|
||||||
printf(" Note: Priority has no effect, because there is only one base station.\n");
|
printf(" Note: Priority has no effect, because there is only one base station.\n");
|
||||||
|
printf(" -A --sysinfo authentifikationsbit=auth>\n");
|
||||||
|
printf(" Enable authentication flag on the base station. Since we cannot\n");
|
||||||
|
printf(" authenticate, because we don't know the secret key and the algorithm,\n");
|
||||||
|
printf(" we just accept any card. Useful get the vendor IDs of the phone.\n");
|
||||||
|
printf(" 0 = Disable. Even chip card phones behave like magnetic card phones.\n");
|
||||||
|
printf(" 1 = Enable. Chip card phones send their card ID.\n");
|
||||||
|
printf(" (default = %d)\n", authentifikationsbit);
|
||||||
printf(" -S --sysinfo ws-kennung=<value>\n");
|
printf(" -S --sysinfo ws-kennung=<value>\n");
|
||||||
printf(" Queue setting of base station. (default = %d)\n", ws_kennung);
|
printf(" Queue setting of base station. (default = %d)\n", ws_kennung);
|
||||||
printf(" 0 = No queue, calls will be handled directly.\n");
|
printf(" 0 = No queue, calls will be handled directly.\n");
|
||||||
|
@ -231,7 +248,7 @@ static void add_options(void)
|
||||||
option_add('C', "clock-speed", 1);
|
option_add('C', "clock-speed", 1);
|
||||||
option_add('F', "flip-polarity", 1);
|
option_add('F', "flip-polarity", 1);
|
||||||
option_add('P', "ms-power", 1);
|
option_add('P', "ms-power", 1);
|
||||||
option_add('A', "authentication", 0);
|
option_add('A', "authentifikationsbit", 1);
|
||||||
option_add('Q', "queue", 1);
|
option_add('Q', "queue", 1);
|
||||||
option_add(OPT_WARTESCHLANGE, "warteschlange", 1);
|
option_add(OPT_WARTESCHLANGE, "warteschlange", 1);
|
||||||
option_add('G', "gebuehren", 1);
|
option_add('G', "gebuehren", 1);
|
||||||
|
@ -287,11 +304,18 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
ms_power = atoi_limit(argv[argi], 0, 3);
|
ms_power = atoi_limit(argv[argi], 0, 3);
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
auth = 1;
|
authentifikationsbit = 1;
|
||||||
|
challenge_valid = 1;
|
||||||
|
challenge = strtoul(argv[argi], NULL, 0);
|
||||||
|
p = strchr(argv[argi], ',');
|
||||||
|
if (p) {
|
||||||
|
response_valid = 1;
|
||||||
|
response = strtoul(p + 1, NULL, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
case OPT_WARTESCHLANGE:
|
case OPT_WARTESCHLANGE:
|
||||||
warteschlange = atoi_limit(argv[argi], 0, 1);;
|
warteschlange = atoi_limit(argv[argi], 0, 1);
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
metering = atoi(argv[argi]);
|
metering = atoi(argv[argi]);
|
||||||
|
@ -318,6 +342,9 @@ static int handle_options(int short_option, int argi, char **argv)
|
||||||
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
|
if (!strncasecmp(argv[argi], "kennung-fufst=", p - argv[argi])) {
|
||||||
kennung_fufst = atoi_limit(p, 0, 3);
|
kennung_fufst = atoi_limit(p, 0, 3);
|
||||||
} else
|
} else
|
||||||
|
if (!strncasecmp(argv[argi], "auth=", p - argv[argi])) {
|
||||||
|
authentifikationsbit = atoi_limit(p, 0, 1);
|
||||||
|
} else
|
||||||
if (!strncasecmp(argv[argi], "ws-kennung=", p - argv[argi])) {
|
if (!strncasecmp(argv[argi], "ws-kennung=", p - argv[argi])) {
|
||||||
ws_kennung = atoi_limit(p, 0, 3);
|
ws_kennung = atoi_limit(p, 0, 3);
|
||||||
} else
|
} else
|
||||||
|
@ -481,7 +508,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (anzahl_gesperrter_teilnehmergruppen)
|
if (anzahl_gesperrter_teilnehmergruppen)
|
||||||
printf("Blocked subscriber with number's last 4 bits from 0x%x to 0x%x\n", teilnehmergruppensperre, (teilnehmergruppensperre + anzahl_gesperrter_teilnehmergruppen - 1) & 0xf);
|
printf("Blocked subscriber with number's last 4 bits from 0x%x to 0x%x\n", teilnehmergruppensperre, (teilnehmergruppensperre + anzahl_gesperrter_teilnehmergruppen - 1) & 0xf);
|
||||||
init_sysinfo(fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen);
|
init_sysinfo(fuz_nat, fuz_fuvst, fuz_rest, kennung_fufst, authentifikationsbit, ws_kennung, fuvst_sperren, grenz_einbuchen, grenz_umschalten, grenz_ausloesen, mittel_umschalten, mittel_ausloesen, genauigkeit, bewertung, entfernung, reduzierung, nachbar_prio, teilnehmergruppensperre, anzahl_gesperrter_teilnehmergruppen);
|
||||||
dsp_init();
|
dsp_init();
|
||||||
rc = init_telegramm();
|
rc = init_telegramm();
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@ -551,7 +578,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* create transceiver instance */
|
/* create transceiver instance */
|
||||||
for (i = 0; i < num_kanal; i++) {
|
for (i = 0; i < num_kanal; i++) {
|
||||||
rc = cnetz_create(kanal[i], chan_type[i], audiodev[i], use_sdr, demod, samplerate, rx_gain, auth, warteschlange, metering, dbm0_deviation, ms_power, (i == 0) ? measure_speed : 0, clock_speed, polarity, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, loopback);
|
rc = cnetz_create(kanal[i], chan_type[i], audiodev[i], use_sdr, demod, samplerate, rx_gain, challenge_valid, challenge, response_valid, response, warteschlange, metering, dbm0_deviation, ms_power, (i == 0) ? measure_speed : 0, clock_speed, polarity, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, read_tx_wave, 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");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
cnetz_si si[2];
|
cnetz_si si[2];
|
||||||
|
|
||||||
void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen)
|
void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen)
|
||||||
{
|
{
|
||||||
memset(&si[0], 0, sizeof(cnetz_si));
|
memset(&si[0], 0, sizeof(cnetz_si));
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t
|
||||||
|
|
||||||
si[0].kennung_fufst = kennung_fufst;
|
si[0].kennung_fufst = kennung_fufst;
|
||||||
|
|
||||||
|
si[0].authentifikationsbit = authentifikationsbit;
|
||||||
|
|
||||||
si[0].ws_kennung = ws_kennung;
|
si[0].ws_kennung = ws_kennung;
|
||||||
|
|
||||||
si[0].nachbar_prio = nachbar_prio;
|
si[0].nachbar_prio = nachbar_prio;
|
||||||
|
|
|
@ -13,6 +13,7 @@ typedef struct system_information {
|
||||||
uint8_t entfernung;
|
uint8_t entfernung;
|
||||||
uint8_t grenz_einbuchen;
|
uint8_t grenz_einbuchen;
|
||||||
uint8_t kennung_fufst; /* prio of base station */
|
uint8_t kennung_fufst; /* prio of base station */
|
||||||
|
uint8_t authentifikationsbit; /* base station suppoerts authentication */
|
||||||
uint8_t ws_kennung; /* queue setting sof base station */
|
uint8_t ws_kennung; /* queue setting sof base station */
|
||||||
uint8_t nachbar_prio;
|
uint8_t nachbar_prio;
|
||||||
uint8_t bewertung;
|
uint8_t bewertung;
|
||||||
|
@ -23,5 +24,5 @@ typedef struct system_information {
|
||||||
|
|
||||||
extern cnetz_si si[];
|
extern cnetz_si si[];
|
||||||
|
|
||||||
void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen);
|
void init_sysinfo(uint8_t fuz_nat, uint8_t fuz_fuvst, uint8_t fuz_rest, uint8_t kennung_fufst, uint8_t authentifikationsbit, uint8_t ws_kennung, uint8_t vermittlungstechnische_sperren, uint8_t grenz_einbuchen, uint8_t grenz_umschalten, uint8_t grenz_ausloesen, uint8_t mittel_umschalten, uint8_t mittel_ausloesen, uint8_t genauigkeit, uint8_t bewertung, uint8_t entfernung, uint8_t reduzierung, uint8_t nachbar_prio, int8_t teilnehmergruppensperre, uint8_t anzahl_gesperrter_teilnehmergruppen);
|
||||||
|
|
||||||
|
|
|
@ -1486,7 +1486,7 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
disassemble_telegramm(&telegramm, bits, cnetz->auth);
|
disassemble_telegramm(&telegramm, bits, si[cnetz->cell_nr].authentifikationsbit);
|
||||||
opcode = telegramm.opcode;
|
opcode = telegramm.opcode;
|
||||||
telegramm.level = level;
|
telegramm.level = level;
|
||||||
telegramm.sync_time = sync_time;
|
telegramm.sync_time = sync_time;
|
||||||
|
|
|
@ -101,7 +101,7 @@ typedef struct telegramm {
|
||||||
uint8_t authentifikationsbit;
|
uint8_t authentifikationsbit;
|
||||||
uint8_t mittelungsfaktor_fuer_ausloesen;
|
uint8_t mittelungsfaktor_fuer_ausloesen;
|
||||||
uint8_t mittelungsfaktor_fuer_umschalten;
|
uint8_t mittelungsfaktor_fuer_umschalten;
|
||||||
uint16_t zufallszahl;
|
uint64_t zufallszahl;
|
||||||
uint8_t bewertung_nach_pegel_und_entfernung;
|
uint8_t bewertung_nach_pegel_und_entfernung;
|
||||||
uint64_t authorisierungsparameter;
|
uint64_t authorisierungsparameter;
|
||||||
uint8_t entfernungsangabe_der_fufst;
|
uint8_t entfernungsangabe_der_fufst;
|
||||||
|
|
|
@ -38,7 +38,7 @@ const char *transaction2rufnummer(transaction_t *trans)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create transaction */
|
/* create transaction */
|
||||||
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int extended)
|
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended)
|
||||||
{
|
{
|
||||||
sender_t *sender;
|
sender_t *sender;
|
||||||
transaction_t *trans = NULL;
|
transaction_t *trans = NULL;
|
||||||
|
@ -88,7 +88,9 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
|
||||||
link_transaction(trans, cnetz);
|
link_transaction(trans, cnetz);
|
||||||
|
|
||||||
/* update database: now busy */
|
/* update database: now busy */
|
||||||
trans->extended = update_db(cnetz, futln_nat, futln_fuvst, futln_rest, extended, 1, 0);
|
update_db(cnetz, futln_nat, futln_fuvst, futln_rest, &futelg_bit, &extended, 1, 0);
|
||||||
|
trans->futelg_bit = futelg_bit;
|
||||||
|
trans->extended = extended;
|
||||||
|
|
||||||
return trans;
|
return trans;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +99,7 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
|
||||||
void destroy_transaction(transaction_t *trans)
|
void destroy_transaction(transaction_t *trans)
|
||||||
{
|
{
|
||||||
/* update database: now idle */
|
/* update database: now idle */
|
||||||
update_db(trans->cnetz, trans->futln_nat, trans->futln_fuvst, trans->futln_rest, -1, 0, trans->page_failed);
|
update_db(trans->cnetz, trans->futln_nat, trans->futln_fuvst, trans->futln_rest, NULL, NULL, 0, trans->page_failed);
|
||||||
|
|
||||||
unlink_transaction(trans);
|
unlink_transaction(trans);
|
||||||
|
|
||||||
|
@ -228,8 +230,14 @@ static const char *trans_state_name(uint64_t state)
|
||||||
return "VAK";
|
return "VAK";
|
||||||
case TRANS_BQ:
|
case TRANS_BQ:
|
||||||
return "BQ";
|
return "BQ";
|
||||||
case TRANS_VHQ:
|
case TRANS_ZFZ:
|
||||||
return "VHQ";
|
return "ZFZ";
|
||||||
|
case TRANS_VHQ_K:
|
||||||
|
return "VHQ_K";
|
||||||
|
case TRANS_VHQ_V:
|
||||||
|
return "VHQ_V";
|
||||||
|
case TRANS_AP:
|
||||||
|
return "AP";
|
||||||
case TRANS_RTA:
|
case TRANS_RTA:
|
||||||
return "RTA";
|
return "RTA";
|
||||||
case TRANS_DS:
|
case TRANS_DS:
|
||||||
|
@ -273,11 +281,15 @@ const char *trans_short_state_name(uint64_t state)
|
||||||
case TRANS_WBP:
|
case TRANS_WBP:
|
||||||
case TRANS_WBN:
|
case TRANS_WBN:
|
||||||
return "DIALING";
|
return "DIALING";
|
||||||
|
case TRANS_ZFZ:
|
||||||
|
case TRANS_AP:
|
||||||
|
return "AUTHENTICATE";
|
||||||
case TRANS_VAG:
|
case TRANS_VAG:
|
||||||
case TRANS_WSK:
|
case TRANS_WSK:
|
||||||
case TRANS_VAK:
|
case TRANS_VAK:
|
||||||
case TRANS_BQ:
|
case TRANS_BQ:
|
||||||
case TRANS_VHQ:
|
case TRANS_VHQ_K:
|
||||||
|
case TRANS_VHQ_V:
|
||||||
return "ASSIGN";
|
return "ASSIGN";
|
||||||
case TRANS_RTA:
|
case TRANS_RTA:
|
||||||
return "ALERT";
|
return "ALERT";
|
||||||
|
|
|
@ -17,20 +17,23 @@
|
||||||
#define TRANS_VAK (1 << 10) /* establishment of call sent, switching channel */
|
#define TRANS_VAK (1 << 10) /* establishment of call sent, switching channel */
|
||||||
/* traffic channel */
|
/* traffic channel */
|
||||||
#define TRANS_BQ (1 << 11) /* accnowledge channel */
|
#define TRANS_BQ (1 << 11) /* accnowledge channel */
|
||||||
#define TRANS_VHQ (1 << 12) /* hold call */
|
#define TRANS_ZFZ (1 << 12) /* hold call and send and receive challenge request */
|
||||||
#define TRANS_RTA (1 << 13) /* hold call and make the phone ring */
|
#define TRANS_AP (1 << 13) /* hold call and send and receive challenge request */
|
||||||
#define TRANS_DS (1 << 14) /* establish speech connection */
|
#define TRANS_VHQ_K (1 << 14) /* hold call until speech channel or challenge response is available */
|
||||||
#define TRANS_AHQ (1 << 15) /* establish speech connection after answer */
|
#define TRANS_VHQ_V (1 << 15) /* hold call while in conversation on distributed signalling */
|
||||||
|
#define TRANS_RTA (1 << 16) /* hold call and make the phone ring */
|
||||||
|
#define TRANS_DS (1 << 17) /* establish speech connection */
|
||||||
|
#define TRANS_AHQ (1 << 18) /* establish speech connection after answer */
|
||||||
/* release */
|
/* release */
|
||||||
#define TRANS_VA (1 << 16) /* release call in queue by base station (OgK) */
|
#define TRANS_VA (1 << 19) /* release call in queue by base station (OgK) */
|
||||||
#define TRANS_AF (1 << 17) /* release connection by base station (SpK) */
|
#define TRANS_AF (1 << 20) /* release connection by base station (SpK) */
|
||||||
#define TRANS_AT (1 << 18) /* release connection by mobile station */
|
#define TRANS_AT (1 << 21) /* release connection by mobile station */
|
||||||
#define TRANS_ATQ (1 << 19) /* acknowledge release of MO call in queue */
|
#define TRANS_ATQ (1 << 22) /* acknowledge release of MO call in queue */
|
||||||
/* queue */
|
/* queue */
|
||||||
#define TRANS_MO_QUEUE (1 << 20) /* MO queue */
|
#define TRANS_MO_QUEUE (1 << 23) /* MO queue */
|
||||||
#define TRANS_MT_QUEUE (1 << 21) /* MT queue */
|
#define TRANS_MT_QUEUE (1 << 24) /* MT queue */
|
||||||
#define TRANS_MO_DELAY (1 << 22) /* delay to be sure the channel is free again */
|
#define TRANS_MO_DELAY (1 << 25) /* delay to be sure the channel is free again */
|
||||||
#define TRANS_MT_DELAY (1 << 23)
|
#define TRANS_MT_DELAY (1 << 26)
|
||||||
|
|
||||||
typedef struct transaction {
|
typedef struct transaction {
|
||||||
struct transaction *next; /* pointer to next node in list */
|
struct transaction *next; /* pointer to next node in list */
|
||||||
|
@ -39,6 +42,7 @@ typedef struct transaction {
|
||||||
uint8_t futln_nat; /* current station ID (3 values) */
|
uint8_t futln_nat; /* current station ID (3 values) */
|
||||||
uint8_t futln_fuvst;
|
uint8_t futln_fuvst;
|
||||||
uint16_t futln_rest;
|
uint16_t futln_rest;
|
||||||
|
int futelg_bit; /* chip card inside phone */
|
||||||
int extended; /* extended frequency capability */
|
int extended; /* extended frequency capability */
|
||||||
char dialing[18]; /* number dialed by the phone */
|
char dialing[18]; /* number dialed by the phone */
|
||||||
int64_t state; /* state of transaction */
|
int64_t state; /* state of transaction */
|
||||||
|
@ -53,7 +57,7 @@ typedef struct transaction {
|
||||||
} transaction_t;
|
} transaction_t;
|
||||||
|
|
||||||
const char *transaction2rufnummer(transaction_t *trans);
|
const char *transaction2rufnummer(transaction_t *trans);
|
||||||
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int extended);
|
transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, int futelg_bit, int extended);
|
||||||
void destroy_transaction(transaction_t *trans);
|
void destroy_transaction(transaction_t *trans);
|
||||||
void link_transaction(transaction_t *trans, cnetz_t *cnetz);
|
void link_transaction(transaction_t *trans, cnetz_t *cnetz);
|
||||||
void unlink_transaction(transaction_t *trans);
|
void unlink_transaction(transaction_t *trans);
|
||||||
|
|
Loading…
Reference in New Issue