chan_dect: support configured timeouts for location registration
Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
57e26b3b13
commit
9ef7618ab8
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in New Issue