Split call control from built-in call console by using MNCC layer

This commit is contained in:
Andreas Eversberg 2017-10-28 07:11:40 +02:00
parent 7cbebaeb75
commit ee3fbeb03b
25 changed files with 926 additions and 854 deletions

View File

@ -643,7 +643,7 @@ void amps_go_idle(amps_t *amps)
if (amps->trans_list) {
PDEBUG(DAMPS, DEBUG_ERROR, "Releasing but still having transaction, please fix!\n");
if (amps->trans_list->callref)
call_in_release(amps->trans_list->callref, CAUSE_NORMAL);
call_up_release(amps->trans_list->callref, CAUSE_NORMAL);
destroy_transaction(amps->trans_list);
}
@ -676,7 +676,7 @@ static void amps_release(transaction_t *trans, uint8_t cause)
trans->order = 3;
/* release towards call control */
if (trans->callref) {
call_in_release(trans->callref, cause);
call_up_release(trans->callref, cause);
trans->callref = 0;
}
/* change DSP mode to transmit release */
@ -709,14 +709,14 @@ void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
break;
timer_stop(&trans->timer);
if (trans->callref)
call_in_release(trans->callref, CAUSE_NORMAL);
call_up_release(trans->callref, CAUSE_NORMAL);
destroy_transaction(trans);
amps_go_idle(amps);
break;
case TRANS_CALL_MT_ALERT:
if (tone) {
timer_stop(&trans->timer);
call_in_alerting(trans->callref);
call_up_alerting(trans->callref);
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_AUDIO_TX, 0);
trans_new_state(trans, TRANS_CALL_MT_ALERT_SEND);
timer_start(&trans->timer, ALERT_TO);
@ -727,7 +727,7 @@ void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
timer_stop(&trans->timer);
if (!trans->sat_detected)
timer_start(&trans->timer, SAT_TO1);
call_in_answer(trans->callref, amps_min2number(trans->min1, trans->min2));
call_up_answer(trans->callref, amps_min2number(trans->min1, trans->min2));
trans_new_state(trans, TRANS_CALL);
}
break;
@ -887,7 +887,7 @@ reject:
*/
/* Call control starts call towards mobile station. */
int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
sender_t *sender;
amps_t *amps;
@ -959,7 +959,7 @@ inval:
return 0;
}
void call_out_answer(int __attribute__((unused)) callref)
void call_down_answer(int __attribute__((unused)) callref)
{
}
@ -967,7 +967,7 @@ void call_out_answer(int __attribute__((unused)) callref)
* An active call stays active, so tones and annoucements can be received
* by mobile station.
*/
void call_out_disconnect(int callref, int cause)
void call_down_disconnect(int callref, int cause)
{
sender_t *sender;
amps_t *amps;
@ -984,7 +984,7 @@ void call_out_disconnect(int callref, int cause)
}
if (!sender) {
PDEBUG(DAMPS, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@ -1001,7 +1001,7 @@ void call_out_disconnect(int callref, int cause)
return;
default:
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call control disconnects on control channel, removing transaction.\n");
call_in_release(callref, cause);
call_up_release(callref, cause);
trans->callref = 0;
destroy_transaction(trans);
amps_go_idle(amps);
@ -1009,7 +1009,7 @@ void call_out_disconnect(int callref, int cause)
}
/* Call control releases call toward mobile station. */
void call_out_release(int callref, int cause)
void call_down_release(int callref, int cause)
{
sender_t *sender;
amps_t *amps;
@ -1046,7 +1046,7 @@ void call_out_release(int callref, int cause)
}
/* Receive audio from call instance. */
void call_rx_audio(int callref, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
amps_t *amps;
@ -1126,7 +1126,7 @@ static amps_t *assign_voice_channel(transaction_t *trans)
if (!trans->callref) {
/* setup call */
PDEBUG(DAMPS, DEBUG_INFO, "Setup call to network.\n");
rc = call_in_setup(callref, callerid, trans->dialing);
rc = call_up_setup(callref, callerid, trans->dialing);
if (rc < 0) {
PDEBUG(DAMPS, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", rc);
amps_release(trans, 0);

View File

@ -841,7 +841,7 @@ static void sender_receive_audio(amps_t *amps, sample_t *samples, int length)
if (pos == 160) {
if (amps->dtx_state == 0)
comfort_noise(spl, 160);
call_tx_audio(trans->callref, spl, 160);
call_up_audio(trans->callref, spl, 160);
pos = 0;
}
}

View File

@ -127,7 +127,7 @@ transaction_t *create_transaction(amps_t *amps, enum amps_trans_state state, uin
if (old_amps) /* should be... */
amps_go_idle(old_amps);
if (old_callref)
call_in_release(old_callref, CAUSE_NORMAL);
call_up_release(old_callref, CAUSE_NORMAL);
}
trans = calloc(1, sizeof(*trans));

View File

@ -287,7 +287,7 @@ void anetz_loss_indication(anetz_t *anetz, double loss_time)
if (anetz->state == ANETZ_GESPRAECH) {
PDEBUG_CHAN(DANETZ, DEBUG_NOTICE, "Detected loss of signal after %.1f seconds, releasing.\n", loss_time);
anetz_release(anetz);
call_in_release(anetz->callref, CAUSE_TEMPFAIL);
call_up_release(anetz->callref, CAUSE_TEMPFAIL);
anetz->callref = 0;
}
}
@ -328,7 +328,7 @@ void anetz_receive_tone(anetz_t *anetz, int tone)
int rc;
PDEBUG_CHAN(DANETZ, DEBUG_INFO, "1750 Hz signal from mobile station is gone, setup call.\n");
rc = call_in_setup(callref, NULL, "010");
rc = call_up_setup(callref, NULL, "010");
if (rc < 0) {
PDEBUG_CHAN(DANETZ, DEBUG_NOTICE, "Call rejected (cause %d), sending release tone.\n", -rc);
anetz_release(anetz);
@ -337,7 +337,7 @@ void anetz_receive_tone(anetz_t *anetz, int tone)
anetz->callref = callref;
} else {
PDEBUG_CHAN(DANETZ, DEBUG_INFO, "1750 Hz signal from mobile station is gone, answer call.\n");
call_in_answer(anetz->callref, anetz->station_id);
call_up_answer(anetz->callref, anetz->station_id);
}
anetz_set_dsp_mode(anetz, DSP_MODE_AUDIO, 0);
}
@ -345,7 +345,7 @@ void anetz_receive_tone(anetz_t *anetz, int tone)
if (tone == 1) {
PDEBUG_CHAN(DANETZ, DEBUG_INFO, "Received 1750 Hz release signal from mobile station, sending release tone.\n");
anetz_release(anetz);
call_in_release(anetz->callref, CAUSE_NORMAL);
call_up_release(anetz->callref, CAUSE_NORMAL);
anetz->callref = 0;
break;
}
@ -373,7 +373,7 @@ static void anetz_timeout(struct timer *timer)
case ANETZ_ANRUF:
PDEBUG_CHAN(DANETZ, DEBUG_NOTICE, "Timeout while waiting for answer, releasing.\n");
anetz_go_idle(anetz);
call_in_release(anetz->callref, CAUSE_NOANSWER);
call_up_release(anetz->callref, CAUSE_NOANSWER);
anetz->callref = 0;
break;
case ANETZ_AUSLOESEN:
@ -385,7 +385,7 @@ static void anetz_timeout(struct timer *timer)
}
/* Call control starts call towards mobile station. */
int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
sender_t *sender;
anetz_t *anetz;
@ -433,12 +433,12 @@ inval:
anetz->callref = callref;
anetz_page(anetz, dialing, freq);
call_in_alerting(callref);
call_up_alerting(callref);
return 0;
}
void call_out_answer(int __attribute__((unused)) callref)
void call_down_answer(int __attribute__((unused)) callref)
{
}
@ -446,7 +446,7 @@ void call_out_answer(int __attribute__((unused)) callref)
* An active call stays active, so tones and annoucements can be received
* by mobile station.
*/
void call_out_disconnect(int callref, int cause)
void call_down_disconnect(int callref, int cause)
{
sender_t *sender;
anetz_t *anetz;
@ -460,7 +460,7 @@ void call_out_disconnect(int callref, int cause)
}
if (!sender) {
PDEBUG(DANETZ, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@ -476,14 +476,14 @@ void call_out_disconnect(int callref, int cause)
break;
}
call_in_release(callref, cause);
call_up_release(callref, cause);
anetz->callref = 0;
}
/* Call control releases call toward mobile station. */
void call_out_release(int callref, __attribute__((unused)) int cause)
void call_down_release(int callref, __attribute__((unused)) int cause)
{
sender_t *sender;
anetz_t *anetz;
@ -518,7 +518,7 @@ void call_out_release(int callref, __attribute__((unused)) int cause)
}
/* Receive audio from call instance. */
void call_rx_audio(int callref, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
anetz_t *anetz;

View File

@ -227,7 +227,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double rf_l
for (i = 0; i < count; i++) {
spl[pos++] = samples[i];
if (pos == 160) {
call_tx_audio(anetz->callref, spl, 160);
call_up_audio(anetz->callref, spl, 160);
pos = 0;
}
}

View File

@ -391,7 +391,7 @@ void bnetz_loss_indication(bnetz_t *bnetz, double loss_time)
|| bnetz->state == BNETZ_RUFHALTUNG) {
PDEBUG_CHAN(DBNETZ, DEBUG_NOTICE, "Detected loss of signal after %.1f seconds, releasing.\n", loss_time);
bnetz_release(bnetz, TRENN_COUNT);
call_in_release(bnetz->callref, CAUSE_TEMPFAIL);
call_up_release(bnetz->callref, CAUSE_TEMPFAIL);
bnetz->callref = 0;
}
}
@ -425,7 +425,7 @@ void bnetz_receive_tone(bnetz_t *bnetz, int bit)
timer_stop(&bnetz->timer);
bnetz_new_state(bnetz, BNETZ_RUFHALTUNG);
bnetz_set_dsp_mode(bnetz, DSP_MODE_1);
call_in_alerting(bnetz->callref);
call_up_alerting(bnetz->callref);
timer_start(&bnetz->timer, ALERTING_TO);
break;
}
@ -439,7 +439,7 @@ void bnetz_receive_tone(bnetz_t *bnetz, int bit)
/* start metering pulses if forced */
if (bnetz->metering < 0)
timer_start(&bnetz->timer, METERING_START);
call_in_answer(bnetz->callref, bnetz->station_id);
call_up_answer(bnetz->callref, bnetz->station_id);
break;
}
default:
@ -615,7 +615,7 @@ void bnetz_receive_telegramm(bnetz_t *bnetz, uint16_t telegramm, double level_av
/* setup call */
PDEBUG(DBNETZ, DEBUG_INFO, "Setup call to network.\n");
rc = call_in_setup(callref, bnetz->station_id, dialing);
rc = call_up_setup(callref, bnetz->station_id, dialing);
if (rc < 0) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", -rc);
bnetz_release(bnetz, TRENN_COUNT);
@ -652,7 +652,7 @@ lets see, if noise will not generate a release signal....
if (digit == 't') {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Received 'Schlusssignal' from mobile station\n");
bnetz_release(bnetz, TRENN_COUNT);
call_in_release(bnetz->callref, CAUSE_NORMAL);
call_up_release(bnetz->callref, CAUSE_NORMAL);
bnetz->callref = 0;
break;
}
@ -691,7 +691,7 @@ static void bnetz_timeout(struct timer *timer)
if (bnetz->page_try == PAGE_TRIES) {
PDEBUG_CHAN(DBNETZ, DEBUG_NOTICE, "Timeout while waiting for call acknowledge from mobile station, going idle.\n");
bnetz_release(bnetz, TRENN_COUNT);
call_in_release(bnetz->callref, CAUSE_OUTOFORDER);
call_up_release(bnetz->callref, CAUSE_OUTOFORDER);
bnetz->callref = 0;
break;
}
@ -701,7 +701,7 @@ static void bnetz_timeout(struct timer *timer)
case BNETZ_RUFHALTUNG:
PDEBUG_CHAN(DBNETZ, DEBUG_NOTICE, "Timeout while waiting for answer of mobile station, releasing.\n");
bnetz_release(bnetz, TRENN_COUNT_NA);
call_in_release(bnetz->callref, CAUSE_NOANSWER);
call_up_release(bnetz->callref, CAUSE_NOANSWER);
bnetz->callref = 0;
break;
case BNETZ_GESPRAECH:
@ -726,7 +726,7 @@ static void bnetz_timeout(struct timer *timer)
}
/* Call control starts call towards mobile station. */
int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
sender_t *sender;
bnetz_t *bnetz;
@ -776,7 +776,7 @@ inval:
return 0;
}
void call_out_answer(int __attribute__((unused)) callref)
void call_down_answer(int __attribute__((unused)) callref)
{
}
@ -784,7 +784,7 @@ void call_out_answer(int __attribute__((unused)) callref)
* An active call stays active, so tones and annoucements can be received
* by mobile station.
*/
void call_out_disconnect(int callref, int cause)
void call_down_disconnect(int callref, int cause)
{
sender_t *sender;
bnetz_t *bnetz;
@ -798,7 +798,7 @@ void call_out_disconnect(int callref, int cause)
}
if (!sender) {
PDEBUG(DBNETZ, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@ -820,13 +820,13 @@ void call_out_disconnect(int callref, int cause)
break;
}
call_in_release(callref, cause);
call_up_release(callref, cause);
bnetz->callref = 0;
}
/* Call control releases call toward mobile station. */
void call_out_release(int callref, int __attribute__((unused)) cause)
void call_down_release(int callref, int __attribute__((unused)) cause)
{
sender_t *sender;
bnetz_t *bnetz;
@ -867,7 +867,7 @@ void call_out_release(int callref, int __attribute__((unused)) cause)
}
/* Receive audio from call instance. */
void call_rx_audio(int callref, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
bnetz_t *bnetz;

View File

@ -239,7 +239,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double rf_l
for (i = 0; i < count; i++) {
spl[pos++] = samples[i];
if (pos == 160) {
call_tx_audio(bnetz->callref, spl, 160);
call_up_audio(bnetz->callref, spl, 160);
pos = 0;
}
}

View File

@ -486,7 +486,7 @@ void cnetz_go_idle(cnetz_t *cnetz)
if (cnetz->trans_list) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Releasing but still having transaction, please fix!\n");
if (cnetz->trans_list->callref)
call_in_release(cnetz->trans_list->callref, CAUSE_NORMAL);
call_up_release(cnetz->trans_list->callref, CAUSE_NORMAL);
destroy_transaction(cnetz->trans_list);
}
@ -524,7 +524,7 @@ static void cnetz_release(transaction_t *trans, uint8_t cause)
}
/* Receive audio from call instance. */
void call_rx_audio(int callref, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
cnetz_t *cnetz;
@ -543,7 +543,7 @@ void call_rx_audio(int callref, sample_t *samples, int count)
}
}
int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
sender_t *sender;
cnetz_t *cnetz, *spk;
@ -626,7 +626,7 @@ inval:
return 0;
}
void call_out_answer(int __attribute__((unused)) callref)
void call_down_answer(int __attribute__((unused)) callref)
{
}
@ -634,7 +634,7 @@ void call_out_answer(int __attribute__((unused)) callref)
* An active call stays active, so tones and annoucements can be received
* by mobile station.
*/
void call_out_disconnect(int callref, int cause)
void call_down_disconnect(int callref, int cause)
{
sender_t *sender;
cnetz_t *cnetz;
@ -651,7 +651,7 @@ void call_out_disconnect(int callref, int cause)
}
if (!sender) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@ -663,12 +663,12 @@ void call_out_disconnect(int callref, int cause)
case DSP_MODE_SPK_K:
PDEBUG(DCNETZ, DEBUG_INFO, "Call control disconnects on speech channel, releasing towards mobile station.\n");
cnetz_release(trans, cnetz_cause_isdn2cnetz(cause));
call_in_release(callref, cause);
call_up_release(callref, cause);
trans->callref = 0;
break;
default:
PDEBUG(DCNETZ, DEBUG_INFO, "Call control disconnects on organisation channel, removing transaction.\n");
call_in_release(callref, cause);
call_up_release(callref, cause);
trans->callref = 0;
if (trans->state == TRANS_MT_QUEUE || trans->state == TRANS_MT_DELAY) {
cnetz_release(trans, cnetz_cause_isdn2cnetz(cause));
@ -681,7 +681,7 @@ void call_out_disconnect(int callref, int cause)
}
/* Call control releases call toward mobile station. */
void call_out_release(int callref, int cause)
void call_down_release(int callref, int cause)
{
sender_t *sender;
cnetz_t *cnetz;
@ -815,7 +815,7 @@ void transaction_timeout(struct timer *timer)
break;
case TRANS_MT_QUEUE:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Phone in queue, but still no channel available, releasing call!\n");
call_in_release(trans->callref, CAUSE_NOCHANNEL);
call_up_release(trans->callref, CAUSE_NOCHANNEL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_GASSENBESETZT);
break;
@ -840,26 +840,26 @@ void transaction_timeout(struct timer *timer)
else
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "Lost signal from 'FuTln' (mobile station)\n");
if (trans->callref) {
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
}
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_DS:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after connect 'Durchschalten'\n");
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_RTA:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after ringing order 'Rufton anschalten'\n");
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
case TRANS_AHQ:
PDEBUG_CHAN(DCNETZ, DEBUG_NOTICE, "No response after answer 'Abhebequittung'\n");
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
break;
@ -1050,7 +1050,7 @@ vak:
telegramm.opcode = OPCODE_WSK_R;
trans_new_state(trans, TRANS_MT_QUEUE);
timer_start(&trans->timer, T_VAK); /* Maximum time to hold queue */
call_in_alerting(trans->callref);
call_up_alerting(trans->callref);
default:
; /* LR */
}
@ -1283,7 +1283,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
if (trans->mo_call) {
int rc;
trans->callref = ++new_callref;
rc = call_in_setup(trans->callref, transaction2rufnummer(trans), trans->dialing);
rc = call_up_setup(trans->callref, transaction2rufnummer(trans), trans->dialing);
if (rc < 0) {
PDEBUG(DCNETZ, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", -rc);
trans->callref = 0;
@ -1298,7 +1298,7 @@ const telegramm_t *cnetz_transmit_telegramm_spk_k(cnetz_t *cnetz)
trans_new_state(trans, TRANS_RTA);
timer_start(&trans->timer, 0.0375 * F_RTA); /* F_RTA frames */
trans->repeat = 0;
call_in_alerting(trans->callref);
call_up_alerting(trans->callref);
}
}
break;
@ -1348,7 +1348,7 @@ call_failed:
trans->page_failed = 1;
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
if (trans->callref)
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
/* must destroy transaction after cnetz_release */
destroy_transaction(trans);
cnetz_go_idle(cnetz);
@ -1364,7 +1364,7 @@ call_failed:
PDEBUG(DCNETZ, DEBUG_NOTICE, "Cannot retry, because currently no OgK available (busy)\n");
cnetz_release(trans, CNETZ_CAUSE_FUNKTECHNISCH);
if (trans->callref)
call_in_release(trans->callref, CAUSE_NOCHANNEL);
call_up_release(trans->callref, CAUSE_NOCHANNEL);
/* must destroy transaction after cnetz_release */
destroy_transaction(trans);
break;
@ -1473,7 +1473,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
trans_new_state(trans, TRANS_AHQ);
trans->repeat = 0;
timer_stop(&trans->timer);
call_in_answer(trans->callref, transaction2rufnummer(trans));
call_up_answer(trans->callref, transaction2rufnummer(trans));
break;
case OPCODE_AT_K:
if (!match_fuz(cnetz, telegramm, cnetz->cell_nr)) {
@ -1491,7 +1491,7 @@ void cnetz_receive_telegramm_spk_k(cnetz_t *cnetz, telegramm_t *telegramm)
trans->repeat = 0;
timer_stop(&trans->timer);
if (trans->callref) {
call_in_release(trans->callref, CAUSE_NORMAL);
call_up_release(trans->callref, CAUSE_NORMAL);
trans->callref = 0;
}
break;
@ -1622,7 +1622,7 @@ void cnetz_receive_telegramm_spk_v(cnetz_t *cnetz, telegramm_t *telegramm)
trans->repeat = 0;
timer_stop(&trans->timer);
if (trans->callref) {
call_in_release(trans->callref, CAUSE_NORMAL);
call_up_release(trans->callref, CAUSE_NORMAL);
trans->callref = 0;
}
break;

View File

@ -837,7 +837,7 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
for (i = 0; i < count; i++) {
spl[pos++] = speech_buffer[i];
if (pos == 160) {
call_tx_audio(cnetz->trans_list->callref, spl, 160);
call_up_audio(cnetz->trans_list->callref, spl, 160);
pos = 0;
}
}

View File

@ -62,7 +62,7 @@ transaction_t *create_transaction(cnetz_t *cnetz, uint64_t state, uint8_t futln_
if (old_cnetz) /* should be... */
cnetz_go_idle(old_cnetz);
if (old_callref)
call_in_release(old_callref, CAUSE_NORMAL);
call_up_release(old_callref, CAUSE_NORMAL);
}
trans = calloc(1, sizeof(*trans));

View File

@ -27,6 +27,7 @@ libmobile_a_SOURCES = \
cause.c \
call.c \
testton.c \
mncc_console.c \
mncc_sock.c \
hagelbarger.c \
display_status.c \

File diff suppressed because it is too large Load Diff

View File

@ -9,34 +9,32 @@ enum number_type {
TYPE_INTERNATIONAL,
};
int call_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int use_mncc_sock, int send_patterns, int release_on_disconnect, int echo_test);
void call_cleanup(void);
int call_open_audio(int latspl);
int call_start_audio(void);
void process_call(int c);
void clear_console_text(void);
void print_console_text(void);
int call_init(int _send_patterns, int _release_on_disconnect);
/* function pointer to delive MNCC messages to upper layer */
extern int (*mncc_up)(uint8_t *buf, int length);
/* MNCC messages from upper layer */
void mncc_down(uint8_t *buf, int length);
/* flush all calls in case of MNCC socket failure */
void mncc_flush(void);
/* received messages */
int call_in_setup(int callref, const char *callerid, const char *dialing);
void call_in_alerting(int callref);
void call_in_answer(int callref, const char *connect_id);
void call_in_release(int callref, int cause);
int call_up_setup(int callref, const char *callerid, const char *dialing);
void call_up_alerting(int callref);
void call_up_answer(int callref, const char *connect_id);
void call_up_release(int callref, int cause);
void call_tone_recall(int callref, int on);
/* send messages */
int call_out_setup(int callref, const char *caller_id, enum number_type caller_type, const char *dialing);
void call_out_answer(int callref);
void call_out_disconnect(int callref, int cause);
void call_out_release(int callref, int cause);
int call_down_setup(int callref, const char *caller_id, enum number_type caller_type, const char *dialing);
void call_down_answer(int callref);
void call_down_disconnect(int callref, int cause);
void call_down_release(int callref, int cause);
/* send and receive audio */
void call_rx_audio(int callref, sample_t *samples, int count);
void call_tx_audio(int callref, sample_t *samples, int count);
void call_up_audio(int callref, sample_t *samples, int count);
void call_down_audio(int callref, sample_t *samples, int count);
/* receive from mncc */
void call_mncc_recv(uint8_t *buf, int length);
void call_mncc_flush(void);
/* clock to transmit to */
void call_mncc_clock(void);
void call_clock(void);

View File

@ -7,6 +7,9 @@
#define CAUSE_TEMPFAIL 41
#define CAUSE_INVALCALLREF 81
#define LOCATION_USER 0
#define LOCATION_PRIVATE_LOCAL 1
const char *cause_name(int cause);

View File

@ -27,7 +27,7 @@
#include "sample.h"
#include "debug.h"
#include "display.h"
#include "call.h"
#include "mncc_console.h"
const char *debug_level[] = {
"debug ",
@ -51,7 +51,7 @@ struct debug_cat {
{ "amps", "\033[1;34m" },
{ "r2000", "\033[1;34m" },
{ "frame", "\033[0;36m" },
{ "call", "\033[1;37m" },
{ "call", "\033[0;37m" },
{ "mncc", "\033[1;32m" },
{ "database", "\033[0;33m" },
{ "transaction", "\033[0;32m" },

View File

@ -35,6 +35,7 @@
#include "sender.h"
#include "timer.h"
#include "call.h"
#include "mncc_console.h"
#include "mncc_sock.h"
#ifdef HAVE_SDR
#include "sdr.h"
@ -425,6 +426,20 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void),
/* latency of send buffer in samples */
latspl = samplerate * latency / 1000;
/* check MNCC support */
if (use_mncc_sock && call_audiodev[0]) {
fprintf(stderr, "You selected MNCC interface, but it cannot be used with call device (headset).\n");
return;
}
if (use_mncc_sock && echo_test) {
fprintf(stderr, "You selected MNCC interface, but it cannot be used with echo test.\n");
return;
}
if (echo_test && call_audiodev[0]) {
fprintf(stderr, "You selected call device (headset), but it cannot be used with echo test.\n");
return;
}
/* init mncc */
if (use_mncc_sock) {
char mncc_sock_name[64];
@ -433,15 +448,17 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void),
mncc_sock_name[sizeof(mncc_sock_name) - 1] = '\0';
} else
strcpy(mncc_sock_name, "/tmp/bsc_mncc");
rc = mncc_init(mncc_sock_name);
rc = mncc_sock_init(mncc_sock_name);
if (rc < 0) {
fprintf(stderr, "Failed to setup MNCC socket. Quitting!\n");
return;
}
} else {
console_init(station_id, call_audiodev, call_samplerate, latency, station_id_digits, loopback, echo_test);
}
/* init call device */
rc = call_init(station_id, call_audiodev, call_samplerate, latency, station_id_digits, loopback, use_mncc_sock, send_patterns, release_on_disconnect, echo_test);
/* init call control instance */
rc = call_init((use_mncc_sock) ? send_patterns : 0, release_on_disconnect);
if (rc < 0) {
fprintf(stderr, "Failed to create call control instance. Quitting!\n");
return;
@ -456,7 +473,7 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void),
/* open audio */
if (sender_open_audio(latspl))
return;
if (call_open_audio(latspl))
if (console_open_audio(latspl))
return;
/* real time priority */
@ -488,7 +505,7 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void),
/* start streaming */
if (sender_start_audio())
*quit = 1;
if (call_start_audio())
if (console_start_audio())
*quit = 1;
while(!(*quit)) {
@ -512,7 +529,7 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void),
if (now - last_time_call >= 0.020) {
last_time_call += 0.020;
/* call clock every 20ms */
call_mncc_clock();
call_clock();
}
next_char:
@ -578,8 +595,11 @@ next_char:
goto next_char;
}
/* process audio of built-in call control */
process_call(c);
/* process call control */
if (use_mncc_sock)
mncc_sock_handle();
else
process_console(c);
if (myhandler)
myhandler();
@ -619,10 +639,11 @@ next_char:
}
/* cleanup call control */
call_cleanup();
if (!use_mncc_sock)
console_cleanup();
/* close mncc socket */
if (use_mncc_sock)
mncc_exit();
mncc_sock_exit();
}

