From d851c37eac70ab5336bbf3b97907aaf51d2db94e Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 19 Jun 2016 17:46:56 +0200 Subject: common code: Release MNCC call 30 seconds after listening to announcement --- src/common/call.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'src/common/call.c') diff --git a/src/common/call.c b/src/common/call.c index e656409..d83fc8f 100644 --- a/src/common/call.c +++ b/src/common/call.c @@ -24,12 +24,15 @@ #include #include #include -#include "../common/debug.h" -#include "../common/sender.h" +#include "debug.h" +#include "sender.h" #include "cause.h" #include "call.h" +#include "timer.h" #include "mncc_sock.h" +#define DISC_TIMEOUT 30 + extern int use_mncc_sock; extern int send_patterns; @@ -219,10 +222,14 @@ typedef struct process { int audio_disconnected; /* if not associated with transceiver anymore */ enum audio_pattern pattern; int audio_pos; + uint8_t cause; + struct timer timer; } process_t; static process_t *process_head = NULL; +static void process_timeout(struct timer *timer); + static void create_process(int callref, int state) { process_t *process; @@ -232,6 +239,7 @@ static void create_process(int callref, int state) PDEBUG(DCALL, DEBUG_ERROR, "No memory!\n"); abort(); } + timer_init(&process->timer, process_timeout, process); process->next = process_head; process_head = process; @@ -247,6 +255,7 @@ static void destroy_process(int callref) while (process) { if (process->callref == callref) { *process_p = process->next; + timer_exit(&process->timer); free(process); return; } @@ -319,6 +328,8 @@ static void disconnect_process(int callref, int cause) process->pattern = cause2pattern(cause); process->audio_disconnected = 1; process->audio_pos = 0; + process->cause = cause; + timer_start(&process->timer, DISC_TIMEOUT); return; } process = process->next; @@ -378,6 +389,28 @@ static void get_process_patterns(process_t *process, int16_t *samples, int lengt process->audio_pos = pos; } +static void process_timeout(struct timer *timer) +{ + process_t *process = (process_t *)timer->priv; + + { + /* announcement timeout */ + 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_IND; + mncc->callref = process->callref; + mncc->fields |= MNCC_F_CAUSE; + mncc->cause.location = 1; /* private local */ + mncc->cause.value = process->cause; + + destroy_process(process->callref); + PDEBUG(DMNCC, DEBUG_INFO, "Releasing MNCC call towards Network (after timeout)\n"); + mncc_write(buf, sizeof(struct gsm_mncc)); + } +} + int call_init(const char *station_id, const char *sounddev, int samplerate, int latency, int dial_digits, int loopback) { int rc = 0; -- cgit v1.2.3