AMPS: Caller ID Support
Support for sending caller ID for newer phones. Currently does not work with older phones, they will abort.
This commit is contained in:
143
src/amps/amps.c
143
src/amps/amps.c
@@ -61,7 +61,9 @@
|
||||
#define PAGE_TRIES 2 /* how many times to page the phone */
|
||||
#define PAGE_TO1 8.0 /* max time to wait for paging reply */
|
||||
#define PAGE_TO2 4.0 /* max time to wait for last paging reply */
|
||||
#define ALERT_TO 60.0 /* max time to wait for answer */
|
||||
#define ALERT_TRIES 3 /* how many times to alert the phone */
|
||||
#define ALERT_TO 0.3 /* max time to wait for alert confirm */
|
||||
#define ANSWER_TO 60.0 /* max time to wait for answer */
|
||||
#define RELEASE_TIMER 5.0 /* max time to send release messages */
|
||||
|
||||
/* Convert channel number to frequency number of base station.
|
||||
@@ -502,7 +504,7 @@ static amps_t *search_pc(void)
|
||||
}
|
||||
|
||||
/* Create transceiver instance and link to a list. */
|
||||
int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, 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, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int tolerant, int loopback)
|
||||
int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *device, int use_sdr, int samplerate, double rx_gain, double tx_gain, 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, amps_si *si, uint16_t sid, uint8_t sat, int polarity, int send_callerid, int tolerant, int loopback)
|
||||
{
|
||||
sender_t *sender;
|
||||
amps_t *amps;
|
||||
@@ -582,12 +584,12 @@ int amps_create(const char *kanal, enum amps_chan_type chan_type, const char *de
|
||||
amps->chan_type = chan_type;
|
||||
memcpy(&s->si, si, sizeof(amps->si));
|
||||
amps->sat = sat;
|
||||
|
||||
amps->send_callerid = send_callerid;
|
||||
if (polarity < 0)
|
||||
amps->flip_polarity = 1;
|
||||
|
||||
amps->pre_emphasis = pre_emphasis;
|
||||
amps->de_emphasis = de_emphasis;
|
||||
|
||||
/* the AMPS uses a frequency rage of 300..3000 Hz, but we still use the default low pass filter, which is not too far above */
|
||||
rc = init_emphasis(&s->estate, samplerate, CUT_OFF_EMPHASIS_DEFAULT, CUT_OFF_HIGHPASS_DEFAULT, CUT_OFF_LOWPASS_DEFAULT);
|
||||
if (rc < 0)
|
||||
@@ -688,14 +690,13 @@ static void amps_release(transaction_t *trans, uint8_t cause)
|
||||
trans->callref = 0;
|
||||
}
|
||||
/* change DSP mode to transmit release */
|
||||
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX || amps->dsp_mode == DSP_MODE_OFF)
|
||||
if (amps->dsp_mode == DSP_MODE_AUDIO_RX_AUDIO_TX || amps->dsp_mode == DSP_MODE_AUDIO_RX_SILENCE_TX || amps->dsp_mode == DSP_MODE_OFF)
|
||||
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* receive signaling
|
||||
*/
|
||||
|
||||
void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
|
||||
{
|
||||
transaction_t *trans = amps->trans_list;
|
||||
@@ -710,6 +711,7 @@ void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Lost Signaling Tone signal\n");
|
||||
|
||||
switch (trans->state) {
|
||||
case TRANS_CALL_MO_ASSIGN_CONFIRM: // should not happen
|
||||
case TRANS_CALL:
|
||||
if (!tone)
|
||||
break;
|
||||
@@ -723,16 +725,19 @@ void amps_rx_signaling_tone(amps_t *amps, int tone, double quality)
|
||||
destroy_transaction(trans);
|
||||
amps_go_idle(amps);
|
||||
break;
|
||||
case TRANS_CALL_MT_ALERT:
|
||||
case TRANS_CALL_MT_ASSIGN_CONFIRM: // should not happen
|
||||
case TRANS_CALL_MT_ALERT: // should not happen
|
||||
case TRANS_CALL_MT_ALERT_SEND: // should not happen
|
||||
case TRANS_CALL_MT_ALERT_CONFIRM:
|
||||
if (tone) {
|
||||
timer_stop(&trans->timer);
|
||||
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);
|
||||
trans_new_state(trans, TRANS_CALL_MT_ANSWER_WAIT);
|
||||
timer_start(&trans->timer, ANSWER_TO);
|
||||
}
|
||||
break;
|
||||
case TRANS_CALL_MT_ALERT_SEND:
|
||||
case TRANS_CALL_MT_ANSWER_WAIT:
|
||||
if (!tone) {
|
||||
timer_stop(&trans->timer);
|
||||
if (!trans->sat_detected)
|
||||
@@ -753,13 +758,20 @@ void amps_rx_sat(amps_t *amps, int tone, double quality)
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_ERROR, "SAT signal without transaction, please fix!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* irgnoring SAT loss on release */
|
||||
if (trans->state == TRANS_CALL_RELEASE
|
||||
|| trans->state == TRANS_CALL_RELEASE_SEND)
|
||||
return;
|
||||
if (trans->state != TRANS_CALL
|
||||
|
||||
/* only SAT with these states */
|
||||
if (trans->state != TRANS_CALL_MO_ASSIGN_CONFIRM
|
||||
&& trans->state != TRANS_CALL_MT_ASSIGN_CONFIRM
|
||||
&& trans->state != TRANS_CALL_MT_ALERT
|
||||
&& trans->state != TRANS_CALL_MT_ALERT_SEND) {
|
||||
&& trans->state != TRANS_CALL_MT_ALERT_SEND
|
||||
&& trans->state != TRANS_CALL_MT_ALERT_CONFIRM
|
||||
&& trans->state != TRANS_CALL_MT_ANSWER_WAIT
|
||||
&& trans->state != TRANS_CALL) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_ERROR, "SAT signal without active call, please fix!\n");
|
||||
return;
|
||||
}
|
||||
@@ -772,9 +784,26 @@ void amps_rx_sat(amps_t *amps, int tone, double quality)
|
||||
trans->sat_detected = 0;
|
||||
}
|
||||
|
||||
/* no SAT during alerting */
|
||||
/* initial SAT received */
|
||||
if (tone && trans->state == TRANS_CALL_MO_ASSIGN_CONFIRM) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Confirm from mobile (SAT) received\n");
|
||||
timer_stop(&trans->timer);
|
||||
trans_new_state(trans, TRANS_CALL);
|
||||
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_AUDIO_TX, 0);
|
||||
}
|
||||
if (tone && trans->state == TRANS_CALL_MT_ASSIGN_CONFIRM) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Confirm from mobile (SAT) received\n");
|
||||
timer_stop(&trans->timer);
|
||||
trans->alert_retry = 1;
|
||||
trans_new_state(trans, TRANS_CALL_MT_ALERT);
|
||||
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
|
||||
}
|
||||
|
||||
/* no SAT timeout handling during alerting */
|
||||
if (trans->state == TRANS_CALL_MT_ALERT
|
||||
|| trans->state == TRANS_CALL_MT_ALERT_SEND)
|
||||
|| trans->state == TRANS_CALL_MT_ALERT_SEND
|
||||
|| trans->state == TRANS_CALL_MT_ALERT_CONFIRM
|
||||
|| trans->state == TRANS_CALL_MT_ANSWER_WAIT)
|
||||
return;
|
||||
|
||||
if (tone) {
|
||||
@@ -790,20 +819,6 @@ void amps_rx_sat(amps_t *amps, int tone, double quality)
|
||||
return;
|
||||
}
|
||||
|
||||
static void timeout_sat(amps_t *amps, double duration)
|
||||
{
|
||||
if (!amps->trans_list) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_ERROR, "SAT timeout, but no transaction, please fix!\n");
|
||||
return;
|
||||
}
|
||||
if (duration == SAT_TO1)
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds not receiving SAT signal.\n", duration);
|
||||
else
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds loosing SAT signal.\n", duration);
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call towards network.\n");
|
||||
amps_release(amps->trans_list, CAUSE_TEMPFAIL);
|
||||
}
|
||||
|
||||
/* receive message from phone on RECC */
|
||||
void amps_rx_recc(amps_t *amps, uint8_t scm, uint8_t mpci, uint32_t esn, uint32_t min1, uint16_t min2, uint8_t msg_type, uint8_t ordq, uint8_t order, const char *dialing)
|
||||
{
|
||||
@@ -950,6 +965,11 @@ int call_down_setup(int callref, const char __attribute__((unused)) *caller_id,
|
||||
}
|
||||
trans->callref = callref;
|
||||
trans->page_retry = 1;
|
||||
if (caller_type == TYPE_INTERNATIONAL) {
|
||||
trans->caller_id[0] = '+';
|
||||
strncpy(trans->caller_id + 1, caller_id, sizeof(trans->caller_id) - 2);
|
||||
} else
|
||||
strncpy(trans->caller_id, caller_id, sizeof(trans->caller_id) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -988,8 +1008,11 @@ void call_down_disconnect(int callref, int cause)
|
||||
switch (amps->dsp_mode) {
|
||||
case DSP_MODE_AUDIO_RX_AUDIO_TX:
|
||||
case DSP_MODE_AUDIO_RX_FRAME_TX:
|
||||
if (trans->state == TRANS_CALL_MT_ALERT
|
||||
|| trans->state == TRANS_CALL_MT_ALERT_SEND) {
|
||||
if (trans->state == TRANS_CALL_MT_ASSIGN_CONFIRM
|
||||
|| trans->state == TRANS_CALL_MT_ALERT
|
||||
|| trans->state == TRANS_CALL_MT_ALERT_SEND
|
||||
|| trans->state == TRANS_CALL_MT_ALERT_CONFIRM
|
||||
|| trans->state == TRANS_CALL_MT_ANSWER_WAIT) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call control disconnect on voice channel while alerting, releasing towards mobile station.\n");
|
||||
amps_release(trans, cause);
|
||||
}
|
||||
@@ -1028,6 +1051,7 @@ void call_down_release(int callref, int cause)
|
||||
trans->callref = 0;
|
||||
|
||||
switch (amps->dsp_mode) {
|
||||
case DSP_MODE_AUDIO_RX_SILENCE_TX:
|
||||
case DSP_MODE_AUDIO_RX_AUDIO_TX:
|
||||
case DSP_MODE_AUDIO_RX_FRAME_TX:
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Call control releases on voice channel, releasing towards mobile station.\n");
|
||||
@@ -1071,8 +1095,16 @@ void transaction_timeout(struct timer *timer)
|
||||
amps_t *amps = trans->amps;
|
||||
|
||||
switch (trans->state) {
|
||||
case TRANS_CALL_MO_ASSIGN_CONFIRM:
|
||||
case TRANS_CALL_MT_ASSIGN_CONFIRM:
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds not receiving initial SAT signal.\n", timer->duration);
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call towards network.\n");
|
||||
amps_release(amps->trans_list, CAUSE_TEMPFAIL);
|
||||
break;
|
||||
case TRANS_CALL:
|
||||
timeout_sat(amps, timer->duration);
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Timeout after %.0f seconds loosing SAT signal.\n", timer->duration);
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call towards network.\n");
|
||||
amps_release(amps->trans_list, CAUSE_TEMPFAIL);
|
||||
break;
|
||||
case TRANS_CALL_RELEASE:
|
||||
case TRANS_CALL_RELEASE_SEND:
|
||||
@@ -1080,10 +1112,18 @@ void transaction_timeout(struct timer *timer)
|
||||
destroy_transaction(trans);
|
||||
amps_go_idle(amps);
|
||||
break;
|
||||
case TRANS_CALL_MT_ALERT:
|
||||
amps_release(trans, CAUSE_TEMPFAIL);
|
||||
break;
|
||||
case TRANS_CALL_MT_ALERT_SEND:
|
||||
case TRANS_CALL_MT_ALERT_CONFIRM:
|
||||
if (trans->alert_retry++ == ALERT_TRIES) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Phone does not respond to alert order, destroying transaction\n");
|
||||
amps_release(trans, CAUSE_TEMPFAIL);
|
||||
} else {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Phone does not respond to alert order, retrying\n");
|
||||
trans_new_state(trans, TRANS_CALL_MT_ALERT);
|
||||
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
|
||||
}
|
||||
break;
|
||||
case TRANS_CALL_MT_ANSWER_WAIT:
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_NOTICE, "Alerting timeout, destroying transaction\n");
|
||||
amps_release(trans, CAUSE_NOANSWER);
|
||||
break;
|
||||
@@ -1173,8 +1213,9 @@ again:
|
||||
vc = assign_voice_channel(trans);
|
||||
if (vc) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Assignment complete, voice connected\n");
|
||||
trans_new_state(trans, TRANS_CALL);
|
||||
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_AUDIO_TX, 0);
|
||||
/* timer and other things are processed at assign_voice_channel() */
|
||||
trans_new_state(trans, TRANS_CALL_MO_ASSIGN_CONFIRM);
|
||||
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_SILENCE_TX, 0);
|
||||
}
|
||||
return NULL;
|
||||
case TRANS_CALL_MT_ASSIGN:
|
||||
@@ -1184,13 +1225,10 @@ again:
|
||||
case TRANS_CALL_MT_ASSIGN_SEND:
|
||||
vc = assign_voice_channel(trans);
|
||||
if (vc) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Assignment complete, next: sending alerting on VC\n");
|
||||
trans->chan = 0;
|
||||
trans->msg_type = 0;
|
||||
trans->ordq = 0;
|
||||
trans->order = 1;
|
||||
trans_new_state(trans, TRANS_CALL_MT_ALERT);
|
||||
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_FRAME_TX, 0);
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Assignment complete, waiting for SAT on VC\n");
|
||||
/* timer and other things are processed at assign_voice_channel() */
|
||||
trans_new_state(trans, TRANS_CALL_MT_ASSIGN_CONFIRM);
|
||||
amps_set_dsp_mode(vc, DSP_MODE_AUDIO_RX_SILENCE_TX, 0);
|
||||
}
|
||||
return NULL;
|
||||
case TRANS_PAGE:
|
||||
@@ -1223,8 +1261,25 @@ transaction_t *amps_tx_frame_fvc(amps_t *amps)
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Release call was sent, continue sending release\n");
|
||||
return trans;
|
||||
case TRANS_CALL_MT_ALERT:
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Sending alerting\n");
|
||||
trans->chan = 0;
|
||||
trans->msg_type = 0;
|
||||
trans->ordq = 0;
|
||||
// "Alert with caller ID" causes older phones to interrupt the connection for some reason, therefore we don't use order 17 when no caller ID is set
|
||||
if (amps->send_callerid && trans->alert_retry == 1 && !trans->caller_id) {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Sending alerting with caller ID\n");
|
||||
trans->order = 17;
|
||||
} else {
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Sending alerting\n");
|
||||
trans->order = 1;
|
||||
}
|
||||
trans_new_state(trans, TRANS_CALL_MT_ALERT_SEND);
|
||||
return trans;
|
||||
case TRANS_CALL_MT_ALERT_SEND:
|
||||
PDEBUG_CHAN(DAMPS, DEBUG_INFO, "Alerting was sent, continue waiting for ST or timeout\n");
|
||||
timer_start(&trans->timer, ALERT_TO);
|
||||
amps_set_dsp_mode(amps, DSP_MODE_AUDIO_RX_SILENCE_TX, 0);
|
||||
trans_new_state(trans, TRANS_CALL_MT_ALERT_CONFIRM);
|
||||
return NULL;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user