473
src/common/mncc_console.c Normal file
View File

@ -0,0 +1,473 @@
/* built-in console to talk to a phone
*
* (C) 2017 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
G* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include "sample.h"
#include "samplerate.h"
#include "jitter.h"
#include "debug.h"
#include "testton.h"
#include "mncc.h"
#include "call.h"
#include "cause.h"
#include "mncc_console.h"
#include "sound.h"
static int new_callref = 0; /* toward mobile */
enum console_state {
CONSOLE_IDLE = 0, /* IDLE */
CONSOLE_SETUP_RO, /* call from radio to console */
CONSOLE_SETUP_RT, /* call from console to radio */
CONSOLE_ALERTING_RO, /* call from radio to console */
CONSOLE_ALERTING_RT, /* call from console to radio */
CONSOLE_CONNECT,
CONSOLE_DISCONNECT,
};
static const char *console_state_name[] = {
"IDLE",
"SETUP_RO",
"SETUP_RT",
"ALERTING_RO",
"ALERTING_RT",
"CONNECT",
"DISCONNECT",
};
/* console call instance */
typedef struct console {
uint32_t callref;
enum console_state state;
int disc_cause; /* cause that has been sent by transceiver instance for release */
char station_id[16];
char dialing[16];
char audiodev[64]; /* headphone interface, if used */
int samplerate; /* sample rate of headphone interface */
void *sound; /* headphone interface */
int latspl; /* sample latency at headphone interface */
samplerate_t srstate; /* patterns/announcement upsampling */
jitter_t dejitter; /* headphone audio dejittering */
int test_audio_pos; /* position for test tone toward mobile */
sample_t tx_buffer[160];/* transmit audio buffer */
int tx_buffer_pos; /* current position in transmit audio buffer */
int dial_digits; /* number of digits to be dialed */
int loopback; /* loopback test for echo */
int echo_test; /* send echo back to mobile phone */
} console_t;
static console_t console;
/* stream test music */
int16_t *test_spl = NULL;
int test_size = 0;
int test_max = 0;
static void get_test_patterns(int16_t *samples, int length)
{
const int16_t *spl;
int size, max, pos;
spl = test_spl;
size = test_size;
max = test_max;
/* stream sample */
pos = console.test_audio_pos;
while(length--) {
if (pos >= size)
*samples++ = 0;
else
*samples++ = spl[pos] >> 2;
if (++pos == max)
pos = 0;
}
console.test_audio_pos = pos;
}
static void console_new_state(enum console_state state)
{
PDEBUG(DMNCC, DEBUG_DEBUG, "Call state '%s' -> '%s'\n", console_state_name[console.state], console_state_name[state]);
console.state = state;
console.test_audio_pos = 0;
}
static int console_mncc_up(uint8_t *buf, int length)
{
struct gsm_mncc *mncc = (struct gsm_mncc *)buf;
if (mncc->msg_type == ANALOG_8000HZ) {
struct gsm_data_frame *data = (struct gsm_data_frame *)buf;
int count = 160;
sample_t samples[count];
/* save audio from transceiver to jitter buffer */
if (console.sound) {
sample_t up[(int)((double)count * console.srstate.factor + 0.5) + 10];
int16_to_samples(samples, (int16_t *)data->data, count);
count = samplerate_upsample(&console.srstate, samples, count, up);
jitter_save(&console.dejitter, up, count);
return 0;
}
/* if echo test is used, send echo back to mobile */
if (console.echo_test) {
/* send down reused MNCC */
mncc_down(buf, length);
return 0;
}
/* if no sound is used, send test tone to mobile */
if (console.state == CONSOLE_CONNECT) {
/* send down reused MNCC */
get_test_patterns((int16_t *)data->data, count);
mncc_down(buf, length);
return 0;
}
return 0;
}
if (mncc->msg_type != MNCC_SETUP_IND && console.callref != mncc->callref) {
PDEBUG(DMNCC, DEBUG_ERROR, "invalid call ref.\n");
/* send down reused MNCC */
mncc->msg_type = MNCC_REL_REQ;
mncc->fields |= MNCC_F_CAUSE;
mncc->cause.location = LOCATION_USER;
mncc->cause.value = CAUSE_INVALCALLREF;
mncc_down(buf, length);
return 0;
}
switch(mncc->msg_type) {
case MNCC_SETUP_IND:
PDEBUG(DMNCC, DEBUG_INFO, "Incoming call from '%s'\n", mncc->calling.number);
/* setup is also allowed on disconnected call */
if (console.state == CONSOLE_DISCONNECT)
console_new_state(CONSOLE_IDLE);
if (console.state != CONSOLE_IDLE) {
PDEBUG(DMNCC, DEBUG_NOTICE, "We are busy, rejecting.\n");
return -CAUSE_BUSY;
}
console.callref = mncc->callref;
if (mncc->calling.number[0]) {
strncpy(console.station_id, mncc->calling.number, console.dial_digits);
console.station_id[console.dial_digits] = '\0';
}
strncpy(console.dialing, mncc->called.number, sizeof(console.dialing) - 1);
console.dialing[sizeof(console.dialing) - 1] = '\0';
console_new_state(CONSOLE_CONNECT);
PDEBUG(DMNCC, DEBUG_INFO, "Call automatically answered\n");
/* send down reused MNCC */
mncc->msg_type = MNCC_SETUP_RSP;
mncc_down(buf, length);
break;
case MNCC_ALERT_IND:
PDEBUG(DMNCC, DEBUG_INFO, "Call alerting\n");
console_new_state(CONSOLE_ALERTING_RT);
break;
case MNCC_SETUP_CNF:
PDEBUG(DMNCC, DEBUG_INFO, "Call connected to '%s'\n", mncc->connected.number);
console_new_state(CONSOLE_CONNECT);
strncpy(console.station_id, mncc->connected.number, console.dial_digits);
console.station_id[console.dial_digits] = '\0';
/* send down reused MNCC */
mncc->msg_type = MNCC_SETUP_COMPL_REQ;
mncc_down(buf, length);
break;
case MNCC_DISC_IND:
PDEBUG(DMNCC, DEBUG_INFO, "Call disconnected (%s)\n", cause_name(mncc->cause.value));
console_new_state(CONSOLE_DISCONNECT);
console.disc_cause = mncc->cause.value;
break;
case MNCC_REL_IND:
PDEBUG(DMNCC, DEBUG_INFO, "Call released (%s)\n", cause_name(mncc->cause.value));
console_new_state(CONSOLE_IDLE);
console.callref = 0;
break;
}
return 0;
}
int console_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int echo_test)
{
int rc = 0;
init_testton();
memset(&console, 0, sizeof(console));
strncpy(console.station_id, station_id, sizeof(console.station_id) - 1);
strncpy(console.audiodev, audiodev, sizeof(console.audiodev) - 1);
console.samplerate = samplerate;
console.latspl = latency * samplerate / 1000;
console.dial_digits = dial_digits;
console.loopback = loopback;
console.echo_test = echo_test;
mncc_up = console_mncc_up;
if (!audiodev[0])
return 0;
rc = init_samplerate(&console.srstate, 8000.0, (double)samplerate, 3300.0);
if (rc < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to init sample rate conversion!\n");
goto error;
}
rc = jitter_create(&console.dejitter, samplerate / 5);
if (rc < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create and init dejitter buffer!\n");
goto error;
}
return 0;
error:
console_cleanup();
return rc;
}
int console_open_audio(int latspl)
{
if (!console.audiodev[0])
return 0;
/* open sound device for call control */
/* use factor 1.4 of speech level for complete range of sound card */
console.sound = sound_open(console.audiodev, NULL, NULL, 1, 0.0, console.samplerate, latspl, 1.4, 4000.0);
if (!console.sound) {
PDEBUG(DSENDER, DEBUG_ERROR, "No sound device!\n");
return -EIO;
}
return 0;
}
int console_start_audio(void)
{
if (!console.audiodev[0])
return 0;
return sound_start(console.sound);
}
void console_cleanup(void)
{
/* close sound devoice */
if (console.sound)
sound_close(console.sound);
jitter_destroy(&console.dejitter);
}
static char console_text[256];
static char console_clear[256];
static int console_len = 0;
static void process_ui(int c)
{
char text[256];
int len;
switch (console.state) {
case CONSOLE_IDLE:
if (c > 0) {
if (c >= '0' && c <= '9' && (int)strlen(console.station_id) < console.dial_digits) {
console.station_id[strlen(console.station_id) + 1] = '\0';
console.station_id[strlen(console.station_id)] = c;
}
if ((c == 8 || c == 127) && strlen(console.station_id))
console.station_id[strlen(console.station_id) - 1] = '\0';
dial_after_hangup:
if (c == 'd' && (int)strlen(console.station_id) == console.dial_digits) {
int callref = ++new_callref;
uint8_t buf[sizeof(struct gsm_mncc)];
struct gsm_mncc *mncc = (struct gsm_mncc *)buf;
PDEBUG(DMNCC, DEBUG_INFO, "Outgoing call to '%s'\n", console.station_id);
console.dialing[0] = '\0';
console_new_state(CONSOLE_SETUP_RT);
console.callref = callref;
memset(buf, 0, sizeof(buf));
mncc->msg_type = MNCC_SETUP_REQ;
mncc->callref = callref;
mncc->fields |= MNCC_F_CALLED;
strncpy(mncc->called.number, console.station_id, sizeof(mncc->called.number) - 1);
mncc->called.type = 0; /* dialing is of type 'unknown' */
mncc->lchan_type = GSM_LCHAN_TCH_F;
mncc->fields |= MNCC_F_BEARER_CAP;
mncc->bearer_cap.speech_ver[0] = BCAP_ANALOG_8000HZ;
mncc->bearer_cap.speech_ver[1] = -1;
mncc_down(buf, sizeof(struct gsm_mncc));
}
}
if (console.dial_digits != (int)strlen(console.station_id))
sprintf(text, "on-hook: %s%s (enter digits 0..9)\r", console.station_id, "..............." + 15 - console.dial_digits + strlen(console.station_id));
else
sprintf(text, "on-hook: %s (press d=dial)\r", console.station_id);
break;
case CONSOLE_SETUP_RO:
case CONSOLE_SETUP_RT:
case CONSOLE_ALERTING_RO:
case CONSOLE_ALERTING_RT:
case CONSOLE_CONNECT:
case CONSOLE_DISCONNECT:
if (c > 0) {
if (c == 'h' || (c == 'd' && console.state == CONSOLE_DISCONNECT)) {
PDEBUG(DMNCC, DEBUG_INFO, "Call hangup\n");
console_new_state(CONSOLE_IDLE);
if (console.callref) {
uint8_t buf[sizeof(struct gsm_mncc)];
struct gsm_mncc *mncc = (struct gsm_mncc *)buf;
memset(buf, 0, sizeof(buf));
mncc->msg_type = MNCC_REL_REQ;
mncc->callref = console.callref;
mncc->fields |= MNCC_F_CAUSE;
mncc->cause.location = LOCATION_USER;
mncc->cause.value = CAUSE_NORMAL;
mncc_down(buf, sizeof(struct gsm_mncc));
console.callref = 0;
}
if (c == 'd')
goto dial_after_hangup;
}
}
if (console.state == CONSOLE_SETUP_RT)
sprintf(text, "call setup: %s (press h=hangup)\r", console.station_id);
if (console.state == CONSOLE_ALERTING_RT)
sprintf(text, "call ringing: %s (press h=hangup)\r", console.station_id);
if (console.state == CONSOLE_CONNECT) {
if (console.dialing[0])
sprintf(text, "call active: %s->%s (press h=hangup)\r", console.station_id, console.dialing);
else
sprintf(text, "call active: %s (press h=hangup)\r", console.station_id);
}
if (console.state == CONSOLE_DISCONNECT)
sprintf(text, "call disconnected: %s (press h=hangup d=redial)\r", cause_name(console.disc_cause));
break;
}
/* skip if nothing has changed */
len = strlen(text);
if (console_len == len && !memcmp(console_text, text, len))
return;
clear_console_text();
console_len = len;
memcpy(console_text, text, len);
memset(console_clear, ' ', len - 1);
console_clear[len - 1] = '\r';
print_console_text();
fflush(stdout);
}
void clear_console_text(void)
{
if (!console_len)
return;
fwrite(console_clear, console_len, 1, stdout);
// note: fflused by user of this function
console_len = 0;
}
void print_console_text(void)
{
if (!console_len)
return;
printf("\033[1;37m");
fwrite(console_text, console_len, 1, stdout);
printf("\033[0;39m");
}
/* get keys from keyboad to control call via console
* returns 1 on exit (ctrl+c) */
void process_console(int c)
{
if (!console.loopback)
process_ui(c);
if (!console.sound)
return;
/* handle audio, if sound device is used */
sample_t samples[console.latspl + 10], *samples_list[1];
uint8_t *power_list[1];
double rf_level_db[1];
int count;
int rc;
count = sound_get_tosend(console.sound, console.latspl);
if (count < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to get samples in buffer (rc = %d)!\n", count);
if (count == -EPIPE)
PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover.\n");
return;
}
if (count > 0) {
jitter_load(&console.dejitter, samples, count);
samples_list[0] = samples;
power_list[0] = NULL;
rc = sound_write(console.sound, samples_list, power_list, count, NULL, NULL, 1);
if (rc < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to sound device (rc = %d)\n", rc);
if (rc == -EPIPE)
PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover.\n");
return;
}
}
samples_list[0] = samples;
count = sound_read(console.sound, samples_list, console.latspl, 1, rf_level_db);
if (count < 0) {
PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from sound device (rc = %d)!\n", count);
if (count == -EPIPE)
PDEBUG(DSENDER, DEBUG_ERROR, "Trying to recover.\n");
return;
}
if (count) {
int i;
if (console.loopback == 3)
jitter_save(&console.dejitter, samples, count);
count = samplerate_downsample(&console.srstate, samples, count);
/* put samples into ring buffer */
for (i = 0; i < count; i++) {
console.tx_buffer[console.tx_buffer_pos] = samples[i];
/* if ring buffer wrapps, deliver data down to call process */
if (++console.tx_buffer_pos == 160) {
console.tx_buffer_pos = 0;
/* only if we have a call */
if (console.callref) {
uint8_t buf[sizeof(struct gsm_data_frame) + 160 * sizeof(int16_t)];
struct gsm_data_frame *data = (struct gsm_data_frame *)buf;
data->msg_type = ANALOG_8000HZ;
data->callref = console.callref;
samples_to_int16((int16_t *)data->data, console.tx_buffer, 160);
mncc_down(buf, sizeof(struct gsm_mncc));
}
}
}
}
}

