openr2(3/6): Convert r2links to standard Asterisk AST_LIST*

Change-Id: Ibcb2401515a58782a1488c0b9efbed201c3f3a17
Signed-off-by: Oron Peled <oron.peled@xorcom.com>
13.29
Tzafrir Cohen 6 years ago committed by George Joseph
parent 4b779a59e4
commit b3de2c0e1e

@ -757,16 +757,21 @@ struct dahdi_mfcr2_conf {
/* MFC-R2 pseudo-link structure */ /* MFC-R2 pseudo-link structure */
struct dahdi_mfcr2 { struct dahdi_mfcr2 {
int index; /*!< Unique index for CLI */
pthread_t r2master; /*!< Thread of master */ pthread_t r2master; /*!< Thread of master */
openr2_context_t *protocol_context; /*!< OpenR2 context handle */ openr2_context_t *protocol_context; /*!< OpenR2 context handle */
struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */ struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
int numchans; /*!< Number of channels in this R2 block */ int numchans; /*!< Number of channels in this R2 block */
int nodev; /*!< Link disconnected? */ int nodev; /*!< Link disconnected? */
struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */ struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */
}; };
/* malloc'd array of malloc'd r2links */ struct r2link_entry {
static struct dahdi_mfcr2 **r2links; struct dahdi_mfcr2 mfcr2;
AST_LIST_ENTRY(r2link_entry) list;
};
static AST_LIST_HEAD_STATIC(r2links, r2link_entry);
/* how many r2links have been malloc'd */ /* how many r2links have been malloc'd */
static int r2links_count = 0; static int r2links_count = 0;
@ -11902,55 +11907,74 @@ static struct dahdi_ss7 * ss7_resolve_linkset(int linkset)
#ifdef HAVE_OPENR2 #ifdef HAVE_OPENR2
static void dahdi_r2_destroy_links(void) static void dahdi_r2_destroy_links(void)
{ {
int i = 0; struct r2link_entry *cur;
if (!r2links) { AST_LIST_LOCK(&r2links);
return; AST_LIST_TRAVERSE_SAFE_BEGIN(&r2links, cur, list) {
} struct dahdi_mfcr2 *r2 = &cur->mfcr2;
for (; i < r2links_count; i++) { ast_debug(3, "Destroying R2 link\n");
if (r2links[i]->r2master != AST_PTHREADT_NULL) { AST_LIST_REMOVE(&r2links, cur, list);
pthread_cancel(r2links[i]->r2master); if (r2->r2master != AST_PTHREADT_NULL) {
pthread_join(r2links[i]->r2master, NULL); pthread_cancel(r2->r2master);
openr2_context_delete(r2links[i]->protocol_context); pthread_join(r2->r2master, NULL);
} openr2_context_delete(r2->protocol_context);
ast_free(r2links[i]); }
} ast_free(cur);
ast_free(r2links); }
r2links = NULL; AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_UNLOCK(&r2links);
r2links_count = 0; r2links_count = 0;
} }
/* This is an artificial convenient capacity, to keep at most a full E1 of channels in a single thread */ /* This is an artificial convenient capacity, to keep at most a full E1 of channels in a single thread */
#define R2_LINK_CAPACITY 30 #define R2_LINK_CAPACITY 30
static struct dahdi_mfcr2 *dahdi_r2_get_link(const struct dahdi_chan_conf *conf) static struct r2link_entry *dahdi_r2_get_link(const struct dahdi_chan_conf *conf)
{ {
struct dahdi_mfcr2 *new_r2link = NULL; struct r2link_entry *cur = NULL;
struct dahdi_mfcr2 **new_r2links = NULL;
/* Only create a new R2 link if /* Only create a new R2 link if
1. This is the first link requested 1. This is the first link requested
2. Configuration changed 2. Configuration changed
3. We got more channels than supported per link */ 3. We got more channels than supported per link */
if (!r2links_count || AST_LIST_LOCK(&r2links);
memcmp(&conf->mfcr2, &r2links[r2links_count - 1]->conf, sizeof(conf->mfcr2)) || if (! AST_LIST_EMPTY(&r2links)) {
(r2links[r2links_count - 1]->numchans == R2_LINK_CAPACITY)) { cur = AST_LIST_LAST(&r2links);
new_r2link = ast_calloc(1, sizeof(**r2links)); if (memcmp(&conf->mfcr2, &cur->mfcr2.conf, sizeof(conf->mfcr2))) {
if (!new_r2link) { ast_debug(3, "Need new R2 link because of: Configuration change\n");
ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); cur = NULL;
return NULL; } else if (cur->mfcr2.numchans == R2_LINK_CAPACITY) {
ast_debug(3, "Need new R2 link because of: Capacity (%d)\n", R2_LINK_CAPACITY);
cur = NULL;
}
}
if (!cur) {
struct r2link_entry *tmp = NULL;
int new_idx = r2links_count + 1;
int i;
for (i = 1; i <= r2links_count; i++) {
int i_unused = 1;
AST_LIST_TRAVERSE(&r2links, tmp, list) {
if (i == tmp->mfcr2.index) {
i_unused = 0;
break;
}
}
if (i_unused) {
new_idx = i;
break;
}
} }
new_r2links = ast_realloc(r2links, ((r2links_count + 1) * sizeof(*r2links))); cur = ast_calloc(1, sizeof(*cur));
if (!new_r2links) { if (!cur) {
ast_log(LOG_ERROR, "Cannot allocate R2 link!\n"); ast_log(LOG_ERROR, "Cannot allocate R2 link!\n");
ast_free(new_r2link);
return NULL; return NULL;
} }
r2links = new_r2links; cur->mfcr2.index = new_idx;
new_r2link->r2master = AST_PTHREADT_NULL; cur->mfcr2.r2master = AST_PTHREADT_NULL;
r2links[r2links_count] = new_r2link;
r2links_count++; r2links_count++;
ast_debug(1, "Created new R2 link!\n"); ast_debug(3, "Created new R2 link #%d (now have %d)\n", new_idx, r2links_count);
AST_LIST_INSERT_TAIL(&r2links, cur, list);
} }
return r2links[r2links_count - 1]; AST_LIST_UNLOCK(&r2links);
return cur;
} }
static int dahdi_r2_set_context(struct dahdi_mfcr2 *r2_link, const struct dahdi_chan_conf *conf) static int dahdi_r2_set_context(struct dahdi_mfcr2 *r2_link, const struct dahdi_chan_conf *conf)
@ -12237,7 +12261,8 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
#ifdef HAVE_OPENR2 #ifdef HAVE_OPENR2
if (chan_sig == SIG_MFCR2) { if (chan_sig == SIG_MFCR2) {
struct dahdi_mfcr2 *r2_link; struct dahdi_mfcr2 *r2_link;
r2_link = dahdi_r2_get_link(conf); struct r2link_entry *r2_le = dahdi_r2_get_link(conf);
r2_link = &r2_le->mfcr2;
if (!r2_link) { if (!r2_link) {
ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n"); ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
destroy_dahdi_pvt(tmp); destroy_dahdi_pvt(tmp);
@ -14824,10 +14849,11 @@ static char *handle_mfcr2_show_variants(struct ast_cli_entry *e, int cmd, struct
static char *handle_mfcr2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) static char *handle_mfcr2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{ {
#define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n" #define FORMAT "%4s %4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
int filtertype = 0; int filtertype = 0;
int targetnum = 0; int targetnum = 0;
char channo[5]; char channo[5];
char linkno[5];
char anino[5]; char anino[5];
char dnisno[5]; char dnisno[5];
struct dahdi_pvt *p; struct dahdi_pvt *p;
@ -14859,7 +14885,7 @@ static char *handle_mfcr2_show_channels(struct ast_cli_entry *e, int cmd, struct
return CLI_SHOWUSAGE; return CLI_SHOWUSAGE;
} }
} }
ast_cli(a->fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS"); ast_cli(a->fd, FORMAT, "Chan", "Link#", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS");
ast_mutex_lock(&iflock); ast_mutex_lock(&iflock);
for (p = iflist; p; p = p->next) { for (p = iflist; p; p = p->next) {
if (!(p->sig & SIG_MFCR2) || !p->r2chan) { if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
@ -14884,9 +14910,10 @@ static char *handle_mfcr2_show_channels(struct ast_cli_entry *e, int cmd, struct
r2context = openr2_chan_get_context(p->r2chan); r2context = openr2_chan_get_context(p->r2chan);
r2variant = openr2_context_get_variant(r2context); r2variant = openr2_context_get_variant(r2context);
snprintf(channo, sizeof(channo), "%d", p->channel); snprintf(channo, sizeof(channo), "%d", p->channel);
snprintf(linkno, sizeof(linkno), "%d", p->mfcr2->index);
snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context)); snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context));
snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context)); snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context));
ast_cli(a->fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant), ast_cli(a->fd, FORMAT, channo, linkno, openr2_proto_get_variant_string(r2variant),
anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No", anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No",
openr2_context_get_immediate_accept(r2context) ? "Yes" : "No", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No",
openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan)); openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
@ -19435,15 +19462,20 @@ static int setup_dahdi_int(int reload, struct dahdi_chan_conf *default_conf, str
#endif /* defined(HAVE_SS7) */ #endif /* defined(HAVE_SS7) */
#ifdef HAVE_OPENR2 #ifdef HAVE_OPENR2
if (reload != 1) { if (reload != 1) {
int x; struct r2link_entry *cur;
for (x = 0; x < r2links_count; x++) { int x = 0;
if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) { 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); ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
return -1; return -1;
} else { } else {
ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1); ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
} }
x++;
} }
AST_LIST_UNLOCK(&r2links);
} }
#endif #endif
/* And start the monitor for the first time */ /* And start the monitor for the first time */

Loading…
Cancel
Save