summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Wedhorn <voip@facts.com.au>2011-10-06 20:18:45 +0000
committerDamien Wedhorn <voip@facts.com.au>2011-10-06 20:18:45 +0000
commitd59bb319fc4769fa64771562f3a34bbbfc9d75bc (patch)
tree28082f6891cf05c8d33775e251cb0be8d6a8551b
parent2f82296096782a378214f23f3925ba132953e1aa (diff)
Fixed segfault on core stop gracefully.
There was an issue that the cap and confcap pointers for each line and device were being memcpy'd so they all pointed to the same ast_format_cap. On destroying, a segfault occured on the second call to the same struct. skinny reload now works again as well. Tested by snuff and myself. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@339680 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_skinny.c41
1 files changed, 11 insertions, 30 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 523d7ffdf..dbec7e36d 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -1280,9 +1280,7 @@ struct skinny_subchannel {
int amaflags; \
int instance; \
int group; \
- struct ast_format_cap *confcap; \
struct ast_codec_pref confprefs; \
- struct ast_format_cap *cap; \
struct ast_codec_pref prefs; \
int nonCodecCapability; \
int immediate; \
@@ -1301,6 +1299,8 @@ struct skinny_line {
AST_LIST_ENTRY(skinny_line) list;
AST_LIST_ENTRY(skinny_line) all;
struct skinny_device *device;
+ struct ast_format_cap *cap;
+ struct ast_format_cap *confcap;
struct ast_variable *chanvars; /*!< Channel variables to set for inbound call */
int newmsgs;
};
@@ -1386,9 +1386,7 @@ struct skinny_addon {
int hookstate; \
int lastlineinstance; \
int lastcallreference; \
- struct ast_format_cap *confcap; \
struct ast_codec_pref confprefs; \
- struct ast_format_cap *cap; \
int earlyrtp; \
int transfer; \
int callwaiting; \
@@ -1406,6 +1404,8 @@ struct skinny_device {
struct ast_ha *ha;
struct skinnysession *session;
struct skinny_line *activeline;
+ struct ast_format_cap *cap;
+ struct ast_format_cap *confcap;
AST_LIST_HEAD(, skinny_line) lines;
AST_LIST_HEAD(, skinny_speeddial) speeddials;
AST_LIST_HEAD(, skinny_addon) addons;
@@ -7347,20 +7347,20 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
}
} else if (!strcasecmp(v->name, "allow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
- ast_parse_allow_disallow(&CDEV_OPTS->confprefs, CDEV_OPTS->confcap, v->value, 1);
+ ast_parse_allow_disallow(&CDEV->confprefs, CDEV->confcap, v->value, 1);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- ast_parse_allow_disallow(&CLINE_OPTS->confprefs, CLINE_OPTS->confcap, v->value, 1);
+ ast_parse_allow_disallow(&CLINE->confprefs, CLINE->confcap, v->value, 1);
continue;
}
} else if (!strcasecmp(v->name, "disallow")) {
if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
- ast_parse_allow_disallow(&CDEV_OPTS->confprefs, CDEV_OPTS->confcap, v->value, 0);
+ ast_parse_allow_disallow(&CDEV->confprefs, CDEV->confcap, v->value, 0);
continue;
}
if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- ast_parse_allow_disallow(&CLINE_OPTS->confprefs, CLINE_OPTS->confcap, v->value, 0);
+ ast_parse_allow_disallow(&CLINE->confprefs, CLINE->confcap, v->value, 0);
continue;
}
} else if (!strcasecmp(v->name, "version")) {
@@ -7545,6 +7545,7 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
memcpy(l, default_line, sizeof(*default_line));
ast_mutex_init(&l->lock);
ast_copy_string(l->name, lname, sizeof(l->name));
+ ast_format_cap_copy(l->confcap, default_cap);
AST_LIST_INSERT_TAIL(&lines, l, all);
ast_mutex_lock(&l->lock);
@@ -7602,6 +7603,7 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
memcpy(d, default_device, sizeof(*default_device));
ast_mutex_init(&d->lock);
ast_copy_string(d->name, dname, sizeof(d->name));
+ ast_format_cap_copy(d->confcap, default_cap);
AST_LIST_INSERT_TAIL(&devices, d, list);
ast_mutex_lock(&d->lock);
@@ -7714,7 +7716,6 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
bindaddr.sin_family = AF_INET;
/* load the lines sections */
- ast_format_cap_copy(default_line->confcap, default_cap);
default_line->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines"));
cat = ast_category_browse(cfg, "lines");
@@ -7724,7 +7725,6 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
}
/* load the devices sections */
- ast_format_cap_copy(default_device->confcap, default_cap);
default_device->confprefs = default_prefs;
config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices"));
cat = ast_category_browse(cfg, "devices");
@@ -7795,6 +7795,7 @@ static void delete_devices(void)
/* Delete all lines for this device */
while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
AST_LIST_REMOVE(&lines, l, all);
+ AST_LIST_REMOVE(&d->lines, l, list);
l = skinny_line_destroy(l);
}
/* Delete all speeddials for this device */
@@ -7904,26 +7905,10 @@ static int load_module(void)
if (!(skinny_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_DECLINE;
}
- if (!(default_line->confcap = ast_format_cap_alloc())) {
- return AST_MODULE_LOAD_DECLINE;
- }
- if (!(default_line->cap = ast_format_cap_alloc())) {
- return AST_MODULE_LOAD_DECLINE;
- }
- if (!(default_device->confcap = ast_format_cap_alloc())) {
- return AST_MODULE_LOAD_DECLINE;
- }
- if (!(default_device->cap = ast_format_cap_alloc())) {
- return AST_MODULE_LOAD_DECLINE;
- }
ast_format_cap_add_all_by_type(skinny_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
- ast_format_cap_add(default_line->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(default_line->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
- ast_format_cap_add(default_device->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
- ast_format_cap_add(default_device->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
for (; res < ARRAY_LEN(soft_key_template_default); res++) {
soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
@@ -8029,10 +8014,6 @@ static int unload_module(void)
default_cap = ast_format_cap_destroy(default_cap);
skinny_tech.capabilities = ast_format_cap_destroy(skinny_tech.capabilities);
- default_line->confcap = ast_format_cap_destroy(default_line->confcap);
- default_line->cap = ast_format_cap_destroy(default_line->cap);
- default_device->confcap = ast_format_cap_destroy(default_device->confcap);
- default_device->cap = ast_format_cap_destroy(default_device->cap);
return 0;
}