From 9ef7618ab81d47bfc0112fdae8d6f9f553c7e992 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 11 Oct 2010 17:29:03 +0200 Subject: [PATCH] chan_dect: support configured timeouts for location registration Signed-off-by: Patrick McHardy --- channels/chan_dect.c | 80 ++++++++++++++++++++++++++++++++-------- configs/dect.conf.sample | 5 ++- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/channels/chan_dect.c b/channels/chan_dect.c index a457bf988..4aab00d03 100644 --- a/channels/chan_dect.c +++ b/channels/chan_dect.c @@ -35,6 +35,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision") #define CONFIG_FILE "dect.conf" +#define DECT_LOCATE_TIMEOUT_SLACK 10 /* seconds */ + static const struct ast_channel_tech dect_tech; static struct dect_handle *dh; static struct sched_context *sched; @@ -66,6 +68,7 @@ struct { char regcontext[AST_MAX_CONTEXT]; unsigned int regexten_base; char pin[sizeof("00000000")]; + unsigned int locate_duration; } dect_cfg; static AST_LIST_HEAD_STATIC(dect_pt_list, dect_pt); @@ -91,8 +94,13 @@ struct dect_pt { struct dect_ie_terminal_capability *terminal_capability; struct dect_ie_codec_list *codec_list; + + int locate_timer; }; +#define dect_pt_log(pt, fmt, args...) \ + ast_log(LOG_NOTICE, "PT '%s': " fmt, (pt)->name, ## args) + struct dect_pvt { struct dect_pt *pt; struct dect_mm_endpoint *mme; @@ -131,6 +139,7 @@ struct dect_mm_pvt { struct dect_ie_collection *); }; +#define div_round_up(x, y) (((x) + ((y) - 1)) / (y)) #define dect_ie_update(pos, ie) \ do { \ if (ie == NULL) \ @@ -284,6 +293,7 @@ static struct dect_pt *dect_init_portable(const char *name) ast_string_field_set(pt, cid_num, ""); ast_string_field_set(pt, cid_name, ""); ast_string_field_set(pt, ring_pattern, "0"); + pt->locate_timer = -1; AST_LIST_INSERT_TAIL(&dect_pt_list, pt, list); return pt; @@ -637,7 +647,7 @@ static int dect_try_to_connect_call(struct dect_pvt *pvt) if (!ast_exists_extension(NULL, pt->context, chan->exten, 1, NULL)) return -1; - ast_log(LOG_NOTICE, "connecting call\n"); + dect_pt_log(pt, "connecting call\n"); if (ast_pbx_start(chan)) { ast_log(LOG_WARNING, "Unable to start PBX\n"); ast_hangup(chan); @@ -649,9 +659,10 @@ static int dect_try_to_connect_call(struct dect_pvt *pvt) static int dect_answer(struct ast_channel *chan) { struct dect_pvt *pvt = chan->tech_pvt; + struct dect_pt *pt = pvt->pt; struct dect_mncc_connect_param connect = {}; - ast_log(LOG_NOTICE, "answer call state %u\n", chan->_state); + dect_pt_log(pt, "answer call state %u\n", chan->_state); if (chan->_state == AST_STATE_UP || chan->_state == AST_STATE_RINGING) return 0; @@ -735,7 +746,7 @@ static struct ast_channel *dect_request_call(const char *type, format_t format, *cause = AST_CAUSE_UNALLOCATED; return NULL; } - ast_log(LOG_NOTICE, "Outgoing call to %s\n", pt->name); + dect_pt_log(pt, "outgoing call\n"); call = dect_call_alloc(dh); if (call == NULL) { @@ -772,9 +783,9 @@ static int dect_hangup(struct ast_channel *chan) struct dect_ie_release_reason release_reason; struct dect_mncc_release_param param; - ast_log(LOG_NOTICE, "Hangup\n"); - if (chan->_state != AST_STATE_DOWN) { + dect_pt_log(pvt->pt, "hangup\n"); + dect_ie_init(&release_reason); release_reason.reason = DECT_RELEASE_NORMAL; @@ -793,6 +804,7 @@ static int dect_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen) { struct dect_pvt *pvt = chan->tech_pvt; + struct dect_pt *pt = pvt->pt; struct dect_mncc_alert_param alert; struct dect_ie_progress_indicator progress; struct dect_ie_signal signal; @@ -800,7 +812,7 @@ static int dect_indicate(struct ast_channel *chan, int condition, switch (condition) { case AST_CONTROL_RINGING: - ast_log(LOG_NOTICE, "Ringing\n"); + dect_pt_log(pt, "call is ringing\n"); memset(&alert, 0, sizeof(alert)); if (0) { alert.signal = dect_signal_init(&signal, DECT_SIGNAL_RING_BACK_TONE_ON); @@ -825,10 +837,10 @@ static int dect_indicate(struct ast_channel *chan, int condition, case AST_CONTROL_SRCUPDATE: case -1: res = -1; - ast_log(LOG_NOTICE, "Indicate %d\n", condition); + dect_pt_log(pt, "indicate condition %d\n", condition); break; default: - ast_log(LOG_NOTICE, "Indicate unknown condition %d\n", condition); + dect_pt_log(pt, "indicate unknown condition %d\n", condition); res = -1; break; } @@ -1033,8 +1045,7 @@ static void dect_mncc_setup_ind(struct dect_handle *dh, struct dect_call *call, ast_log(LOG_NOTICE, "Incoming call from unknown PT\n"); return dect_mncc_reject(call, DECT_RELEASE_UNKNOWN_IDENTITY); } - - ast_log(LOG_NOTICE, "Incoming call from %s\n", pt->name); + dect_pt_log(pt, "incoming call\n"); mme = dect_mm_endpoint_get(dh, &pt->ipui); if (mme == NULL) @@ -1322,14 +1333,14 @@ static void dect_mm_authenticate_cfm(struct dect_handle *dh, dect_auth_a12(ks, mmp->rand, dck, &res1); if (res1 == param->res->value) { - ast_log(LOG_NOTICE, "PT authentication succeeded\n"); + dect_pt_log(pt, "authentication succeeded\n"); /* Store DCK */ memcpy(pt->dck, dck, sizeof(pt->dck)); auth_cfm(mmp, true, iec); } else { reject: - ast_log(LOG_NOTICE, "PT authentication failed\n"); + dect_pt_log(pt, "authentication failed\n"); auth_cfm(mmp, false, iec); } @@ -1605,6 +1616,7 @@ static void dect_destroy_portable(struct dect_pt *pt) dect_register_extension(pt, false); AST_LIST_REMOVE(&dect_pt_list, pt, list); + AST_SCHED_DEL(sched, pt->locate_timer); ast_free(pt); } @@ -1686,6 +1698,16 @@ static void dect_access_rights_terminate(struct dect_pt *pt) * Location procedures */ +static int dect_locate_timer(const void *data) +{ + struct dect_pt *pt = (struct dect_pt *)data;; + + dect_pt_log(pt, "location registation timeout\n"); + dect_register_extension(pt, false); + pt->locate_timer = -1; + return 0; +} + static void dect_mm_locate_reject(struct dect_mm_endpoint *mme, enum dect_reject_reasons reason) { @@ -1708,6 +1730,7 @@ static void dect_mm_locate_auth_cfm(struct dect_mm_pvt *mmp, bool success, .codec_list = param->codec_list, .duration = &duration, }; + unsigned int limit, timeout; if (!success) { dect_mm_locate_reject(mme, DECT_REJECT_AUTHENTICATION_FAILED); @@ -1718,8 +1741,23 @@ static void dect_mm_locate_auth_cfm(struct dect_mm_pvt *mmp, bool success, portable_identity.tpui = pt->tpui; duration.lock = DECT_LOCK_TEMPORARY_USER_LIMIT_1; - duration.time = DECT_TIME_LIMIT_DEFINED_TIME_LIMIT_1; - duration.duration = 1; + if (dect_cfg.locate_duration * DECT_FRAMES_PER_SECOND <= + 255 * DECT_TIME_LIMIT_UNITS_1) { + limit = div_round_up(dect_cfg.locate_duration * + DECT_FRAMES_PER_SECOND, + DECT_TIME_LIMIT_UNITS_1); + timeout = div_round_up(limit * DECT_TIME_LIMIT_UNITS_1, + DECT_FRAMES_PER_SECOND); + duration.time = DECT_TIME_LIMIT_DEFINED_TIME_LIMIT_1; + } else { + limit = div_round_up(dect_cfg.locate_duration * + DECT_FRAMES_PER_SECOND, + DECT_TIME_LIMIT_UNITS_2); + timeout = div_round_up(limit * DECT_TIME_LIMIT_UNITS_2, + DECT_FRAMES_PER_SECOND); + duration.time = DECT_TIME_LIMIT_DEFINED_TIME_LIMIT_2; + } + duration.duration = limit; if (dect_mm_locate_res(dh, mme, true, &reply) < 0) return; @@ -1733,7 +1771,13 @@ static void dect_mm_locate_auth_cfm(struct dect_mm_pvt *mmp, bool success, dect_db_store_codec_list(pt); } + timeout += DECT_LOCATE_TIMEOUT_SLACK; + dect_pt_log(pt, "location registration: timeout: %us\n", timeout); + dect_register_extension(pt, true); + pt->locate_timer = ast_sched_replace(pt->locate_timer, sched, + timeout * 1000, + dect_locate_timer, pt); } static void dect_mm_locate_ind(struct dect_handle *dh, @@ -1845,6 +1889,8 @@ static int dect_load_config(void) } else if (!strcasecmp(v->name, "pin")) { ast_copy_string(dect_cfg.pin, v->value, sizeof(dect_cfg.pin)); + } else if (!strcasecmp(v->name, "locate_duration")) { + dect_cfg.locate_duration = strtoul(v->value, NULL, 0); } } @@ -1913,9 +1959,10 @@ static char *dect_cli_show_portables(struct ast_cli_entry *e, int cmd, return NULL; } - ast_cli(a->fd, "Name Extension\n"); + ast_cli(a->fd, "Name Extension Registered\n"); AST_LIST_TRAVERSE(&dect_pt_list, pt, list) - ast_cli(a->fd, "%-16s%s\n", pt->name, pt->regexten); + ast_cli(a->fd, "%-16s%-16s%-16s\n", + pt->name, pt->regexten, pt->locate_timer == -1 ? "No" : "Yes"); return CLI_SUCCESS; } @@ -1952,6 +1999,7 @@ static char *dect_cli_show_portable(struct ast_cli_entry *e, int cmd, ast_cli(a->fd, "IPEI: %s\n", pt->ipei); ast_cli(a->fd, "Extension: %s\n", pt->regexten); + ast_cli(a->fd, "Registered: %s\n", pt->locate_timer == -1 ? "No" : "Yes"); ast_cli(a->fd, "Context: %s\n", pt->context); ast_cli(a->fd, "Language: %s\n", pt->language); ast_cli(a->fd, "CallerId: %s\n", cidbuf); diff --git a/configs/dect.conf.sample b/configs/dect.conf.sample index 524cbd5b2..530b47fb8 100644 --- a/configs/dect.conf.sample +++ b/configs/dect.conf.sample @@ -7,7 +7,10 @@ language = de ; Registration context for dynamic registrations regcontext = dect_register regexten_base = 600 -pin = 1234 + +pin = 1234 ; PIN code for access rights requests/key allocation +locate_duration = 60 ; duration location registration stays valid, in seconds, will be + ; rounded up to a unit of 16 or 256 multiframes ;------------------------------ JITTER BUFFER CONFIGURATION -------------------------- ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an