From ba8bf0e9d535f1c9a4848a243ac1d5c700fbb3e6 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Wed, 20 Jul 2016 11:55:03 +0200 Subject: [PATCH] NMT: Fix autoanswer If phone does not support autoanswer, the MTX proceeds with regular ringing. --- src/nmt/nmt.c | 74 ++++++++++++++++++++++++++++++++++++++++++++------- src/nmt/nmt.h | 2 ++ 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/nmt/nmt.c b/src/nmt/nmt.c index 295ffed..15200b0 100644 --- a/src/nmt/nmt.c +++ b/src/nmt/nmt.c @@ -75,6 +75,8 @@ const char *nmt_state_name(enum nmt_state state) return "MT CALL CHANNEL"; case STATE_MT_IDENT: return "MT CALL IDENT"; + case STATE_MT_AUTOANSWER: + return "MT CALL AUTOANSWER"; case STATE_MT_RINGING: return "MT CALL RINGING"; case STATE_MT_COMPLETE: @@ -810,7 +812,7 @@ static void tx_mo_complete(nmt_t *nmt, frame_t *frame) if (++nmt->tx_frame_count <= 4) { set_line_signal(nmt, frame, 6); if (nmt->tx_frame_count == 1) - PDEBUG(DNMT, DEBUG_INFO, "Send 'addess complete'.\n"); + PDEBUG(DNMT, DEBUG_INFO, "Send 'address complete'.\n"); } else { if (nmt->compandor) { set_line_signal(nmt, frame, 5); @@ -937,11 +939,19 @@ static void rx_mt_ident(nmt_t *nmt, frame_t *frame) nmt_value2digits(frame->ms_password, nmt->subscriber.password, 3); PDEBUG(DNMT, DEBUG_INFO, "Received identity (password %s).\n", nmt->subscriber.password); if (nmt->dms_call) { - nmt_new_state(nmt, STATE_MT_COMPLETE); + nmt_new_state(nmt, STATE_MT_AUTOANSWER); + nmt->wait_autoanswer = 1; nmt->tx_frame_count = 0; } else { nmt_new_state(nmt, STATE_MT_RINGING); - nmt->tx_frame_count = 0; + /* start with caller ID before ringing */ + if (nmt->send_callerid) { + nmt->tx_frame_count = 4; + nmt->tx_callerid_count = 1; + } else { + nmt->tx_frame_count = 0; + nmt->tx_callerid_count = 0; + } timer_start(&nmt->timer, RINGING_TO); call_in_alerting(nmt->sender.callref); } @@ -951,6 +961,49 @@ static void rx_mt_ident(nmt_t *nmt, frame_t *frame) } } +static void tx_mt_autoanswer(nmt_t *nmt, frame_t *frame) +{ + /* first we need to wait for autoanswer */ + if (nmt->wait_autoanswer) { + frame->index = NMT_MESSAGE_6; + return; + } + if (++nmt->tx_frame_count == 1) + PDEBUG(DNMT, DEBUG_INFO, "Send 'autoanswer order'.\n"); + set_line_signal(nmt, frame, 12); + if (nmt->tx_frame_count == 4) { + PDEBUG(DNMT, DEBUG_INFO, "No reaction to autoanswer, proceed with ringing.\n"); + nmt_new_state(nmt, STATE_MT_RINGING); + nmt->tx_frame_count = 0; + nmt->tx_callerid_count = 0; + timer_start(&nmt->timer, RINGING_TO); + call_in_alerting(nmt->sender.callref); + } +} + +static void rx_mt_autoanswer(nmt_t *nmt, frame_t *frame) +{ + switch (frame->index) { + case NMT_MESSAGE_15: /* idle */ + nmt->wait_autoanswer = 0; + break; + case NMT_MESSAGE_13a: /* line signal */ + if (!match_channel(nmt, frame)) + break; + if (!match_subscriber(nmt, frame)) + break; + if ((frame->line_signal & 0xf) != 12) + break; + PDEBUG(DNMT, DEBUG_INFO, "Received acknowlege to autoanswer.\n"); + nmt_new_state(nmt, STATE_MT_COMPLETE); + nmt->tx_frame_count = 0; + call_in_answer(nmt->sender.callref, &nmt->subscriber.country); + break; + default: + PDEBUG(DNMT, DEBUG_DEBUG, "Dropping message %s in state %s\n", nmt_frame_name(frame->index), nmt_state_name(nmt->state)); + } +} + static void tx_mt_ringing(nmt_t *nmt, frame_t *frame) { set_line_signal(nmt, frame, 9); @@ -967,6 +1020,8 @@ static void rx_mt_ringing(nmt_t *nmt, frame_t *frame) { switch (frame->index) { case NMT_MESSAGE_13a: /* line signal */ + if (!match_channel(nmt, frame)) + break; if (!match_subscriber(nmt, frame)) break; if ((frame->line_signal & 0xf) != 14) @@ -984,12 +1039,7 @@ static void rx_mt_ringing(nmt_t *nmt, frame_t *frame) static void tx_mt_complete(nmt_t *nmt, frame_t *frame) { ++nmt->tx_frame_count; - if (nmt->dms_call) { - if (nmt->tx_frame_count == 1) - PDEBUG(DNMT, DEBUG_INFO, "Send 'autoanswer'.\n"); - set_line_signal(nmt, frame, 12); - } else - if (nmt->compandor) { + if (nmt->compandor && !nmt->dms_call) { if (nmt->tx_frame_count == 1) PDEBUG(DNMT, DEBUG_INFO, "Send 'compandor in'.\n"); set_line_signal(nmt, frame, 5); @@ -1274,6 +1324,9 @@ void nmt_receive_frame(nmt_t *nmt, const char *bits, double quality, double leve case STATE_MT_IDENT: rx_mt_ident(nmt, &frame); break; + case STATE_MT_AUTOANSWER: + rx_mt_autoanswer(nmt, &frame); + break; case STATE_MT_RINGING: rx_mt_ringing(nmt, &frame); break; @@ -1352,6 +1405,9 @@ const char *nmt_get_frame(nmt_t *nmt) case STATE_MT_IDENT: tx_mt_ident(nmt, &frame); break; + case STATE_MT_AUTOANSWER: + tx_mt_autoanswer(nmt, &frame); + break; case STATE_MT_RINGING: tx_mt_ringing(nmt, &frame); break; diff --git a/src/nmt/nmt.h b/src/nmt/nmt.h index 8b5b9a4..cd7ff24 100644 --- a/src/nmt/nmt.h +++ b/src/nmt/nmt.h @@ -31,6 +31,7 @@ enum nmt_state { STATE_MT_PAGING, /* paging mobile phone */ STATE_MT_CHANNEL, /* assigning traffic channel */ STATE_MT_IDENT, /* waiting for identity */ + STATE_MT_AUTOANSWER, /* sending autoanswer, waiting for reply */ STATE_MT_RINGING, /* mobile phone is ringing, waiting for answer */ STATE_MT_COMPLETE, /* mobile phone has answered, completing call */ STATE_ACTIVE, /* during active call */ @@ -79,6 +80,7 @@ typedef struct nmt { /* sender's states */ enum nmt_state state; + int wait_autoanswer; /* wait for frame 15 before we can send autoanswer */ enum nmt_active_state active_state; nmt_subscriber_t subscriber; /* current subscriber */ struct timer timer;