Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
A
asterisk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Voice
asterisk
Commits
96a2ce1a
Commit
96a2ce1a
authored
5 years ago
by
George Joseph
Committed by
Gerrit Code Review
5 years ago
Browse files
Options
Downloads
Plain Diff
Merge "openr2(5/6): added cli command -- mfcr2 destroy link <index>"
parents
64b6d0fc
f6709450
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
channels/chan_dahdi.c
+187
-24
187 additions, 24 deletions
channels/chan_dahdi.c
with
187 additions
and
24 deletions
channels/chan_dahdi.c
+
187
−
24
View file @
96a2ce1a
...
...
@@ -749,6 +749,7 @@ struct dahdi_mfcr2 {
openr2_context_t *protocol_context; /*!< OpenR2 context handle */
struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
int numchans; /*!< Number of channels in this R2 block */
int live_chans; /*!< Number of unremoved channels in this R2 block */
int nodev; /*!< Link disconnected? */
struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */
};
...
...
@@ -758,6 +759,8 @@ struct r2link_entry {
AST_LIST_ENTRY(r2link_entry) list;
};
static AST_LIST_HEAD_STATIC(r2links, r2link_entry);
static struct r2links nodev_r2links = AST_LIST_HEAD_INIT_VALUE;
/* how many r2links have been malloc'd */
static int r2links_count = 0;
...
...
@@ -3548,6 +3551,21 @@ static void handle_clear_alarms(struct dahdi_pvt *p)
}
#ifdef HAVE_OPENR2
static void mfcr2_queue_for_destruction(const struct dahdi_pvt *p)
{
const struct dahdi_mfcr2 *r2link = p->mfcr2;
struct r2link_entry *cur;
AST_LIST_LOCK(&r2links);
AST_LIST_TRAVERSE_SAFE_BEGIN(&r2links, cur, list) {
if (r2link == &cur->mfcr2) {
ast_debug(3, "MFC/R2 channel %d queued for destruction\n", p->channel);
AST_LIST_MOVE_CURRENT(&nodev_r2links, list);
break;
}
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&r2links);
}
static int dahdi_r2_answer(struct dahdi_pvt *p)
{
...
...
@@ -3633,6 +3651,9 @@ static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
p->inalarm = alarm ? 1 : 0;
if (p->inalarm) {
res = get_alarms(p);
if (res == DAHDI_ALARM_NOTOPEN) {
mfcr2_queue_for_destruction(p);
}
handle_alarms(p, res);
} else {
handle_clear_alarms(p);
...
...
@@ -5490,6 +5511,49 @@ static void dahdi_unlink_ss7_pvt(struct dahdi_pvt *pvt)
}
#endif /* defined(HAVE_SS7) */
#if defined(HAVE_OPENR2)
/*!
* \internal
* \brief Unlink the channel interface from the MFC/R2 private pointer array.
*
* \param pvt chan_dahdi private interface structure to unlink.
*
* \return Nothing
*/
static void dahdi_unlink_mfcr2_pvt(struct dahdi_pvt *pvt)
{
unsigned idx;
struct dahdi_mfcr2 *mfcr2;
int should_destroy_link = 0;
ast_mutex_lock(&pvt->lock);
if (pvt->r2chan) {
ast_debug(1, "Disable MFC/R2 channel %d read\n", pvt->channel);
openr2_chan_disable_read(pvt->r2chan);
}
mfcr2 = pvt->mfcr2;
if (mfcr2) {
for (idx = 0; idx < mfcr2->numchans; ++idx) {
if (mfcr2->pvts[idx] == pvt) {
ast_debug(1, "Removing MFC/R2 channel %d from the mfcr2 link\n", pvt->channel);
mfcr2->pvts[idx] = NULL;
mfcr2->live_chans--;
break;
}
}
if (!mfcr2->live_chans) {
ast_debug(1, "MFC/R2 link is now empty\n");
should_destroy_link = 1;
}
}
ast_mutex_unlock(&pvt->lock);
if (should_destroy_link) {
ast_debug(1, "MFC/R2 link is now empty\n");
mfcr2_queue_for_destruction(pvt);
}
}
#endif /* defined(HAVE_OPENR2) */
static struct dahdi_pvt *find_next_iface_in_span(struct dahdi_pvt *cur)
{
if (cur->next && cur->next->span == cur->span) {
...
...
@@ -5518,6 +5582,9 @@ static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_SS7)
dahdi_unlink_ss7_pvt(p);
#endif /* defined(HAVE_SS7) */
#if defined(HAVE_OPENR2)
dahdi_unlink_mfcr2_pvt(p);
#endif /* defined(HAVE_SS7) */
switch (pvt->which_iflist) {
case DAHDI_IFLIST_NONE:
...
...
@@ -11032,6 +11099,40 @@ static void dahdi_destroy_channel_range(int start, int end)
}
}
#ifdef HAVE_OPENR2
static void dahdi_r2_destroy_nodev(void)
{
struct r2link_entry *cur;
AST_LIST_LOCK(&nodev_r2links);
AST_LIST_TRAVERSE_SAFE_BEGIN(&nodev_r2links, cur, list) {
int i;
struct dahdi_mfcr2 *r2 = &cur->mfcr2;
ast_debug(3, "About to destroy %d DAHDI channels of MFC/R2 link.\n", r2->numchans);
for (i = 0; i < r2->numchans; i++) {
int channel;
struct dahdi_pvt *pvt = r2->pvts[i];
if (!pvt) {
continue;
}
channel = pvt->channel;
ast_debug(3, "About to destroy B-channel %d.\n", channel);
dahdi_destroy_channel_range(channel, channel);
}
ast_debug(3, "Destroying R2 link\n");
AST_LIST_REMOVE(&nodev_r2links, cur, list);
if (r2->r2master != AST_PTHREADT_NULL) {
pthread_cancel(r2->r2master);
pthread_join(r2->r2master, NULL);
r2->r2master = AST_PTHREADT_NULL;
openr2_context_delete(r2->protocol_context);
}
ast_free(cur);
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&nodev_r2links);
}
#endif
static int setup_dahdi(int reload);
static int setup_dahdi_int(int reload, struct dahdi_chan_conf *default_conf, struct dahdi_chan_conf *base_conf, struct dahdi_chan_conf *conf);
...
...
@@ -11655,6 +11756,9 @@ static void *do_monitor(void *data)
}
ast_mutex_unlock(&iflock);
release_doomed_pris();
#ifdef HAVE_OPENR2
dahdi_r2_destroy_nodev();
#endif
}
/* Never reached */
pthread_cleanup_pop(1);
...
...
@@ -11841,21 +11945,17 @@ static struct dahdi_ss7 * ss7_resolve_linkset(int linkset)
static void dahdi_r2_destroy_links(void)
{
struct r2link_entry *cur;
/* Queue everything for removal */
AST_LIST_LOCK(&r2links);
AST_LIST_TRAVERSE_SAFE_BEGIN(&r2links, cur, list) {
struct dahdi_mfcr2 *r2 = &cur->mfcr2;
ast_debug(3, "Destroying R2 link\n");
AST_LIST_REMOVE(&r2links, cur, list);
if (r2->r2master != AST_PTHREADT_NULL) {
pthread_cancel(r2->r2master);
pthread_join(r2->r2master, NULL);
openr2_context_delete(r2->protocol_context);
}
ast_free(cur);
ast_debug(3, "MFC/R2 link #%d queued for destruction\n", cur->mfcr2.index);
AST_LIST_MOVE_CURRENT(&nodev_r2links, list);
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&r2links);
r2links_count = 0;
/* Now destroy properly */
dahdi_r2_destroy_nodev();
}
/* This is an artificial convenient capacity, to keep at most a full E1 of channels in a single thread */
...
...
@@ -12189,6 +12289,7 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
destroy_dahdi_pvt(tmp);
return NULL;
}
r2_link->live_chans++;
tmp->mfcr2 = r2_link;
if (conf->mfcr2.call_files) {
openr2_chan_enable_call_files(tmp->r2chan);
...
...
@@ -13750,6 +13851,8 @@ static void dahdi_ss7_error(struct ss7 *ss7, char *s)
static void *mfcr2_monitor(void *data)
{
struct dahdi_mfcr2 *mfcr2 = data;
struct dahdi_pvt *pvt;
/* we should be using pthread_key_create
and allocate pollers dynamically.
I think do_monitor() could be leaking, since it
...
...
@@ -13766,8 +13869,12 @@ static void *mfcr2_monitor(void *data)
/* now that we're ready to get calls, unblock our side and
get current line state */
for (i = 0; i < mfcr2->numchans; i++) {
openr2_chan_set_idle(mfcr2->pvts[i]->r2chan);
openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan);
pvt = mfcr2->pvts[i];
if (!pvt) {
continue;
}
openr2_chan_set_idle(pvt->r2chan);
openr2_chan_handle_cas(pvt->r2chan);
}
while (1) {
/* we trust here that the mfcr2 channel list will not ever change once
...
...
@@ -13776,20 +13883,24 @@ static void *mfcr2_monitor(void *data)
for (i = 0; i < mfcr2->numchans; i++) {
pollers[i].revents = 0;
pollers[i].events = 0;
if (mfcr2->pvts[i]->owner) {
pvt = mfcr2->pvts[i];
if (!pvt) {
continue;
}
if (pvt->owner) {
continue;
}
if (mfcr2->nodev) {
continue;
}
if (!
mfcr2->pvts[i]
->r2chan) {
ast_debug(1, "Wow, no r2chan on channel %d\n",
mfcr2->pvts[i]
->channel);
if (!
pvt
->r2chan) {
ast_debug(1, "Wow, no r2chan on channel %d\n",
pvt
->channel);
quit_loop = 1;
break;
}
openr2_chan_enable_read(
mfcr2->pvts[i]
->r2chan);
openr2_chan_enable_read(
pvt
->r2chan);
pollers[i].events = POLLIN | POLLPRI;
pollers[i].fd =
mfcr2->pvts[i]
->subs[SUB_REAL].dfd;
pollers[i].fd =
pvt
->subs[SUB_REAL].dfd;
pollsize++;
}
if (quit_loop) {
...
...
@@ -13816,8 +13927,12 @@ static void *mfcr2_monitor(void *data)
/* do we want to allow to cancel while processing events? */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
for (i = 0; i < mfcr2->numchans; i++) {
pvt = mfcr2->pvts[i];
if (!pvt) {
continue;
}
if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) {
openr2_chan_process_event(
mfcr2->pvts[i]
->r2chan);
openr2_chan_process_event(
pvt
->r2chan);
}
}
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
...
...
@@ -15121,6 +15236,51 @@ static char *handle_mfcr2_show_links(struct ast_cli_entry *e, int cmd, struct as
return CLI_SUCCESS;
}
static char *handle_mfcr2_destroy_link(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
int res;
int wanted_link_index;
int found_link = 0;
struct r2link_entry *cur = NULL;
switch (cmd) {
case CLI_INIT:
e->command = "mfcr2 destroy link";
e->usage =
"Usage: mfcr2 destroy link <index-number>\n"
" Destorys D-channel of link and its B-channels.\n"
" DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc < 4) {
return CLI_SHOWUSAGE;
}
res = sscanf(a->argv[3], "%30d", &wanted_link_index);
if ((res != 1) || wanted_link_index < 1) {
ast_cli(a->fd,
"Invalid link index '%s'. Should be a positive number\n", a->argv[3]);
return CLI_SUCCESS;
}
AST_LIST_LOCK(&r2links);
AST_LIST_TRAVERSE_SAFE_BEGIN(&r2links, cur, list) {
struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
if (wanted_link_index == mfcr2->index) {
AST_LIST_MOVE_CURRENT(&nodev_r2links, list);
r2links_count--;
break;
}
}
AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&r2links);
if (! found_link) {
ast_cli(a->fd, "No link found with index %d.\n", wanted_link_index);
return CLI_FAILURE;
}
return CLI_SUCCESS;
}
static struct ast_cli_entry dahdi_mfcr2_cli[] = {
AST_CLI_DEFINE(handle_mfcr2_version, "Show OpenR2 library version"),
AST_CLI_DEFINE(handle_mfcr2_show_variants, "Show supported MFC/R2 variants"),
...
...
@@ -15130,6 +15290,7 @@ static struct ast_cli_entry dahdi_mfcr2_cli[] = {
AST_CLI_DEFINE(handle_mfcr2_call_files, "Enable/Disable MFC/R2 call files"),
AST_CLI_DEFINE(handle_mfcr2_set_idle, "Reset MFC/R2 channel forcing it to IDLE"),
AST_CLI_DEFINE(handle_mfcr2_set_blocked, "Reset MFC/R2 channel forcing it to BLOCKED"),
AST_CLI_DEFINE(handle_mfcr2_destroy_link, "Destroy given MFC/R2 link"),
};
#endif /* HAVE_OPENR2 */
...
...
@@ -19437,13 +19598,15 @@ static int setup_dahdi_int(int reload, struct dahdi_chan_conf *default_conf, str
AST_LIST_LOCK(&r2links);
AST_LIST_TRAVERSE(&r2links, cur, list) {
struct dahdi_mfcr2 *r2 = &cur->mfcr2;
if (ast_pthread_create(&r2->r2master, NULL, mfcr2_monitor, r2)) {
ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
return -1;
} else {
ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
if (r2->r2master == AST_PTHREADT_NULL) {
if (ast_pthread_create(&r2->r2master, NULL, mfcr2_monitor, r2)) {
ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
return -1;
} else {
ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
}
x++;
}
x++;
}
AST_LIST_UNLOCK(&r2links);
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment