dect
/
asterisk
Archived
13
0
Fork 0

chan_dect: support configured timeouts for location registration

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2010-10-11 17:29:03 +02:00
parent 57e26b3b13
commit 9ef7618ab8
2 changed files with 68 additions and 17 deletions

View File

@ -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);

View File

@ -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