[asterisk-ss7] chan_ss7 1.4.3 bug with overlapping CIC numbers on combined linksets
Jasper van der Neut - Stulen
jasper at speakup.nl
Fri Jan 7 11:52:02 CST 2011
Gregory Massel wrote:
> Hi Robert
>
> I think the write buffer notice you're getting is normal audio loss due to the jitter buffer and
> jitter associated with the SIP channel.
>
> It seems that remove_from_idlelist() in l4isup.c may be the issue:
>
> static void remove_from_idlelist(struct ss7_chan *pvt) {
> struct linkset* linkset = pvt->link->linkset;
> struct ss7_chan *prev, *cur;
>
>
> cur = linkset->group_linkset->idle_list;
> prev = NULL;
> while(cur != NULL) {
> if(pvt->cic == cur->cic) {
> if(prev == NULL) {
> linkset->group_linkset->idle_list = pvt->next_idle;
> } else {
> prev->next_idle = pvt->next_idle;
> }
> pvt->next_idle = NULL;
> return;
> }
> prev = cur;
> cur = cur->next_idle;
> }
> ast_log(LOG_NOTICE, "Trying to remove CIC=%d from idle list, but not found?!?.\n", pvt->cic);
> }
>
>
> What concerns me is the following line:
>
> if(pvt->cic == cur->cic) {
>
> I get the impression that it should read something like:
>
> if(pvt->cic == cur->cic && linkset->dpc == cur->linkset->dpc) {
>
> In my mind, this should, in theory, ensure that the CIC is matched not just on the CIC number but
> also on the DPC.
Although the above seems buggy indeed, this only is an use when you use a 'group' statement in your
configuration, which you don't according to your first email.
I think the problem is caused by the various cic_hunt functions, for example:
/* This implements the policy: Sequential low to high CICs */
static struct ss7_chan *cic_hunt_seq_lth_htl(struct linkset* linkset, int lth, int first_cic, int
last_cic)
{
struct ss7_chan *cur, *prev, *best = NULL, *best_prev = NULL;
for(cur = linkset->group_linkset->idle_list, prev = NULL; cur != NULL; prev = cur, cur =
cur->next_idle) {
/* Don't select lines that are resetting or blocked. */
if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN|BL_NOUSE))) {
continue;
}
/* is this cic within the selected range? */
if(cur->cic < first_cic || cur->cic > last_cic) {
continue;
}
if (!best) {
best = cur;
continue;
}
if (lth) {
if (cur->cic < best->cic) {
best = cur;
best_prev = prev;
}
}
else {
if (cur->cic > best->cic) {
best = cur;
best_prev = prev;
}
}
}
if(best != NULL) {
if(best_prev == NULL) {
linkset->group_linkset->idle_list = best->next_idle;
} else {
best_prev->next_idle = best->next_idle;
}
best->next_idle = NULL;
return best;
} else {
ast_log(LOG_WARNING, "No idle circuit found.\n");
return NULL;
}
}
If "best" is the n-th entry and the first - (n-1)th entry are either blocked for
some reason or outside the range we want, "best_prev" will still be NULL when
we remove "best" from the idle_list, which all cause all entries before "best"
to also be removed from the idle_list.
Using this will fix that:
if(best != NULL) {
remove_from_idlelist(best);
return best;
} else {
ast_log(LOG_WARNING, "No idle circuit found.\n");
return NULL;
}
--
Regards
Jasper van der Neut
SpeakUp BV
T: 088-SPEAKUP (088-7732587)
F: 088-7732588
More information about the asterisk-ss7
mailing list