10
src/common/mncc_console.h Normal file
View File

@ -0,0 +1,10 @@
int console_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int echo_test);
void console_cleanup(void);
int console_open_audio(int latspl);
int console_start_audio(void);
void console_process(int c);
void clear_console_text(void);
void print_console_text(void);
void process_console(int c);

View File

@ -29,33 +29,34 @@
#include "sample.h"
#include "debug.h"
#include "call.h"
#include "cause.h"
#include "mncc_sock.h"
static int listen_sock = -1;
static int mncc_sock = -1;
/* write to mncc socket, return error or -EIO if no socket connection */
int mncc_write(uint8_t *buf, int length)
static int mncc_write(uint8_t *buf, int length)
{
int rc;
if (mncc_sock <= 0) {
PDEBUG(DMNCC, DEBUG_NOTICE, "MNCC not connected.\n");
return -EIO;
PDEBUG(DMNCC, DEBUG_NOTICE, "We have no MNCC connection, rejecting.\n");
return -CAUSE_TEMPFAIL;
}
rc = send(mncc_sock, buf, length, 0);
if (rc < 0) {
PDEBUG(DMNCC, DEBUG_ERROR, "MNCC connection failed (errno = %d).\n", errno);
mncc_sock_close();
return 0;
return -CAUSE_TEMPFAIL;
}
if (rc != length) {
PDEBUG(DMNCC, DEBUG_NOTICE, "MNCC write failed.\n");
mncc_sock_close();
return 0;
return -CAUSE_TEMPFAIL;
}
return rc;
return 0;
}
@ -80,7 +81,7 @@ static int mncc_read(void)
return -errno;
}
call_mncc_recv(buf, rc);
mncc_down(buf, rc);
return rc;
}
@ -141,7 +142,7 @@ static int mncc_accept(void)
return 1;
}
void mncc_handle(void)
void mncc_sock_handle(void)
{
mncc_accept();
@ -159,11 +160,11 @@ void mncc_sock_close(void)
close(mncc_sock);
mncc_sock = -1;
/* clear all call instances */
call_mncc_flush();
mncc_flush();
}
}
int mncc_init(const char *sock_name)
int mncc_sock_init(const char *sock_name)
{
struct sockaddr_un local;
unsigned int namelen;
@ -197,14 +198,14 @@ int mncc_init(const char *sock_name)
if (rc < 0) {
PDEBUG(DMNCC, DEBUG_ERROR, "Failed to bind the unix domain "
"socket. '%s'\n", local.sun_path);
mncc_exit();
mncc_sock_exit();
return rc;
}
rc = listen(listen_sock, 0);
if (rc < 0) {
PDEBUG(DMNCC, DEBUG_ERROR, "Failed to listen.\n");
mncc_exit();
mncc_sock_exit();
return rc;
}
@ -213,16 +214,18 @@ int mncc_init(const char *sock_name)
rc = fcntl(listen_sock, F_SETFL, flags | O_NONBLOCK);
if (rc < 0) {
PDEBUG(DMNCC, DEBUG_ERROR, "Failed to set socket into non-blocking IO mode.\n");
mncc_exit();
mncc_sock_exit();
return rc;
}
mncc_up = mncc_write;
PDEBUG(DMNCC, DEBUG_DEBUG, "MNCC socket at '%s' initialized, waiting for connection.\n", sock_name);
return 0;
}
void mncc_exit(void)
void mncc_sock_exit(void)
{
mncc_sock_close();

View File

@ -1,8 +1,7 @@
#include "mncc.h"
int mncc_write(uint8_t *buf, int length);
void mncc_handle(void);
void mncc_sock_handle(void);
void mncc_sock_close(void);
int mncc_init(const char *sock_name);
void mncc_exit(void);
int mncc_sock_init(const char *sock_name);
void mncc_sock_exit(void);

View File

@ -349,7 +349,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
for (i = 0; i < count; i++) {
spl[pos++] = samples[i];
if (pos == 160) {
call_tx_audio(nmt->trans->callref, spl, 160);
call_up_audio(nmt->trans->callref, spl, 160);
pos = 0;
}
}

View File

@ -881,7 +881,7 @@ static void rx_mo_dialing(nmt_t *nmt, frame_t *frame)
int callref = ++new_callref;
int rc;
PDEBUG(DNMT, DEBUG_INFO, "Setup call to network.\n");
rc = call_in_setup(callref, &trans->subscriber.country, nmt->dialing);
rc = call_up_setup(callref, &trans->subscriber.country, nmt->dialing);
if (rc < 0) {
PDEBUG(DNMT, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", rc);
nmt_release(nmt);
@ -971,7 +971,7 @@ void timeout_mt_paging(transaction_t *trans)
PDEBUG(DNMT, DEBUG_NOTICE, "No answer from mobile phone (try %d).\n", trans->page_try);
if (trans->page_try == PAGE_TRIES) {
PDEBUG(DNMT, DEBUG_INFO, "Release call towards network.\n");
call_in_release(trans->callref, CAUSE_OUTOFORDER);
call_up_release(trans->callref, CAUSE_OUTOFORDER);
destroy_transaction(trans);
return;
}
@ -1036,7 +1036,7 @@ static void tx_mt_ident(nmt_t *nmt, frame_t *frame)
if (nmt->tx_frame_count == 8) {
PDEBUG_CHAN(DNMT, DEBUG_NOTICE, "Timeout waiting for identity reply\n");
PDEBUG_CHAN(DNMT, DEBUG_INFO, "Release call towards network.\n");
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
destroy_transaction(trans);
}
}
@ -1066,7 +1066,7 @@ static void rx_mt_ident(nmt_t *nmt, frame_t *frame)
nmt->tx_callerid_count = 0;
}
timer_start(&nmt->timer, RINGING_TO);
call_in_alerting(trans->callref);
call_up_alerting(trans->callref);
}
break;
default:
@ -1092,7 +1092,7 @@ static void tx_mt_autoanswer(nmt_t *nmt, frame_t *frame)
nmt->tx_frame_count = 0;
nmt->tx_callerid_count = 0;
timer_start(&nmt->timer, RINGING_TO);
call_in_alerting(trans->callref);
call_up_alerting(trans->callref);
}
}
@ -1121,7 +1121,7 @@ static void rx_mt_autoanswer(nmt_t *nmt, frame_t *frame)
PDEBUG_CHAN(DNMT, DEBUG_INFO, "Received acknowledge to autoanswer.\n");
nmt_new_state(nmt, STATE_MT_COMPLETE);
nmt->tx_frame_count = 0;
call_in_answer(trans->callref, &trans->subscriber.country);
call_up_answer(trans->callref, &trans->subscriber.country);
break;
default:
PDEBUG_CHAN(DNMT, DEBUG_DEBUG, "Dropping message %s in state %s\n", nmt_frame_name(frame->mt), nmt_state_name(nmt->state));
@ -1180,7 +1180,7 @@ static void rx_mt_ringing(nmt_t *nmt, frame_t *frame)
nmt_new_state(nmt, STATE_MT_COMPLETE);
nmt->tx_frame_count = 0;
timer_stop(&nmt->timer);
call_in_answer(trans->callref, &trans->subscriber.country);
call_up_answer(trans->callref, &trans->subscriber.country);
break;
default:
PDEBUG_CHAN(DNMT, DEBUG_DEBUG, "Dropping message %s in state %s\n", nmt_frame_name(frame->mt), nmt_state_name(nmt->state));
@ -1220,7 +1220,7 @@ static void timeout_mt_ringing(nmt_t *nmt)
PDEBUG_CHAN(DNMT, DEBUG_NOTICE, "Timeout while waiting for answer of the phone.\n");
PDEBUG(DNMT, DEBUG_INFO, "Release call towards network.\n");
call_in_release(trans->callref, CAUSE_NOANSWER);
call_up_release(trans->callref, CAUSE_NOANSWER);
trans->callref = 0;
nmt_release(nmt);
}
@ -1320,7 +1320,7 @@ static void timeout_active(nmt_t *nmt, double duration)
else
PDEBUG_CHAN(DNMT, DEBUG_NOTICE, "Timeout after %.0f seconds loosing supervisory signal.\n", duration);
PDEBUG_CHAN(DNMT, DEBUG_INFO, "Release call towards network.\n");
call_in_release(trans->callref, CAUSE_TEMPFAIL);
call_up_release(trans->callref, CAUSE_TEMPFAIL);
trans->callref = 0;
nmt_release(nmt);
}
@ -1497,7 +1497,7 @@ void nmt_receive_frame(nmt_t *nmt, const char *bits, double quality, double leve
nmt_set_dsp_mode(nmt, DSP_MODE_FRAME);
if (nmt->trans->callref) {
PDEBUG(DNMT, DEBUG_INFO, "Release call towards network.\n");
call_in_release(nmt->trans->callref, CAUSE_NORMAL);
call_up_release(nmt->trans->callref, CAUSE_NORMAL);
nmt->trans->callref = 0;
}
return;
@ -1719,7 +1719,7 @@ inval:
return 0;
}
int call_out_setup(int callref, const char *caller_id, enum number_type caller_type, const char *dialing)
int call_down_setup(int callref, const char *caller_id, enum number_type caller_type, const char *dialing)
{
return _out_setup(callref, caller_id, caller_type, dialing, NULL);
}
@ -1728,7 +1728,7 @@ int sms_out_setup(char *dialing, const char *caller_id, enum number_type caller_
return _out_setup(0, caller_id, caller_type, dialing, sms);
}
void call_out_answer(int __attribute__((unused)) callref)
void call_down_answer(int __attribute__((unused)) callref)
{
}
@ -1736,7 +1736,7 @@ void call_out_answer(int __attribute__((unused)) callref)
* An active call stays active, so tones and annoucements can be received
* by mobile station.
*/
void call_out_disconnect(int callref, int cause)
void call_down_disconnect(int callref, int cause)
{
transaction_t *trans;
nmt_t *nmt;
@ -1746,13 +1746,13 @@ void call_out_disconnect(int callref, int cause)
trans = get_transaction_by_callref(callref);
if (!trans) {
PDEBUG(DNMT, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
nmt = trans->nmt;
if (!nmt) {
call_in_release(callref, cause);
call_up_release(callref, cause);
trans->callref = 0;
destroy_transaction(trans);
return;
@ -1774,11 +1774,11 @@ void call_out_disconnect(int callref, int cause)
break;
}
call_in_release(callref, cause);
call_up_release(callref, cause);
}
/* Call control releases call toward mobile station. */
void call_out_release(int callref, int __attribute__((unused)) cause)
void call_down_release(int callref, int __attribute__((unused)) cause)
{
transaction_t *trans;
nmt_t *nmt;
@ -1817,7 +1817,7 @@ void call_out_release(int callref, int __attribute__((unused)) cause)
}
/* Receive audio from call instance. */
void call_rx_audio(int callref, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
transaction_t *trans;
nmt_t *nmt;

View File

@ -282,7 +282,7 @@ void sender_receive(sender_t *sender, sample_t *samples, int length, double __at
for (i = 0; i < count; i++) {
spl[pos++] = samples[i];
if (pos == 160) {
call_tx_audio(r2000->callref, spl, 160);
call_up_audio(r2000->callref, spl, 160);
pos = 0;
}
}

View File

@ -557,7 +557,7 @@ void r2000_go_idle(r2000_t *r2000)
if (r2000->callref) {
PDEBUG(DR2000, DEBUG_ERROR, "Going idle, but still having callref, please fix!\n");
call_in_release(r2000->callref, CAUSE_NORMAL);
call_up_release(r2000->callref, CAUSE_NORMAL);
r2000->callref = 0;
}
@ -635,7 +635,7 @@ static r2000_t *move_call_to_chan(r2000_t *old_r2000, enum r2000_chan_type chan_
PDEBUG(DR2000, DEBUG_NOTICE, "Cannot move us to %s, because there is no free channel!\n", chan_type_long_name(chan_type));
if (old_r2000->callref) {
PDEBUG(DR2000, DEBUG_NOTICE, "Failed to assign channel, releasing towards network\n");
call_in_release(old_r2000->callref, CAUSE_NOCHANNEL);
call_up_release(old_r2000->callref, CAUSE_NOCHANNEL);
old_r2000->callref = 0;
}
r2000_release(old_r2000);
@ -835,7 +835,7 @@ static void rx_ident(r2000_t *r2000, frame_t *frame)
/* alert the phone */
r2000_new_state(r2000, STATE_IN_ALERT);
timer_start(&r2000->timer, ALERT_TIME);
call_in_alerting(r2000->callref);
call_up_alerting(r2000->callref);
break;
case STATE_RECALL_IDENT:
/* alert the phone */
@ -884,7 +884,7 @@ static void timeout_in_ident(r2000_t *r2000)
/* ... or release */
PDEBUG_CHAN(DR2000, DEBUG_NOTICE, "Phone does not response, releasing towards network\n");
call_in_release(r2000->callref, CAUSE_OUTOFORDER);
call_up_release(r2000->callref, CAUSE_OUTOFORDER);
r2000->callref = 0;
r2000_release(r2000);
}
@ -920,7 +920,7 @@ static int setup_call(r2000_t *r2000)
/* make call toward network */
PDEBUG(DR2000, DEBUG_INFO, "Setup call to network.\n");
rc = call_in_setup(callref, subscriber2string(&r2000->subscriber), r2000->subscriber.dialing);
rc = call_up_setup(callref, subscriber2string(&r2000->subscriber), r2000->subscriber.dialing);
if (rc < 0) {
PDEBUG(DR2000, DEBUG_NOTICE, "Call rejected (cause %d), releasing.\n", -rc);
r2000_release(r2000);
@ -952,7 +952,7 @@ static void rx_alert(r2000_t *r2000, frame_t *frame)
case STATE_IN_ALERT:
/* answer incomming call */
PDEBUG(DR2000, DEBUG_INFO, "Answer call to network.\n");
call_in_answer(r2000->callref, subscriber2string(&r2000->subscriber));
call_up_answer(r2000->callref, subscriber2string(&r2000->subscriber));
break;
case STATE_OUT_ALERT:
/* setup call, possible r2000_release() is called there! */
@ -983,7 +983,7 @@ static void timeout_alert(r2000_t *r2000)
PDEBUG_CHAN(DR2000, DEBUG_NOTICE, "Phone does not response, releasing towards network\n");
if (r2000->callref) {
call_in_release(r2000->callref, CAUSE_NOANSWER);
call_up_release(r2000->callref, CAUSE_NOANSWER);
r2000->callref = 0;
}
r2000_release(r2000);
@ -1150,7 +1150,7 @@ static void timeout_active(r2000_t *r2000)
{
PDEBUG_CHAN(DR2000, DEBUG_INFO, "Timeout after loosing supervisory signal, releasing call\n");
call_in_release(r2000->callref, CAUSE_TEMPFAIL);
call_up_release(r2000->callref, CAUSE_TEMPFAIL);
r2000->callref = 0;
r2000_release(r2000);
}
@ -1309,7 +1309,7 @@ void r2000_receive_frame(r2000_t *r2000, const char *bits, double quality, doubl
PDEBUG_CHAN(DR2000, DEBUG_INFO, "Received release from station mobile\n");
if (r2000->callref) {
call_in_release(r2000->callref, CAUSE_NORMAL);
call_up_release(r2000->callref, CAUSE_NORMAL);
r2000->callref = 0;
}
r2000_go_idle(r2000);
@ -1425,7 +1425,7 @@ static void r2000_timeout(struct timer *timer)
*/
/* Call control starts call towards station mobile. */
int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
int call_down_setup(int callref, const char __attribute__((unused)) *caller_id, enum number_type __attribute__((unused)) caller_type, const char *dialing)
{
sender_t *sender;
r2000_t *r2000, *tc;
@ -1475,7 +1475,7 @@ int call_out_setup(int callref, const char __attribute__((unused)) *caller_id, e
}
/* Call control answers call toward station mobile. */
void call_out_answer(int callref)
void call_down_answer(int callref)
{
sender_t *sender;
r2000_t *r2000;
@ -1487,7 +1487,7 @@ void call_out_answer(int callref)
}
if (!sender) {
PDEBUG(DR2000, DEBUG_NOTICE, "Outgoing answer, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@ -1506,7 +1506,7 @@ void call_out_answer(int callref)
* An active call stays active, so tones and annoucements can be received
* by station mobile.
*/
void call_out_disconnect(int callref, int __attribute__((unused)) cause)
void call_down_disconnect(int callref, int __attribute__((unused)) cause)
{
sender_t *sender;
r2000_t *r2000;
@ -1520,7 +1520,7 @@ void call_out_disconnect(int callref, int __attribute__((unused)) cause)
}
if (!sender) {
PDEBUG(DR2000, DEBUG_NOTICE, "Outgoing disconnect, but no callref!\n");
call_in_release(callref, CAUSE_INVALCALLREF);
call_up_release(callref, CAUSE_INVALCALLREF);
return;
}
@ -1535,11 +1535,11 @@ void call_out_disconnect(int callref, int __attribute__((unused)) cause)
break;
}
call_in_release(callref, cause);
call_up_release(callref, cause);
}
/* Call control releases call toward station mobile. */
void call_out_release(int callref, int __attribute__((unused)) cause)
void call_down_release(int callref, int __attribute__((unused)) cause)
{
sender_t *sender;
r2000_t *r2000;
@ -1572,7 +1572,7 @@ void call_out_release(int callref, int __attribute__((unused)) cause)
}
/* Receive audio from call instance. */
void call_rx_audio(int callref, sample_t *samples, int count)
void call_down_audio(int callref, sample_t *samples, int count)
{
sender_t *sender;
r2000_t *r2000;

View File

@ -1,8 +1,8 @@
void call_rx_audio() { }
void call_out_setup() { }
void call_out_release() { }
void call_out_disconnect() { }
void call_out_answer() { }
void call_down_audio() { }
void call_down_setup() { }
void call_down_release() { }
void call_down_disconnect() { }
void call_down_answer() { }
void print_help() { }
void sender_send() { }
void sender_receive() { }