aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-10-11 17:29:03 +0200
committerPatrick McHardy <kaber@trash.net>2011-02-26 22:06:07 +0100
commit9ef7618ab81d47bfc0112fdae8d6f9f553c7e992 (patch)
tree97f2e81f7e3176713d3bff665284d40a910fd348
parent57e26b3b1314455f3c29cc28b4dd30a4b36f28b8 (diff)
chan_dect: support configured timeouts for location registration
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--channels/chan_dect.c80
-rw-r--r--configs/dect.conf.sample5
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