diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2016-06-19 17:46:56 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2016-06-19 17:46:56 +0200 |
commit | d851c37eac70ab5336bbf3b97907aaf51d2db94e (patch) | |
tree | ca5e6ace105717d3ff7037376d0b32c955ba500f /src | |
parent | b45b0c6bacf1ae52c23c5030dcc6994c906815a4 (diff) |
common code: Release MNCC call 30 seconds after listening to announcement
Diffstat (limited to 'src')
-rw-r--r-- | src/common/call.c | 37 |
1 files changed, 35 insertions, 2 deletions
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 <stdlib.h> #include <errno.h> #include <sys/time.h> -#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; |