Dear all,
Here in the Netherlands we have a SS7 connection with the biggest local
telco. We have 4 E1s with the following CIC usage:
Linkset one:
1-31 Incoming
33-58 Outgoing
58-63 Emergency Traffic
Linkset two:
1-31 Incoming
33-58 Outgoing
58-63 Emergency Traffic
Using the standard Dial command we cannot select on which CICs to send
out traffic, since chan_ss7 will by default use all CICs:
Dial(SS7/Linkset1/number)
To overcome this problem we have written a patch that allows you to
select the CICs when dialing, like follows:
Dial(SS7/Linkset1:33-58/number)
This way we can specify on which CICs to send. With the patch it's also
possible to specify a single CIC like:
Dial(SS7/Linkset1:33/number)
The patch attached was written for chan_ss7 1.2.1
Best Regards,
Matthias van der Vlies
--- l4isup.c.orig 2010-04-14 13:32:30.000000000 +0200
+++ l4isup.c 2010-04-14 13:31:39.000000000 +0200
@@ -525,7 +525,7 @@
/* This implements the policy: Primary hunting group odd CICs, secondary
hunting group even CICs. Choose least recently used CIC. */
-static struct ss7_chan *cic_hunt_odd_lru(struct linkset* linkset) {
+static struct ss7_chan *cic_hunt_odd_lru(struct linkset* linkset, int first_cic, int last_cic) {
struct ss7_chan *cur, *prev, *best, *best_prev;
int odd;
@@ -537,6 +537,10 @@
if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN))) {
continue;
}
+ /* is this cic within the selected range? */
+ if(cur->cic < first_cic || cur->cic > last_cic) {
+ continue;
+ }
if((cur->cic % 2) == odd) {
best = cur;
best_prev = prev;
@@ -558,7 +562,7 @@
/* This implements the policy: Primary hunting group even CICs, secondary
hunting group odd CICs. Choose most recently used CIC. */
-static struct ss7_chan *cic_hunt_even_mru(struct linkset* linkset) {
+static struct ss7_chan *cic_hunt_even_mru(struct linkset* linkset, int first_cic, int last_cic) {
struct ss7_chan *cur, *prev, *best, *best_prev;
best = NULL;
@@ -569,6 +573,10 @@
if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN))) {
continue;
}
+ /* is this cic within the selected range? */
+ if(cur->cic < first_cic || cur->cic > last_cic) {
+ continue;
+ }
if((cur->cic % 2) == 0) {
/* Choose the first idle even circuit, if any. */
best = cur;
@@ -597,7 +605,7 @@
}
/* This implements the policy: Sequential low to high CICs */
-static struct ss7_chan *cic_hunt_seq_lth_htl(struct linkset* linkset, int lth)
+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;
@@ -606,6 +614,10 @@
if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN))) {
continue;
}
+ /* is this cic within the selected range? */
+ if(cur->cic < first_cic || cur->cic > last_cic) {
+ continue;
+ }
if (!best) {
best = cur;
continue;
@@ -815,21 +827,30 @@
}
/* hunt free CIC */
-static struct ss7_chan* cic_hunt(struct linkset* linkset)
+static struct ss7_chan* cic_hunt(struct linkset* linkset, int first_cic, int last_cic)
{
+ if(first_cic > last_cic) {
+ ast_log(LOG_ERROR, "first CIC: %d greater than last CIC: %d\n", first_cic, last_cic);
+ return NULL;
+ }
+ if(first_cic < linkset->first_cic || first_cic > linkset->last_cic || last_cic > linkset->last_cic) {
+ ast_log(LOG_ERROR, "CICs not in valid range, first: %d last: %d\n", first_cic, last_cic);
+ return NULL;
+ }
+
struct ss7_chan* pvt;
switch(linkset->hunt_policy) {
case HUNT_ODD_LRU:
- pvt = cic_hunt_odd_lru(linkset);
+ pvt = cic_hunt_odd_lru(linkset, first_cic, last_cic);
break;
case HUNT_EVEN_MRU:
- pvt = cic_hunt_even_mru(linkset);
+ pvt = cic_hunt_even_mru(linkset, first_cic, last_cic);
break;
case HUNT_SEQ_LTH:
- pvt = cic_hunt_seq_lth_htl(linkset, 1);
+ pvt = cic_hunt_seq_lth_htl(linkset, 1, first_cic, last_cic);
break;
case HUNT_SEQ_HTL:
- pvt = cic_hunt_seq_lth_htl(linkset, 0);
+ pvt = cic_hunt_seq_lth_htl(linkset, 0, first_cic, last_cic);
break;
default:
pvt = NULL;
@@ -847,6 +868,7 @@
struct ss7_chan *pvt;
struct linkset* linkset = this_host->default_linkset;
char *sep = strchr(arg, '/');
+ char *cic_sep = strchr(arg, ':');
ast_log(LOG_DEBUG, "SS7 request (%s/%s) format = 0x%X.\n", type, arg, format);
@@ -857,16 +879,58 @@
}
if (sep) {
char name_buf[100];
- strncpy(name_buf, arg, sep-arg);
- name_buf[sep-arg] = 0;
+
+ // linkset:cics -> link1:10-21
+ if(cic_sep != NULL) {
+ strncpy(name_buf, arg, cic_sep-arg);
+ name_buf[cic_sep-arg] = 0;
+ }
+ else {
+ strncpy(name_buf, arg, sep-arg);
+ name_buf[sep-arg] = 0;
+ }
+
linkset = lookup_linkset(name_buf);
+
if (!linkset) {
ast_log(LOG_ERROR, "SS7 requester: No such linkset: '%s', using default\n", name_buf);
linkset = this_host->default_linkset;
}
}
lock_global();
- pvt = cic_hunt(linkset);
+
+ // CIC selection via dial parameter
+ // TODO check if cics extracted are numeric before calling atoi()
+ if(cic_sep != NULL) {
+ // use specific cics
+ char cics[100];
+ char first_cic[10], last_cic[10];
+
+ // copy xxx:xxx part
+ strncpy(cics, cic_sep + 1, sep-cic_sep-1);
+ cics[sep-cic_sep] = '\0';
+
+ char *cics_sep = strchr(cics, '-');
+
+ if(cics_sep != NULL) {
+ // copy cic parts
+ strncpy(first_cic, cics, cics_sep-cics);
+ strncpy(last_cic, cics_sep + 1, strlen(cics) - (cics_sep-cics) - 2);
+
+ first_cic[cics_sep-cics] = '\0';
+ last_cic[strlen(cics) - (cics_sep-cics) - 2] = '\0';
+
+ pvt = cic_hunt(linkset, atoi(first_cic), atoi(last_cic));
+ }
+ else {
+ // single CIC
+ int cic = atoi(cics);
+ pvt = cic_hunt(linkset, cic, cic);
+ }
+ }
+ else {
+ pvt = cic_hunt(linkset, linkset->first_cic, linkset->last_cic);
+ }
if(pvt == NULL) {
unlock_global();
@@ -2789,7 +2853,9 @@
t7_clear(pvt);
pvt->owner = NULL;
chan->tech_pvt = NULL;
- newpvt = cic_hunt(pvt->link->linkset);
+ ast_log(LOG_WARNING, "Reattempt call: hunting on all cics\n");
+ // todo: use cics specified in dial parameters
+ newpvt = cic_hunt(pvt->link->linkset, pvt->link->linkset->first_cic, pvt->link->linkset->last_cic);
if (newpvt) {
ast_mutex_lock(&newpvt->lock);
ast_log(LOG_DEBUG, "Reattempt call: Got cic %d\n", newpvt->cic);
--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --
asterisk-ss7 mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/asterisk-ss7