Extract the layer 2 link structure out of struct pri.
This completes the layer 2 link and Q.931 call control restructuring. Some code is now simplified since there is only one D channel control structure and the amount of allocated memory is reduced. git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2077 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
305
pri.c
305
pri.c
@@ -225,7 +225,6 @@ int pri_set_timer(struct pri *ctrl, int timer, int value)
|
||||
if (!ctrl || timer < 0 || PRI_MAX_TIMERS <= timer || value < 0) {
|
||||
return -1;
|
||||
}
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->timers[timer] = value;
|
||||
return 0;
|
||||
}
|
||||
@@ -235,7 +234,6 @@ int pri_get_timer(struct pri *ctrl, int timer)
|
||||
if (!ctrl || timer < 0 || PRI_MAX_TIMERS <= timer) {
|
||||
return -1;
|
||||
}
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
return ctrl->timers[timer];
|
||||
}
|
||||
|
||||
@@ -285,34 +283,150 @@ static int __pri_write(struct pri *pri, void *buf, int buflen)
|
||||
return res;
|
||||
}
|
||||
|
||||
void __pri_free_tei(struct pri * p)
|
||||
/*!
|
||||
* \brief Destroy the given link.
|
||||
*
|
||||
* \param link Q.921 link to destroy.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_link_destroy(struct q921_link *link)
|
||||
{
|
||||
if (p) {
|
||||
if (link) {
|
||||
struct q931_call *call;
|
||||
|
||||
call = p->dummy_call;
|
||||
call = link->dummy_call;
|
||||
if (call) {
|
||||
pri_schedule_del(call->pri, call->retranstimer);
|
||||
call->retranstimer = 0;
|
||||
pri_call_apdu_queue_cleanup(call);
|
||||
}
|
||||
free(p->msg_line);
|
||||
free(p->sched.timer);
|
||||
free(p);
|
||||
free(link);
|
||||
}
|
||||
}
|
||||
|
||||
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri)
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Initialize the layer 2 link structure.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param link Q.921 link to initialize.
|
||||
* \param sapi SAPI new link is to use.
|
||||
* \param tei TEI new link is to use.
|
||||
*
|
||||
* \note It is assumed that the link has already been memset to zero.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void pri_link_init(struct pri *ctrl, struct q921_link *link, int sapi, int tei)
|
||||
{
|
||||
link->ctrl = ctrl;
|
||||
link->sapi = sapi;
|
||||
link->tei = tei;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Create a new layer 2 link.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param sapi SAPI new link is to use.
|
||||
* \param tei TEI new link is to use.
|
||||
*
|
||||
* \retval link on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
struct q921_link *pri_link_new(struct pri *ctrl, int sapi, int tei)
|
||||
{
|
||||
struct link_dummy *dummy_link;
|
||||
struct q921_link *link;
|
||||
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_GR303_EOC:
|
||||
case PRI_SWITCH_GR303_TMC:
|
||||
link = calloc(1, sizeof(*link));
|
||||
if (!link) {
|
||||
return NULL;
|
||||
}
|
||||
dummy_link = NULL;
|
||||
break;
|
||||
default:
|
||||
dummy_link = calloc(1, sizeof(*dummy_link));
|
||||
if (!dummy_link) {
|
||||
return NULL;
|
||||
}
|
||||
link = &dummy_link->link;
|
||||
break;
|
||||
}
|
||||
|
||||
pri_link_init(ctrl, link, sapi, tei);
|
||||
if (dummy_link) {
|
||||
/* Initialize the dummy call reference call record. */
|
||||
link->dummy_call = &dummy_link->dummy_call;
|
||||
q931_init_call_record(link, link->dummy_call, Q931_DUMMY_CALL_REFERENCE);
|
||||
}
|
||||
|
||||
q921_start(link);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Destroy the given D channel controller.
|
||||
*
|
||||
* \param ctrl D channel control to destroy.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void pri_ctrl_destroy(struct pri *ctrl)
|
||||
{
|
||||
if (ctrl) {
|
||||
struct q931_call *call;
|
||||
|
||||
if (ctrl->link.tei == Q921_TEI_GROUP
|
||||
&& ctrl->link.sapi == Q921_SAPI_LAYER2_MANAGEMENT
|
||||
&& ctrl->localtype == PRI_CPE) {
|
||||
/* This dummy call was borrowed from the specific TEI link. */
|
||||
call = NULL;
|
||||
} else {
|
||||
call = ctrl->link.dummy_call;
|
||||
}
|
||||
if (call) {
|
||||
pri_schedule_del(call->pri, call->retranstimer);
|
||||
call->retranstimer = 0;
|
||||
pri_call_apdu_queue_cleanup(call);
|
||||
}
|
||||
free(ctrl->msg_line);
|
||||
free(ctrl->sched.timer);
|
||||
free(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Create a new D channel control structure.
|
||||
*
|
||||
* \param fd D channel file descriptor if no callback functions supplied.
|
||||
* \param node Switch NET/CPE type
|
||||
* \param switchtype ISDN switch type
|
||||
* \param rd D channel read callback function
|
||||
* \param wr D channel write callback function
|
||||
* \param userdata Callback function parameter
|
||||
* \param tei TEI new link is to use.
|
||||
* \param bri TRUE if interface is BRI
|
||||
*
|
||||
* \retval ctrl on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static struct pri *pri_ctrl_new(int fd, int node, int switchtype, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri)
|
||||
{
|
||||
int create_dummy_call;
|
||||
struct d_ctrl_dummy *dummy_ctrl;
|
||||
struct pri *p;
|
||||
struct pri *ctrl;
|
||||
|
||||
switch (switchtype) {
|
||||
case PRI_SWITCH_GR303_EOC:
|
||||
case PRI_SWITCH_GR303_TMC:
|
||||
case PRI_SWITCH_GR303_TMC_SWITCHING:
|
||||
case PRI_SWITCH_GR303_EOC_PATH:
|
||||
create_dummy_call = 0;
|
||||
break;
|
||||
default:
|
||||
@@ -332,96 +446,75 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
if (!dummy_ctrl) {
|
||||
return NULL;
|
||||
}
|
||||
p = &dummy_ctrl->ctrl;
|
||||
ctrl = &dummy_ctrl->ctrl;
|
||||
} else {
|
||||
p = calloc(1, sizeof(*p));
|
||||
if (!p) {
|
||||
ctrl = calloc(1, sizeof(*ctrl));
|
||||
if (!ctrl) {
|
||||
return NULL;
|
||||
}
|
||||
dummy_ctrl = NULL;
|
||||
}
|
||||
if (!master) {
|
||||
/* This is the master record. */
|
||||
p->msg_line = calloc(1, sizeof(*p->msg_line));
|
||||
if (!p->msg_line) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
ctrl->msg_line = calloc(1, sizeof(*ctrl->msg_line));
|
||||
if (!ctrl->msg_line) {
|
||||
free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->bri = bri;
|
||||
p->fd = fd;
|
||||
p->read_func = rd;
|
||||
p->write_func = wr;
|
||||
p->userdata = userdata;
|
||||
p->localtype = node;
|
||||
p->switchtype = switchtype;
|
||||
p->cref = 1;
|
||||
p->sapi = (tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL;
|
||||
p->tei = tei;
|
||||
p->nsf = PRI_NSF_NONE;
|
||||
p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
|
||||
p->master = master;
|
||||
p->callpool = &p->localpool;
|
||||
pri_default_timers(p, switchtype);
|
||||
if (master) {
|
||||
pri_set_debug(p, master->debug);
|
||||
pri_set_inbanddisconnect(p, master->acceptinbanddisconnect);
|
||||
if (master->sendfacility)
|
||||
pri_facility_enable(p);
|
||||
}
|
||||
ctrl->bri = bri;
|
||||
ctrl->fd = fd;
|
||||
ctrl->read_func = rd;
|
||||
ctrl->write_func = wr;
|
||||
ctrl->userdata = userdata;
|
||||
ctrl->localtype = node;
|
||||
ctrl->switchtype = switchtype;
|
||||
ctrl->cref = 1;
|
||||
ctrl->nsf = PRI_NSF_NONE;
|
||||
ctrl->callpool = &ctrl->localpool;
|
||||
pri_default_timers(ctrl, switchtype);
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
p->q921_rxcount = 0;
|
||||
p->q921_txcount = 0;
|
||||
p->q931_rxcount = 0;
|
||||
p->q931_txcount = 0;
|
||||
ctrl->q921_rxcount = 0;
|
||||
ctrl->q921_txcount = 0;
|
||||
ctrl->q931_rxcount = 0;
|
||||
ctrl->q931_txcount = 0;
|
||||
#endif
|
||||
if (dummy_ctrl) {
|
||||
/* Initialize the dummy call reference call record. */
|
||||
dummy_ctrl->ctrl.dummy_call = &dummy_ctrl->dummy_call;
|
||||
q931_init_call_record(&dummy_ctrl->ctrl, dummy_ctrl->ctrl.dummy_call,
|
||||
Q931_DUMMY_CALL_REFERENCE);
|
||||
}
|
||||
switch (switchtype) {
|
||||
case PRI_SWITCH_GR303_EOC:
|
||||
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
p->sapi = Q921_SAPI_GR303_EOC;
|
||||
p->tei = Q921_TEI_GR303_EOC_OPS;
|
||||
p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0);
|
||||
if (!p->subchannel) {
|
||||
free(p);
|
||||
ctrl->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
pri_link_init(ctrl, &ctrl->link, Q921_SAPI_GR303_EOC, Q921_TEI_GR303_EOC_OPS);
|
||||
ctrl->link.next = pri_link_new(ctrl, Q921_SAPI_GR303_EOC, Q921_TEI_GR303_EOC_PATH);
|
||||
if (!ctrl->link.next) {
|
||||
pri_ctrl_destroy(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case PRI_SWITCH_GR303_TMC:
|
||||
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
|
||||
p->tei = Q921_TEI_GR303_TMC_CALLPROC;
|
||||
p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0);
|
||||
if (!p->subchannel) {
|
||||
free(p);
|
||||
ctrl->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
pri_link_init(ctrl, &ctrl->link, Q921_SAPI_GR303_TMC_CALLPROC, Q921_TEI_GR303_TMC_CALLPROC);
|
||||
ctrl->link.next = pri_link_new(ctrl, Q921_SAPI_GR303_TMC_SWITCHING, Q921_TEI_GR303_TMC_SWITCHING);
|
||||
if (!ctrl->link.next) {
|
||||
pri_ctrl_destroy(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case PRI_SWITCH_GR303_TMC_SWITCHING:
|
||||
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
|
||||
p->tei = Q921_TEI_GR303_TMC_SWITCHING;
|
||||
break;
|
||||
case PRI_SWITCH_GR303_EOC_PATH:
|
||||
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
p->sapi = Q921_SAPI_GR303_EOC;
|
||||
p->tei = Q921_TEI_GR303_EOC_PATH;
|
||||
break;
|
||||
default:
|
||||
ctrl->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
|
||||
pri_link_init(ctrl, &ctrl->link,
|
||||
(tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL,
|
||||
tei);
|
||||
break;
|
||||
}
|
||||
if (dummy_ctrl) {
|
||||
/* Initialize the dummy call reference call record. */
|
||||
ctrl->link.dummy_call = &dummy_ctrl->dummy_call;
|
||||
q931_init_call_record(&ctrl->link, ctrl->link.dummy_call,
|
||||
Q931_DUMMY_CALL_REFERENCE);
|
||||
}
|
||||
|
||||
if (p->tei == Q921_TEI_GROUP && p->sapi == Q921_SAPI_LAYER2_MANAGEMENT
|
||||
&& p->localtype == PRI_CPE) {
|
||||
p->subchannel = __pri_new_tei(-1, p->localtype, p->switchtype, p, NULL, NULL, NULL, Q921_TEI_PRI, 1);
|
||||
if (!p->subchannel) {
|
||||
free(p);
|
||||
if (ctrl->link.tei == Q921_TEI_GROUP && ctrl->link.sapi == Q921_SAPI_LAYER2_MANAGEMENT
|
||||
&& ctrl->localtype == PRI_CPE) {
|
||||
ctrl->link.next = pri_link_new(ctrl, Q921_SAPI_CALL_CTRL, Q921_TEI_PRI);
|
||||
if (!ctrl->link.next) {
|
||||
pri_ctrl_destroy(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
@@ -430,11 +523,12 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
* to broadcast messages on the dummy call or to broadcast any
|
||||
* messages for that matter.
|
||||
*/
|
||||
p->dummy_call = p->subchannel->dummy_call;
|
||||
} else
|
||||
q921_start(p);
|
||||
|
||||
return p;
|
||||
ctrl->link.dummy_call = ctrl->link.next->dummy_call;
|
||||
} else {
|
||||
q921_start(&ctrl->link);
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
void pri_call_set_useruser(q931_call *c, const char *userchars)
|
||||
@@ -470,15 +564,15 @@ int pri_restart(struct pri *pri)
|
||||
|
||||
struct pri *pri_new(int fd, int nodetype, int switchtype)
|
||||
{
|
||||
return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0);
|
||||
return pri_ctrl_new(fd, nodetype, switchtype, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0);
|
||||
}
|
||||
|
||||
struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype)
|
||||
{
|
||||
if (ptpmode)
|
||||
return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1);
|
||||
return pri_ctrl_new(fd, nodetype, switchtype, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1);
|
||||
else
|
||||
return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1);
|
||||
return pri_ctrl_new(fd, nodetype, switchtype, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1);
|
||||
}
|
||||
|
||||
struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
|
||||
@@ -487,7 +581,7 @@ struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read,
|
||||
io_read = __pri_read;
|
||||
if (!io_write)
|
||||
io_write = __pri_write;
|
||||
return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 0);
|
||||
return pri_ctrl_new(fd, nodetype, switchtype, io_read, io_write, userdata, Q921_TEI_PRI, 0);
|
||||
}
|
||||
|
||||
struct pri *pri_new_bri_cb(int fd, int ptpmode, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
|
||||
@@ -499,9 +593,9 @@ struct pri *pri_new_bri_cb(int fd, int ptpmode, int nodetype, int switchtype, pr
|
||||
io_write = __pri_write;
|
||||
}
|
||||
if (ptpmode) {
|
||||
return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 1);
|
||||
return pri_ctrl_new(fd, nodetype, switchtype, io_read, io_write, userdata, Q921_TEI_PRI, 1);
|
||||
} else {
|
||||
return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_GROUP, 1);
|
||||
return pri_ctrl_new(fd, nodetype, switchtype, io_read, io_write, userdata, Q921_TEI_GROUP, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,16 +741,12 @@ void pri_set_debug(struct pri *pri, int debug)
|
||||
if (!pri)
|
||||
return;
|
||||
pri->debug = debug;
|
||||
if (pri->subchannel)
|
||||
pri_set_debug(pri->subchannel, debug);
|
||||
}
|
||||
|
||||
int pri_get_debug(struct pri *pri)
|
||||
{
|
||||
if (!pri)
|
||||
return -1;
|
||||
if (pri->subchannel)
|
||||
return pri_get_debug(pri->subchannel);
|
||||
return pri->debug;
|
||||
}
|
||||
|
||||
@@ -665,9 +755,6 @@ void pri_facility_enable(struct pri *pri)
|
||||
if (!pri)
|
||||
return;
|
||||
pri->sendfacility = 1;
|
||||
if (pri->subchannel)
|
||||
pri_facility_enable(pri->subchannel);
|
||||
return;
|
||||
}
|
||||
|
||||
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
|
||||
@@ -763,7 +850,6 @@ int pri_connect_ack(struct pri *ctrl, q931_call *call, int channel)
|
||||
void pri_connect_ack_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->manual_connect_ack = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1162,7 +1248,6 @@ int pri_channel_bridge(q931_call *call1, q931_call *call2)
|
||||
void pri_hangup_fix_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->hangup_fix_enabled = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1348,9 +1433,6 @@ void pri_message(struct pri *ctrl, const char *fmt, ...)
|
||||
int added_length;
|
||||
va_list ap;
|
||||
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
}
|
||||
if (!ctrl || !ctrl->msg_line) {
|
||||
/* Just have to do it the old way. */
|
||||
va_start(ap, fmt);
|
||||
@@ -1412,7 +1494,7 @@ void pri_error(struct pri *pri, const char *fmt, ...)
|
||||
vsnprintf(tmp, sizeof(tmp), fmt, ap);
|
||||
va_end(ap);
|
||||
if (__pri_error)
|
||||
__pri_error(pri ? PRI_MASTER(pri) : NULL, tmp);
|
||||
__pri_error(pri, tmp);
|
||||
else
|
||||
fputs(tmp, stderr);
|
||||
}
|
||||
@@ -1478,7 +1560,7 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
size_t used;
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
struct q921_frame *f;
|
||||
struct pri *link;
|
||||
struct q921_link *link;
|
||||
unsigned q921outstanding;
|
||||
#endif
|
||||
unsigned idx;
|
||||
@@ -1494,8 +1576,6 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
/* Might be nice to format these a little better */
|
||||
used = 0;
|
||||
used = pri_snprintf(buf, used, buf_size, "Switchtype: %s\n",
|
||||
@@ -1507,9 +1587,9 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
used = pri_snprintf(buf, used, buf_size, "Q931 TX: %d\n", ctrl->q931_txcount);
|
||||
used = pri_snprintf(buf, used, buf_size, "Q921 RX: %d\n", ctrl->q921_rxcount);
|
||||
used = pri_snprintf(buf, used, buf_size, "Q921 TX: %d\n", ctrl->q921_txcount);
|
||||
for (link = ctrl; link; link = link->subchannel) {
|
||||
for (link = &ctrl->link; link; link = link->next) {
|
||||
q921outstanding = 0;
|
||||
for (f = link->txqueue; f; f = f->next) {
|
||||
for (f = link->tx_queue; f; f = f->next) {
|
||||
++q921outstanding;
|
||||
}
|
||||
used = pri_snprintf(buf, used, buf_size, "Q921 Outstanding: %u (TEI=%d)\n",
|
||||
@@ -1702,7 +1782,6 @@ void pri_sr_set_keypad_digits(struct pri_sr *sr, const char *keypad_digits)
|
||||
void pri_transfer_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->transfer_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1710,7 +1789,6 @@ void pri_transfer_enable(struct pri *ctrl, int enable)
|
||||
void pri_hold_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->hold_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1775,7 +1853,6 @@ int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *des
|
||||
void pri_reroute_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->deflection_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1827,7 +1904,6 @@ int pri_reroute_call(struct pri *ctrl, q931_call *call, const struct pri_party_i
|
||||
void pri_cc_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1835,7 +1911,6 @@ void pri_cc_enable(struct pri *ctrl, int enable)
|
||||
void pri_cc_recall_mode(struct pri *ctrl, int mode)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.option.recall_mode = mode ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -1843,7 +1918,6 @@ void pri_cc_recall_mode(struct pri *ctrl, int mode)
|
||||
void pri_cc_retain_signaling_req(struct pri *ctrl, int signaling_retention)
|
||||
{
|
||||
if (ctrl && 0 <= signaling_retention && signaling_retention < 3) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.option.signaling_retention_req = signaling_retention;
|
||||
}
|
||||
}
|
||||
@@ -1851,7 +1925,6 @@ void pri_cc_retain_signaling_req(struct pri *ctrl, int signaling_retention)
|
||||
void pri_cc_retain_signaling_rsp(struct pri *ctrl, int signaling_retention)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.option.signaling_retention_rsp = signaling_retention ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
15
pri_aoc.c
15
pri_aoc.c
@@ -212,7 +212,7 @@ void aoc_etsi_aoc_request(struct pri *ctrl, q931_call *call, const struct rose_m
|
||||
struct pri_subcommand *subcmd;
|
||||
int request;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id, ROSE_ERROR_Gen_NotSubscribed);
|
||||
return;
|
||||
}
|
||||
@@ -439,7 +439,7 @@ void aoc_etsi_aoc_s_currency(struct pri *ctrl, const struct rose_msg_invoke *inv
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -470,7 +470,7 @@ void aoc_etsi_aoc_s_special_arrangement(struct pri *ctrl, const struct rose_msg_
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -535,7 +535,7 @@ void aoc_etsi_aoc_d_currency(struct pri *ctrl, const struct rose_msg_invoke *inv
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -577,7 +577,7 @@ void aoc_etsi_aoc_d_charging_unit(struct pri *ctrl, const struct rose_msg_invoke
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -760,7 +760,7 @@ void aoc_etsi_aoc_e_currency(struct pri *ctrl, q931_call *call, const struct ros
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -828,7 +828,7 @@ void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struc
|
||||
}
|
||||
}
|
||||
|
||||
if (!PRI_MASTER(ctrl)->aoc_support) {
|
||||
if (!ctrl->aoc_support) {
|
||||
return;
|
||||
}
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
@@ -869,7 +869,6 @@ void aoc_etsi_aoc_e_charging_unit(struct pri *ctrl, q931_call *call, const struc
|
||||
void pri_aoc_events_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->aoc_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
51
pri_cc.c
51
pri_cc.c
@@ -61,7 +61,6 @@ struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned refere
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->ccbs_reference_id == reference_id) {
|
||||
/* Found the record */
|
||||
@@ -85,7 +84,6 @@ struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->call_linkage_id == linkage_id) {
|
||||
/* Found the record */
|
||||
@@ -110,7 +108,6 @@ static struct pri_cc_record *pri_cc_find_by_id(struct pri *ctrl, long cc_id)
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->record_id == cc_id) {
|
||||
/* Found the record */
|
||||
@@ -234,7 +231,6 @@ struct pri_cc_record *pri_cc_find_by_addressing(struct pri *ctrl, const struct q
|
||||
struct q931_party_address addr_a;
|
||||
struct q931_party_address addr_b;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
addr_a = *party_a;
|
||||
addr_b = *party_b;
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
@@ -266,7 +262,6 @@ static int pri_cc_new_reference_id(struct pri *ctrl)
|
||||
long reference_id;
|
||||
long first_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.last_reference_id = (ctrl->cc.last_reference_id + 1) & 0x7F;
|
||||
reference_id = ctrl->cc.last_reference_id;
|
||||
first_id = reference_id;
|
||||
@@ -298,7 +293,6 @@ static int pri_cc_new_linkage_id(struct pri *ctrl)
|
||||
long linkage_id;
|
||||
long first_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->cc.last_linkage_id = (ctrl->cc.last_linkage_id + 1) & 0x7F;
|
||||
linkage_id = ctrl->cc.last_linkage_id;
|
||||
first_id = linkage_id;
|
||||
@@ -330,7 +324,6 @@ static long pri_cc_new_id(struct pri *ctrl)
|
||||
long record_id;
|
||||
long first_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
record_id = ++ctrl->cc.last_record_id;
|
||||
first_id = record_id;
|
||||
while (pri_cc_find_by_id(ctrl, record_id)) {
|
||||
@@ -386,7 +379,6 @@ static void pri_cc_delete_record(struct pri *ctrl, struct pri_cc_record *doomed)
|
||||
}
|
||||
pri_cc_disassociate_signaling_link(doomed);
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
for (prev = &ctrl->cc.pool, current = ctrl->cc.pool; current;
|
||||
prev = ¤t->next, current = current->next) {
|
||||
if (current == doomed) {
|
||||
@@ -413,7 +405,6 @@ struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
|
||||
struct pri_cc_record *cc_record;
|
||||
long record_id;
|
||||
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
record_id = pri_cc_new_id(ctrl);
|
||||
if (record_id < 0) {
|
||||
return NULL;
|
||||
@@ -424,7 +415,7 @@ struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
|
||||
}
|
||||
|
||||
/* Initialize the new record */
|
||||
cc_record->master = ctrl;
|
||||
cc_record->ctrl = ctrl;
|
||||
cc_record->record_id = record_id;
|
||||
cc_record->call_linkage_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
|
||||
cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
|
||||
@@ -975,7 +966,7 @@ static unsigned char *enc_qsig_cc_request(struct pri *ctrl,
|
||||
|
||||
//msg.args.qsig.CcbsRequest.can_retain_service = 0;
|
||||
|
||||
switch (PRI_MASTER(ctrl)->cc.option.signaling_retention_req) {
|
||||
switch (ctrl->cc.option.signaling_retention_req) {
|
||||
case 0:/* Want release signaling link. */
|
||||
cc_record->option.retain_signaling_link = 0;
|
||||
|
||||
@@ -1954,7 +1945,6 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
|
||||
struct q931_party_number party_a_number;
|
||||
const struct pri_cc_record *cc_record;
|
||||
unsigned char *new_pos;
|
||||
struct pri *master;
|
||||
unsigned idx;
|
||||
|
||||
pos = facility_encode_header(ctrl, pos, end, NULL);
|
||||
@@ -1966,8 +1956,7 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
|
||||
msg.invoke_id = invoke->invoke_id;
|
||||
msg.operation = invoke->operation;
|
||||
|
||||
master = PRI_MASTER(ctrl);
|
||||
msg.args.etsi.CCBSInterrogate.recall_mode = master->cc.option.recall_mode;
|
||||
msg.args.etsi.CCBSInterrogate.recall_mode = ctrl->cc.option.recall_mode;
|
||||
|
||||
/* Convert the given party A number. */
|
||||
q931_party_number_init(&party_a_number);
|
||||
@@ -1979,7 +1968,7 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
|
||||
|
||||
/* Build the CallDetails list. */
|
||||
idx = 0;
|
||||
for (cc_record = master->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
|
||||
if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID
|
||||
|| (!cc_record->is_ccnr) != (invoke->operation == ROSE_ETSI_CCBSInterrogate)) {
|
||||
/*
|
||||
@@ -2087,7 +2076,7 @@ int pri_cc_interrogate_rsp(struct pri *ctrl, q931_call *call, const struct rose_
|
||||
{
|
||||
int encode_result;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
return send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
@@ -2134,7 +2123,7 @@ void pri_cc_ptmp_request(struct pri *ctrl, q931_call *call, const struct rose_ms
|
||||
{
|
||||
struct pri_cc_record *cc_record;
|
||||
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
@@ -2191,7 +2180,7 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
|
||||
/* Ignore CC request message since it did not come in on the correct message. */
|
||||
return;
|
||||
}
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
@@ -2270,7 +2259,6 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
|
||||
*/
|
||||
void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
|
||||
{
|
||||
struct pri *master;
|
||||
struct pri_cc_record *cc_record;
|
||||
struct q931_party_address party_a;
|
||||
struct q931_party_address party_b;
|
||||
@@ -2279,8 +2267,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
|
||||
/* Ignore CC request message since it did not come in on the correct message. */
|
||||
return;
|
||||
}
|
||||
master = PRI_MASTER(ctrl);
|
||||
if (!master->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/* Call completion is disabled. */
|
||||
rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
|
||||
ROSE_ERROR_QSIG_LongTermRejection);
|
||||
@@ -2302,7 +2289,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
|
||||
rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
|
||||
&invoke->args.qsig.CcbsRequest.subaddr_b);
|
||||
|
||||
cc_record = pri_cc_find_by_addressing(master, &party_a, &party_b,
|
||||
cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
|
||||
invoke->args.qsig.CcbsRequest.q931ie.length,
|
||||
invoke->args.qsig.CcbsRequest.q931ie.contents);
|
||||
if (!cc_record || cc_record->state != CC_STATE_AVAILABLE) {
|
||||
@@ -2321,7 +2308,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
|
||||
} else {
|
||||
/* The originator does not care. Do how we are configured. */
|
||||
cc_record->option.retain_signaling_link =
|
||||
master->cc.option.signaling_retention_rsp;
|
||||
ctrl->cc.option.signaling_retention_rsp;
|
||||
}
|
||||
if (!cc_record->party_a.number.valid || cc_record->party_a.number.str[0] == '\0') {
|
||||
/*
|
||||
@@ -2805,7 +2792,7 @@ static void pri_cc_timeout_t_retention(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_retention = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2857,7 +2844,7 @@ static void pri_cc_timeout_extended_t_ccbs1(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2911,7 +2898,7 @@ static void pri_cc_timeout_t_supervision(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_supervision = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2991,7 +2978,7 @@ static void pri_cc_timeout_t_recall(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_recall = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -3755,7 +3742,7 @@ static void pri_cc_indirect_status_rsp_a(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_indirect = 0;
|
||||
q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_rsp_a);
|
||||
q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_rsp_a);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -3904,7 +3891,7 @@ static void pri_cc_indirect_status_a(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_indirect = 0;
|
||||
q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_a);
|
||||
q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_a);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -4261,7 +4248,7 @@ static void pri_cc_post_hangup_signaling(void *data)
|
||||
struct pri_cc_record *cc_record = data;
|
||||
|
||||
cc_record->t_indirect = 0;
|
||||
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_HANGUP_SIGNALING);
|
||||
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_HANGUP_SIGNALING);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -6850,7 +6837,7 @@ long pri_cc_available(struct pri *ctrl, q931_call *call)
|
||||
break;
|
||||
}
|
||||
cc_record->call_linkage_id = linkage_id;
|
||||
cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
|
||||
cc_record->signaling = ctrl->link.dummy_call;
|
||||
} else {
|
||||
cc_record = pri_cc_new_record(ctrl, call);
|
||||
if (!cc_record) {
|
||||
@@ -6894,7 +6881,7 @@ void pri_cc_qsig_determine_available(struct pri *ctrl, q931_call *call)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/*
|
||||
* Blocking the cc-available event effectively
|
||||
* disables call completion for outgoing calls.
|
||||
|
||||
@@ -1859,7 +1859,7 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
|
||||
if (!BRI_NT_PTMP(ctrl)) {
|
||||
return -1;
|
||||
}
|
||||
call = PRI_MASTER(ctrl)->dummy_call;
|
||||
call = ctrl->link.dummy_call;
|
||||
if (!call) {
|
||||
return -1;
|
||||
}
|
||||
@@ -3825,7 +3825,6 @@ int pri_mcid_req_send(struct pri *ctrl, q931_call *call)
|
||||
void pri_mcid_enable(struct pri *ctrl, int enable)
|
||||
{
|
||||
if (ctrl) {
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl->mcid_support = enable ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -3882,7 +3881,7 @@ void rose_handle_reject(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
* Look for the original invocation message on the
|
||||
* broadcast dummy call reference call first.
|
||||
*/
|
||||
orig_call = PRI_MASTER(ctrl)->dummy_call;
|
||||
orig_call = ctrl->link.dummy_call;
|
||||
if (orig_call) {
|
||||
apdu = pri_call_apdu_find(orig_call, reject->invoke_id);
|
||||
}
|
||||
@@ -3966,7 +3965,7 @@ void rose_handle_error(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *
|
||||
* Look for the original invocation message on the
|
||||
* broadcast dummy call reference call first.
|
||||
*/
|
||||
orig_call = PRI_MASTER(ctrl)->dummy_call;
|
||||
orig_call = ctrl->link.dummy_call;
|
||||
if (orig_call) {
|
||||
apdu = pri_call_apdu_find(orig_call, error->invoke_id);
|
||||
}
|
||||
@@ -4042,7 +4041,7 @@ void rose_handle_result(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
* Look for the original invocation message on the
|
||||
* broadcast dummy call reference call first.
|
||||
*/
|
||||
orig_call = PRI_MASTER(ctrl)->dummy_call;
|
||||
orig_call = ctrl->link.dummy_call;
|
||||
if (orig_call) {
|
||||
apdu = pri_call_apdu_find(orig_call, result->invoke_id);
|
||||
}
|
||||
@@ -4099,7 +4098,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_CallDeflection:
|
||||
if (!PRI_MASTER(ctrl)->deflection_support) {
|
||||
if (!ctrl->deflection_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4167,7 +4166,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
&deflection);
|
||||
break;
|
||||
case ROSE_ETSI_CallRerouting:
|
||||
if (!PRI_MASTER(ctrl)->deflection_support) {
|
||||
if (!ctrl->deflection_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4365,7 +4364,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_EctExecute:
|
||||
if (!PRI_MASTER(ctrl)->transfer_support) {
|
||||
if (!ctrl->transfer_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4390,7 +4389,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_EctLinkIdRequest:
|
||||
if (!PRI_MASTER(ctrl)->transfer_support) {
|
||||
if (!ctrl->transfer_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_ResourceUnavailable);
|
||||
break;
|
||||
@@ -4430,7 +4429,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
|
||||
case ROSE_ETSI_CallInfoRetain:
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/*
|
||||
* Blocking the cc-available event effectively
|
||||
* disables call completion for outgoing calls.
|
||||
@@ -4445,7 +4444,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
if (!cc_record) {
|
||||
break;
|
||||
}
|
||||
cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
|
||||
cc_record->signaling = ctrl->link.dummy_call;
|
||||
/*
|
||||
* Since we received this facility, we will not be allocating any
|
||||
* reference and linkage id's.
|
||||
@@ -4645,7 +4644,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
pri_cc_event(ctrl, call, cc_record, CC_EVENT_REMOTE_USER_FREE);
|
||||
break;
|
||||
case ROSE_ETSI_CCBS_T_Available:
|
||||
if (!PRI_MASTER(ctrl)->cc_support) {
|
||||
if (!ctrl->cc_support) {
|
||||
/*
|
||||
* Blocking the cc-available event effectively
|
||||
* disables call completion for outgoing calls.
|
||||
@@ -4669,7 +4668,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
/* Don't even dignify this with a response. */
|
||||
break;
|
||||
}
|
||||
if (!PRI_MASTER(ctrl)->mcid_support) {
|
||||
if (!ctrl->mcid_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
@@ -4877,7 +4876,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_CallRerouting:
|
||||
if (!PRI_MASTER(ctrl)->deflection_support) {
|
||||
if (!ctrl->deflection_support) {
|
||||
send_facility_error(ctrl, call, invoke->invoke_id,
|
||||
ROSE_ERROR_Gen_NotSubscribed);
|
||||
break;
|
||||
|
||||
113
pri_internal.h
113
pri_internal.h
@@ -76,8 +76,6 @@ struct pri {
|
||||
void *userdata;
|
||||
/*! Accumulated pri_message() line. (Valid in master record only) */
|
||||
struct pri_msg_line *msg_line;
|
||||
struct pri *subchannel; /* Sub-channel if appropriate */
|
||||
struct pri *master; /* Master channel if appropriate */
|
||||
struct {
|
||||
/*! Dynamically allocated array of timers that can grow as needed. */
|
||||
struct pri_sched *timer;
|
||||
@@ -93,9 +91,8 @@ struct pri {
|
||||
int localtype; /* Local network type (unknown, network, cpe) */
|
||||
int remotetype; /* Remote network type (unknown, network, cpe) */
|
||||
|
||||
int sapi;
|
||||
int tei;
|
||||
int protodisc;
|
||||
int protodisc; /* Layer 3 protocol discriminator */
|
||||
|
||||
unsigned int nfas:1;/* TRUE if this D channel is involved with an NFAS group */
|
||||
unsigned int bri:1;
|
||||
unsigned int acceptinbanddisconnect:1; /* Should we allow inband progress after DISCONNECT? */
|
||||
@@ -112,57 +109,23 @@ struct pri {
|
||||
unsigned int manual_connect_ack:1;/* TRUE if the CONNECT_ACKNOWLEDGE is sent with API call */
|
||||
unsigned int mcid_support:1;/* TRUE if the upper layer supports MCID */
|
||||
|
||||
/* MDL variables */
|
||||
int mdl_error;
|
||||
int mdl_error_state;
|
||||
int mdl_timer;
|
||||
int mdl_free_me;
|
||||
|
||||
/* Q.921 State */
|
||||
int q921_state;
|
||||
int RC;
|
||||
int peer_rx_busy:1;
|
||||
int own_rx_busy:1;
|
||||
int acknowledge_pending:1;
|
||||
int reject_exception:1;
|
||||
|
||||
int v_s; /* Next N(S) for transmission */
|
||||
int v_a; /* Last acknowledged frame */
|
||||
int v_r; /* Next frame expected to be received */
|
||||
/*! Layer 2 link control for D channel. */
|
||||
struct q921_link link;
|
||||
|
||||
int cref; /* Next call reference value */
|
||||
|
||||
int l3initiated;
|
||||
|
||||
/* Various timers */
|
||||
int t203_timer; /* Max idle time */
|
||||
int t202_timer;
|
||||
int n202_counter;
|
||||
int ri;
|
||||
int t200_timer; /* T-200 retransmission timer */
|
||||
/* All ISDN Timer values */
|
||||
int timers[PRI_MAX_TIMERS];
|
||||
|
||||
/* Used by scheduler */
|
||||
struct timeval tv;
|
||||
int schedev;
|
||||
pri_event ev; /* Static event thingy */
|
||||
/*! Subcommands for static event thingy. */
|
||||
struct pri_subcommands subcmds;
|
||||
|
||||
/* Q.921 Re-transmission queue */
|
||||
struct q921_frame *txqueue;
|
||||
|
||||
/* Q.931 calls */
|
||||
q931_call **callpool;
|
||||
q931_call *localpool;
|
||||
|
||||
/*!
|
||||
* \brief Q.931 Dummy call reference call associated with this TEI.
|
||||
* \note If present then this call is allocated as part of the
|
||||
* D channel control structure.
|
||||
*/
|
||||
q931_call *dummy_call;
|
||||
struct q931_call **callpool;
|
||||
struct q931_call *localpool;
|
||||
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
/* q921/q931 packet counters */
|
||||
@@ -370,10 +333,6 @@ struct pri_sr {
|
||||
int aoc_charging_request;
|
||||
};
|
||||
|
||||
/* Internal switch types */
|
||||
#define PRI_SWITCH_GR303_EOC_PATH 19
|
||||
#define PRI_SWITCH_GR303_TMC_SWITCHING 20
|
||||
|
||||
#define Q931_MAX_TEI 8
|
||||
|
||||
/*! \brief Incoming call transfer states. */
|
||||
@@ -449,7 +408,7 @@ struct decoded_bc {
|
||||
/* q931_call datastructure */
|
||||
struct q931_call {
|
||||
struct pri *pri; /* D channel controller (master) */
|
||||
struct pri *link; /* Q.921 link associated with this call. */
|
||||
struct q921_link *link; /* Q.921 link associated with this call. */
|
||||
struct q931_call *next;
|
||||
int cr; /* Call Reference */
|
||||
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
|
||||
@@ -592,7 +551,7 @@ struct q931_call {
|
||||
int is_link_id_valid;
|
||||
|
||||
/* Bridged call info */
|
||||
q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
|
||||
struct q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
|
||||
|
||||
int changestatus; /* SERVICE message changestatus */
|
||||
int reversecharge; /* Reverse charging indication:
|
||||
@@ -746,8 +705,8 @@ enum CC_PARTY_A_AVAILABILITY {
|
||||
struct pri_cc_record {
|
||||
/*! Next call-completion record in the list */
|
||||
struct pri_cc_record *next;
|
||||
/*! Master D channel control structure. */
|
||||
struct pri *master;
|
||||
/*! D channel control structure. */
|
||||
struct pri *ctrl;
|
||||
/*! Original call that is offered CC availability. (NULL if no longer exists.) */
|
||||
struct q931_call *original_call;
|
||||
/*!
|
||||
@@ -883,6 +842,14 @@ struct d_ctrl_dummy {
|
||||
struct q931_call dummy_call;
|
||||
};
|
||||
|
||||
/*! Layer 2 link control structure with associated dummy call reference record. */
|
||||
struct link_dummy {
|
||||
/*! Layer 2 control structure. Must be first in the structure. */
|
||||
struct q921_link link;
|
||||
/*! Dummy call reference call record. */
|
||||
struct q931_call dummy_call;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Check if the given call ptr is valid and gripe if not.
|
||||
*
|
||||
@@ -912,10 +879,10 @@ void pri_error(struct pri *ctrl, const char *fmt, ...) __attribute__((format(pri
|
||||
|
||||
void libpri_copy_string(char *dst, const char *src, size_t size);
|
||||
|
||||
struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri);
|
||||
void __pri_free_tei(struct pri *p);
|
||||
void pri_link_destroy(struct q921_link *link);
|
||||
struct q921_link *pri_link_new(struct pri *ctrl, int sapi, int tei);
|
||||
|
||||
void q931_init_call_record(struct pri *link, struct q931_call *call, int cr);
|
||||
void q931_init_call_record(struct q921_link *link, struct q931_call *call, int cr);
|
||||
|
||||
void pri_sr_init(struct pri_sr *req);
|
||||
|
||||
@@ -984,21 +951,6 @@ int pri_cc_event(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_rec
|
||||
int q931_cc_timeout(struct pri *ctrl, struct pri_cc_record *cc_record, enum CC_EVENTS event);
|
||||
void q931_cc_indirect(struct pri *ctrl, struct pri_cc_record *cc_record, void (*func)(struct pri *ctrl, q931_call *call, struct pri_cc_record *cc_record));
|
||||
|
||||
/*!
|
||||
* \brief Get the master PRI control structure.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Master PRI control structure.
|
||||
*/
|
||||
static inline struct pri *PRI_MASTER(struct pri *ctrl)
|
||||
{
|
||||
while (ctrl->master) {
|
||||
ctrl = ctrl->master;
|
||||
}
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Determine if layer 2 is in BRI NT PTMP mode.
|
||||
*
|
||||
@@ -1011,10 +963,8 @@ static inline int BRI_NT_PTMP(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->bri && my_ctrl->localtype == PRI_NETWORK
|
||||
&& my_ctrl->tei == Q921_TEI_GROUP;
|
||||
&& my_ctrl->link.tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1029,10 +979,8 @@ static inline int BRI_TE_PTMP(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->bri && my_ctrl->localtype == PRI_CPE
|
||||
&& my_ctrl->tei == Q921_TEI_GROUP;
|
||||
&& my_ctrl->link.tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1047,8 +995,6 @@ static inline int NT_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->localtype == PRI_NETWORK;
|
||||
}
|
||||
|
||||
@@ -1064,8 +1010,6 @@ static inline int TE_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->localtype == PRI_CPE;
|
||||
}
|
||||
|
||||
@@ -1081,9 +1025,7 @@ static inline int PTP_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->tei == Q921_TEI_PRI;
|
||||
return my_ctrl->link.tei == Q921_TEI_PRI;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1098,9 +1040,7 @@ static inline int PTMP_MODE(const struct pri *ctrl)
|
||||
{
|
||||
struct pri *my_ctrl = (struct pri *) ctrl;
|
||||
|
||||
/* Check master control structure */
|
||||
my_ctrl = PRI_MASTER(my_ctrl);
|
||||
return my_ctrl->tei == Q921_TEI_GROUP;
|
||||
return my_ctrl->link.tei == Q921_TEI_GROUP;
|
||||
}
|
||||
|
||||
#define Q931_DUMMY_CALL_REFERENCE -1
|
||||
@@ -1112,14 +1052,13 @@ static inline int PTMP_MODE(const struct pri *ctrl)
|
||||
* \retval TRUE if given call is a dummy call.
|
||||
* \retval FALSE otherwise.
|
||||
*/
|
||||
static inline int q931_is_dummy_call(const q931_call *call)
|
||||
static inline int q931_is_dummy_call(const struct q931_call *call)
|
||||
{
|
||||
return (call->cr == Q931_DUMMY_CALL_REFERENCE) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline short get_invokeid(struct pri *ctrl)
|
||||
{
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
return ++ctrl->last_invoke;
|
||||
}
|
||||
|
||||
|
||||
66
pri_q921.h
66
pri_q921.h
@@ -180,6 +180,66 @@ typedef enum q921_state {
|
||||
Q921_TIMER_RECOVERY = 8,
|
||||
} q921_state;
|
||||
|
||||
/*! \brief Q.921 link controller structure */
|
||||
struct q921_link {
|
||||
/*! Next Q.921 link in the chain. */
|
||||
struct q921_link *next;
|
||||
/*! D channel controller associated with this link. */
|
||||
struct pri *ctrl;
|
||||
|
||||
/*!
|
||||
* \brief Q.931 Dummy call reference call associated with this TEI.
|
||||
*
|
||||
* \note If present then this call is allocated with the D
|
||||
* channel control structure or the link control structure
|
||||
* unless this is the TE PTMP broadcast TEI or a GR303 link.
|
||||
*/
|
||||
struct q931_call *dummy_call;
|
||||
|
||||
/*! Q.921 Re-transmission queue */
|
||||
struct q921_frame *tx_queue;
|
||||
|
||||
/*! Q.921 State */
|
||||
enum q921_state state;
|
||||
|
||||
/*! Service Access Profile Identifier (SAPI) of this link */
|
||||
int sapi;
|
||||
/*! Terminal Endpoint Identifier (TEI) of this link */
|
||||
int tei;
|
||||
/*! TEI assignment random indicator. */
|
||||
int ri;
|
||||
|
||||
/*! V(A) - Next I-frame sequence number needing ack */
|
||||
int v_a;
|
||||
/*! V(S) - Next I-frame sequence number to send */
|
||||
int v_s;
|
||||
/*! V(R) - Next I-frame sequence number expected to receive */
|
||||
int v_r;
|
||||
|
||||
/* Various timers */
|
||||
|
||||
/*! T-200 retransmission timer */
|
||||
int t200_timer;
|
||||
/*! Retry Count (T200) */
|
||||
int RC;
|
||||
int t202_timer;
|
||||
int n202_counter;
|
||||
/*! Max idle time */
|
||||
int t203_timer;
|
||||
|
||||
/* MDL variables */
|
||||
int mdl_timer;
|
||||
int mdl_error;
|
||||
enum q921_state mdl_error_state;
|
||||
unsigned int mdl_free_me:1;
|
||||
|
||||
unsigned int peer_rx_busy:1;
|
||||
unsigned int own_rx_busy:1;
|
||||
unsigned int acknowledge_pending:1;
|
||||
unsigned int reject_exception:1;
|
||||
unsigned int l3_initiated:1;
|
||||
};
|
||||
|
||||
static inline int Q921_ADD(int a, int b)
|
||||
{
|
||||
return (a + b) % 128;
|
||||
@@ -189,15 +249,15 @@ static inline int Q921_ADD(int a, int b)
|
||||
extern void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx);
|
||||
|
||||
/* Bring up the D-channel */
|
||||
void q921_start(struct pri *link);
|
||||
void q921_start(struct q921_link *link);
|
||||
|
||||
//extern void q921_reset(struct pri *pri, int reset_iqueue);
|
||||
|
||||
extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
|
||||
|
||||
int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr);
|
||||
int q921_transmit_iframe(struct q921_link *link, void *buf, int len, int cr);
|
||||
|
||||
int q921_transmit_uiframe(struct pri *link, void *buf, int len);
|
||||
int q921_transmit_uiframe(struct q921_link *link, void *buf, int len);
|
||||
|
||||
extern pri_event *q921_dchannel_up(struct pri *pri);
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ extern int maintenance_service(struct pri *pri, int span, int channel, int chang
|
||||
/* Q.SIG specific */
|
||||
#define QSIG_IE_TRANSIT_COUNT 0x31
|
||||
|
||||
int q931_receive(struct pri *link, q931_h *h, int len);
|
||||
int q931_receive(struct q921_link *link, q931_h *h, int len);
|
||||
|
||||
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
||||
|
||||
@@ -507,7 +507,7 @@ enum Q931_DL_EVENT {
|
||||
Q931_DL_EVENT_DL_RELEASE_CONFIRM,
|
||||
Q931_DL_EVENT_TEI_REMOVAL,
|
||||
};
|
||||
void q931_dl_event(struct pri *link, enum Q931_DL_EVENT event);
|
||||
void q931_dl_event(struct q921_link *link, enum Q931_DL_EVENT event);
|
||||
|
||||
int q931_send_hold(struct pri *ctrl, struct q931_call *call);
|
||||
int q931_send_hold_ack(struct pri *ctrl, struct q931_call *call);
|
||||
|
||||
15
prisched.c
15
prisched.c
@@ -112,9 +112,6 @@ int pri_schedule_event(struct pri *ctrl, int ms, void (*function)(void *data), v
|
||||
unsigned x;
|
||||
struct timeval tv;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
max_used = ctrl->sched.max_used;
|
||||
for (x = 0; x < max_used; ++x) {
|
||||
if (!ctrl->sched.timer[x].callback) {
|
||||
@@ -156,9 +153,6 @@ struct timeval *pri_schedule_next(struct pri *ctrl)
|
||||
struct timeval *closest = NULL;
|
||||
unsigned x;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
/* Scan the scheduled timer slots backwards so we can update the max_used value. */
|
||||
for (x = ctrl->sched.max_used; x--;) {
|
||||
if (ctrl->sched.timer[x].callback) {
|
||||
@@ -196,9 +190,6 @@ static pri_event *__pri_schedule_run(struct pri *ctrl, struct timeval *tv)
|
||||
void (*callback)(void *);
|
||||
void *data;
|
||||
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
max_used = ctrl->sched.max_used;
|
||||
for (x = 0; x < max_used; ++x) {
|
||||
if (ctrl->sched.timer[x].callback
|
||||
@@ -246,9 +237,6 @@ pri_event *pri_schedule_run(struct pri *ctrl)
|
||||
*/
|
||||
void pri_schedule_del(struct pri *ctrl, int id)
|
||||
{
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
if (0 < id && id <= ctrl->sched.num_slots) {
|
||||
ctrl->sched.timer[id - 1].callback = NULL;
|
||||
} else if (id) {
|
||||
@@ -271,9 +259,6 @@ void pri_schedule_del(struct pri *ctrl, int id)
|
||||
*/
|
||||
int pri_schedule_check(struct pri *ctrl, int id, void (*function)(void *data), void *data)
|
||||
{
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
if (0 < id && id <= ctrl->sched.num_slots) {
|
||||
if (ctrl->sched.timer[id - 1].callback == function
|
||||
&& ctrl->sched.timer[id - 1].data == data) {
|
||||
|
||||
107
q931.c
107
q931.c
@@ -334,7 +334,7 @@ static int q931_encode_channel(const q931_call *call)
|
||||
int q931_is_call_valid(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
struct q931_call *cur;
|
||||
struct pri *link;
|
||||
struct q921_link *link;
|
||||
int idx;
|
||||
|
||||
if (!call) {
|
||||
@@ -347,11 +347,7 @@ int q931_is_call_valid(struct pri *ctrl, struct q931_call *call)
|
||||
/* Definitely a bad call pointer. */
|
||||
return 0;
|
||||
}
|
||||
/* Find the master - He has the call pool */
|
||||
ctrl = PRI_MASTER(call->pri);
|
||||
} else {
|
||||
/* Find the master - He has the call pool */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
ctrl = call->pri;
|
||||
}
|
||||
|
||||
/* Check real call records. */
|
||||
@@ -372,7 +368,7 @@ int q931_is_call_valid(struct pri *ctrl, struct q931_call *call)
|
||||
}
|
||||
|
||||
/* Check dummy call records. */
|
||||
for (link = ctrl; link; link = link->subchannel) {
|
||||
for (link = &ctrl->link; link; link = link->next) {
|
||||
if (link->dummy_call == call) {
|
||||
/* Found it. */
|
||||
return 1;
|
||||
@@ -1612,7 +1608,7 @@ static int transmit_bearer_capability(int full_ie, struct pri *ctrl, q931_call *
|
||||
if(order > 1)
|
||||
return 0;
|
||||
|
||||
if (ctrl->subchannel && !ctrl->bri) {
|
||||
if (ctrl->link.next && !ctrl->bri) {
|
||||
/* Bearer capability is *hard coded* in GR-303 */
|
||||
ie->data[0] = 0x88;
|
||||
ie->data[1] = 0x90;
|
||||
@@ -2744,7 +2740,7 @@ static int transmit_progress_indicator(int full_ie, struct pri *ctrl, q931_call
|
||||
{
|
||||
int code, mask;
|
||||
/* Can't send progress indicator on GR-303 -- EVER! */
|
||||
if (ctrl->subchannel && !ctrl->bri)
|
||||
if (ctrl->link.next && !ctrl->bri)
|
||||
return 0;
|
||||
if (call->progressmask > 0) {
|
||||
if (call->progressmask & (mask = PRI_PROG_CALL_NOT_E2E_ISDN))
|
||||
@@ -3786,7 +3782,7 @@ static inline void q931_dumpie(struct pri *ctrl, int codeset, q931_ie *ie, char
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void q931_init_call_record(struct pri *link, struct q931_call *call, int cr)
|
||||
void q931_init_call_record(struct q921_link *link, struct q931_call *call, int cr)
|
||||
{
|
||||
struct pri *ctrl;
|
||||
|
||||
@@ -3825,14 +3821,14 @@ void q931_init_call_record(struct pri *link, struct q931_call *call, int cr)
|
||||
q931_party_redirecting_init(&call->redirecting);
|
||||
|
||||
/* The call is now attached to whoever called us */
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
call->pri = ctrl;
|
||||
if (cr == Q931_DUMMY_CALL_REFERENCE) {
|
||||
/* Dummy calls are always for the given link. */
|
||||
call->link = link;
|
||||
} else if (BRI_TE_PTMP(ctrl)) {
|
||||
/* Always uses the specific TEI link. */
|
||||
call->link = ctrl->subchannel;
|
||||
call->link = ctrl->link.next;
|
||||
} else {
|
||||
call->link = link;
|
||||
}
|
||||
@@ -3848,14 +3844,13 @@ void q931_init_call_record(struct pri *link, struct q931_call *call, int cr)
|
||||
* \retval record on success.
|
||||
* \retval NULL on error.
|
||||
*/
|
||||
static struct q931_call *q931_create_call_record(struct pri *link, int cr)
|
||||
static struct q931_call *q931_create_call_record(struct q921_link *link, int cr)
|
||||
{
|
||||
struct q931_call *call;
|
||||
struct q931_call *prev;
|
||||
struct pri *ctrl;
|
||||
|
||||
/* Find the master - He has the call pool */
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
|
||||
pri_message(ctrl, "-- Making new call for cref %d\n", cr);
|
||||
@@ -3893,7 +3888,7 @@ static struct q931_call *q931_create_call_record(struct pri *link, int cr)
|
||||
* \retval call if found.
|
||||
* \retval NULL if not found.
|
||||
*/
|
||||
static struct q931_call *q931_find_call(struct pri *link, int cr)
|
||||
static struct q931_call *q931_find_call(struct q921_link *link, int cr)
|
||||
{
|
||||
struct q931_call *cur;
|
||||
struct pri *ctrl;
|
||||
@@ -3902,8 +3897,7 @@ static struct q931_call *q931_find_call(struct pri *link, int cr)
|
||||
return link->dummy_call;
|
||||
}
|
||||
|
||||
/* Find the master - He has the call pool */
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
|
||||
if (BRI_NT_PTMP(ctrl) && !(cr & Q931_CALL_REFERENCE_FLAG)) {
|
||||
if (link->tei == Q921_TEI_GROUP) {
|
||||
@@ -3925,9 +3919,7 @@ static struct q931_call *q931_find_call(struct pri *link, int cr)
|
||||
/* Found existing call. */
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_GR303_EOC:
|
||||
case PRI_SWITCH_GR303_EOC_PATH:
|
||||
case PRI_SWITCH_GR303_TMC:
|
||||
case PRI_SWITCH_GR303_TMC_SWITCHING:
|
||||
break;
|
||||
default:
|
||||
if (!ctrl->bri) {
|
||||
@@ -3944,7 +3936,7 @@ static struct q931_call *q931_find_call(struct pri *link, int cr)
|
||||
return cur;
|
||||
}
|
||||
|
||||
static struct q931_call *q931_getcall(struct pri *link, int cr)
|
||||
static struct q931_call *q931_getcall(struct q921_link *link, int cr)
|
||||
{
|
||||
struct q931_call *cur;
|
||||
struct pri *ctrl;
|
||||
@@ -3957,7 +3949,7 @@ static struct q931_call *q931_getcall(struct pri *link, int cr)
|
||||
/* Do not create new dummy call records. */
|
||||
return NULL;
|
||||
}
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
if (link->tei == Q921_TEI_GROUP
|
||||
&& BRI_NT_PTMP(ctrl)) {
|
||||
/* Do not create NT PTMP broadcast call records here. */
|
||||
@@ -3981,13 +3973,10 @@ static struct q931_call *q931_getcall(struct pri *link, int cr)
|
||||
struct q931_call *q931_new_call(struct pri *ctrl)
|
||||
{
|
||||
struct q931_call *cur;
|
||||
struct pri *link;
|
||||
struct q921_link *link;
|
||||
int first_cref;
|
||||
int cref;
|
||||
|
||||
/* Find the master - He has the call pool */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
/* Find a new call reference value. */
|
||||
first_cref = ctrl->cref;
|
||||
do {
|
||||
@@ -4018,7 +4007,7 @@ struct q931_call *q931_new_call(struct pri *ctrl)
|
||||
}
|
||||
} while (cur);
|
||||
|
||||
link = ctrl;
|
||||
link = &ctrl->link;
|
||||
return q931_create_call_record(link, cref);
|
||||
}
|
||||
|
||||
@@ -4063,9 +4052,6 @@ void q931_destroycall(struct pri *ctrl, q931_call *c)
|
||||
slave = NULL;
|
||||
}
|
||||
|
||||
/* For destroying, make sure we are using the master span, since it maintains the call pool */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
prev = NULL;
|
||||
cur = *ctrl->callpool;
|
||||
while (cur) {
|
||||
@@ -4478,7 +4464,7 @@ static void init_header(struct pri *ctrl, q931_call *call, unsigned char *buf, q
|
||||
} else if (!ctrl->bri) {
|
||||
/* Two bytes of Call Reference. */
|
||||
h->crlen = 2;
|
||||
if (ctrl->subchannel) {
|
||||
if (ctrl->link.next) {
|
||||
/* On GR-303, Q931_CALL_REFERENCE_FLAG is always 0 */
|
||||
crv = ((unsigned) call->cr) & ~Q931_CALL_REFERENCE_FLAG;
|
||||
} else {
|
||||
@@ -4503,11 +4489,11 @@ static void init_header(struct pri *ctrl, q931_call *call, unsigned char *buf, q
|
||||
*mhb = mh;
|
||||
}
|
||||
|
||||
static void q931_xmit(struct pri *link, q931_h *h, int len, int cr, int uiframe)
|
||||
static void q931_xmit(struct q921_link *link, q931_h *h, int len, int cr, int uiframe)
|
||||
{
|
||||
struct pri *ctrl;
|
||||
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
ctrl->q931_txcount++;
|
||||
#endif
|
||||
@@ -4671,7 +4657,7 @@ int maintenance_service(struct pri *ctrl, int span, int channel, int changestatu
|
||||
int pd = MAINTENANCE_PROTOCOL_DISCRIMINATOR_1;
|
||||
int mt = ATT_SERVICE;
|
||||
|
||||
c = q931_getcall(ctrl, 0 | Q931_CALL_REFERENCE_FLAG);
|
||||
c = q931_getcall(&ctrl->link, 0 | Q931_CALL_REFERENCE_FLAG);
|
||||
if (!c) {
|
||||
return -1;
|
||||
}
|
||||
@@ -5105,7 +5091,7 @@ int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
|
||||
/* Connect request timer */
|
||||
pri_schedule_del(ctrl, c->retranstimer);
|
||||
c->retranstimer = 0;
|
||||
if ((c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) && (ctrl->bri || (!ctrl->subchannel)))
|
||||
if ((c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) && (ctrl->bri || (!ctrl->link.next)))
|
||||
c->retranstimer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T313], pri_connect_timeout, c);
|
||||
|
||||
if (c->redirecting.state == Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3) {
|
||||
@@ -5197,7 +5183,7 @@ int q931_restart(struct pri *ctrl, int channel)
|
||||
{
|
||||
struct q931_call *c;
|
||||
|
||||
c = q931_getcall(ctrl, 0 | Q931_CALL_REFERENCE_FLAG);
|
||||
c = q931_getcall(&ctrl->link, 0 | Q931_CALL_REFERENCE_FLAG);
|
||||
if (!c)
|
||||
return -1;
|
||||
if (!channel)
|
||||
@@ -5321,7 +5307,7 @@ static void t303_expiry(void *data)
|
||||
} else if (c->t303_expirycnt < 2) {
|
||||
c->cc.saved_ie_contents.length = 0;
|
||||
c->cc.saved_ie_flags = 0;
|
||||
if (ctrl->subchannel && !ctrl->bri)
|
||||
if (ctrl->link.next && !ctrl->bri)
|
||||
res = send_message(ctrl, c, Q931_SETUP, gr303_setup_ies);
|
||||
else if (c->cis_call)
|
||||
res = send_message(ctrl, c, Q931_SETUP, cis_setup_ies);
|
||||
@@ -5366,7 +5352,7 @@ int q931_setup(struct pri *ctrl, q931_call *c, struct pri_sr *req)
|
||||
|
||||
c->ds1no = (req->channel & 0xff00) >> 8;
|
||||
c->ds1explicit = (req->channel & 0x10000) >> 16;
|
||||
if ((ctrl->localtype == PRI_CPE) && ctrl->subchannel && !ctrl->bri) {
|
||||
if ((ctrl->localtype == PRI_CPE) && ctrl->link.next && !ctrl->bri) {
|
||||
c->channelno = 0;
|
||||
c->chanflags = 0;
|
||||
} else {
|
||||
@@ -5426,7 +5412,7 @@ int q931_setup(struct pri *ctrl, q931_call *c, struct pri_sr *req)
|
||||
if (BRI_NT_PTMP(ctrl)) {
|
||||
c->outboundbroadcast = 1;
|
||||
}
|
||||
if (ctrl->subchannel && !ctrl->bri)
|
||||
if (ctrl->link.next && !ctrl->bri)
|
||||
res = send_message(ctrl, c, Q931_SETUP, gr303_setup_ies);
|
||||
else if (c->cis_call)
|
||||
res = send_message(ctrl, c, Q931_SETUP, cis_setup_ies);
|
||||
@@ -5554,7 +5540,7 @@ int q931_connect_acknowledge(struct pri *ctrl, q931_call *call, int channel)
|
||||
winner->chanflags |= FLAG_EXCLUSIVE;
|
||||
}
|
||||
use_ies = NULL;
|
||||
if (ctrl->subchannel && !ctrl->bri) {
|
||||
if (ctrl->link.next && !ctrl->bri) {
|
||||
if (ctrl->localtype == PRI_CPE) {
|
||||
use_ies = gr303_connect_ack_ies;
|
||||
}
|
||||
@@ -6042,7 +6028,7 @@ static int __q931_hangup(struct pri *ctrl, q931_call *c, int cause)
|
||||
case PRI_CAUSE_REQUESTED_CHAN_UNAVAIL:
|
||||
case PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST:
|
||||
case PRI_CAUSE_UNALLOCATED:
|
||||
if (!PRI_MASTER(ctrl)->hangup_fix_enabled) {
|
||||
if (!ctrl->hangup_fix_enabled) {
|
||||
/* Legacy: We'll send RELEASE_COMPLETE with these causes */
|
||||
disconnect = 0;
|
||||
release_compl = 1;
|
||||
@@ -6115,7 +6101,7 @@ static int __q931_hangup(struct pri *ctrl, q931_call *c, int cause)
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
|
||||
pri_message(ctrl, "Faking clearing\n");
|
||||
}
|
||||
pri_create_fake_clearing(c, PRI_MASTER(ctrl));
|
||||
pri_create_fake_clearing(c, ctrl);
|
||||
/* This means that we never got a response from a TEI */
|
||||
return 0;
|
||||
}
|
||||
@@ -6505,14 +6491,14 @@ static void q931_set_subcall_winner(struct q931_call *subcall)
|
||||
}
|
||||
}
|
||||
|
||||
static struct q931_call *q931_get_subcall(struct pri *link, struct q931_call *master_call)
|
||||
static struct q931_call *q931_get_subcall(struct q921_link *link, struct q931_call *master_call)
|
||||
{
|
||||
int i;
|
||||
struct q931_call *cur;
|
||||
struct pri *ctrl;
|
||||
int firstfree = -1;
|
||||
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
|
||||
/* First try to locate our subcall */
|
||||
for (i = 0; i < ARRAY_LEN(master_call->subcalls); ++i) {
|
||||
@@ -6564,7 +6550,7 @@ static struct q931_call *q931_get_subcall(struct pri *link, struct q931_call *ma
|
||||
return cur;
|
||||
}
|
||||
|
||||
int q931_receive(struct pri *link, q931_h *h, int len)
|
||||
int q931_receive(struct q921_link *link, q931_h *h, int len)
|
||||
{
|
||||
q931_mh *mh;
|
||||
struct q931_call *c;
|
||||
@@ -6582,7 +6568,7 @@ int q931_receive(struct pri *link, q931_h *h, int len)
|
||||
int allow_event;
|
||||
int allow_posthandle;
|
||||
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
memset(last_ie, 0, sizeof(last_ie));
|
||||
#ifdef LIBPRI_COUNTERS
|
||||
ctrl->q931_rxcount++;
|
||||
@@ -6622,7 +6608,7 @@ int q931_receive(struct pri *link, q931_h *h, int len)
|
||||
pri_error(ctrl, "Unable to locate call %d\n", cref);
|
||||
return -1;
|
||||
}
|
||||
if (c->master_call->outboundbroadcast && link != ctrl) {
|
||||
if (c->master_call->outboundbroadcast && link != &ctrl->link) {
|
||||
c = q931_get_subcall(link, c->master_call);
|
||||
if (!c) {
|
||||
pri_error(ctrl, "Unable to locate subcall for %d\n", cref);
|
||||
@@ -7332,7 +7318,7 @@ int q931_cc_timeout(struct pri *ctrl, struct pri_cc_record *cc_record, enum CC_E
|
||||
int fsm_complete;
|
||||
|
||||
q931_clr_subcommands(ctrl);
|
||||
dummy = cc_record->master->dummy_call;
|
||||
dummy = ctrl->link.dummy_call;
|
||||
call = cc_record->signaling;
|
||||
if (!call) {
|
||||
/* Substitute the broadcast dummy call reference call. */
|
||||
@@ -7361,7 +7347,7 @@ void q931_cc_indirect(struct pri *ctrl, struct pri_cc_record *cc_record, void (*
|
||||
q931_call *dummy;
|
||||
|
||||
q931_clr_subcommands(ctrl);
|
||||
dummy = cc_record->master->dummy_call;
|
||||
dummy = ctrl->link.dummy_call;
|
||||
call = cc_record->signaling;
|
||||
if (!call) {
|
||||
/* Substitute the broadcast dummy call reference call. */
|
||||
@@ -7385,14 +7371,12 @@ void q931_cc_indirect(struct pri *ctrl, struct pri_cc_record *cc_record, void (*
|
||||
*/
|
||||
struct q931_call *q931_find_link_id_call(struct pri *ctrl, int link_id)
|
||||
{
|
||||
struct pri *master;
|
||||
struct q931_call *cur;
|
||||
struct q931_call *winner;
|
||||
struct q931_call *match;
|
||||
|
||||
match = NULL;
|
||||
master = PRI_MASTER(ctrl);
|
||||
for (cur = *master->callpool; cur; cur = cur->next) {
|
||||
for (cur = *ctrl->callpool; cur; cur = cur->next) {
|
||||
if (cur->is_link_id_valid && cur->link_id == link_id) {
|
||||
/* Found the link_id call. */
|
||||
winner = q931_find_winning_call(cur);
|
||||
@@ -7432,14 +7416,12 @@ struct q931_call *q931_find_link_id_call(struct pri *ctrl, int link_id)
|
||||
*/
|
||||
struct q931_call *q931_find_held_active_call(struct pri *ctrl, struct q931_call *held_call)
|
||||
{
|
||||
struct pri *master;
|
||||
struct q931_call *cur;
|
||||
struct q931_call *winner;
|
||||
struct q931_call *match;
|
||||
|
||||
match = NULL;
|
||||
master = PRI_MASTER(ctrl);
|
||||
for (cur = *master->callpool; cur; cur = cur->next) {
|
||||
for (cur = *ctrl->callpool; cur; cur = cur->next) {
|
||||
if (cur->hold_state == Q931_HOLD_STATE_IDLE) {
|
||||
/* Found an active call. */
|
||||
winner = q931_find_winning_call(cur);
|
||||
@@ -7486,14 +7468,12 @@ struct q931_call *q931_find_held_active_call(struct pri *ctrl, struct q931_call
|
||||
*/
|
||||
static struct q931_call *q931_find_held_call(struct pri *ctrl, struct q931_call *active_call)
|
||||
{
|
||||
struct pri *master;
|
||||
struct q931_call *cur;
|
||||
struct q931_call *winner;
|
||||
struct q931_call *match;
|
||||
|
||||
match = NULL;
|
||||
master = PRI_MASTER(ctrl);
|
||||
for (cur = *master->callpool; cur; cur = cur->next) {
|
||||
for (cur = *ctrl->callpool; cur; cur = cur->next) {
|
||||
if (cur->hold_state == Q931_HOLD_STATE_CALL_HELD) {
|
||||
/* Found a held call. */
|
||||
winner = q931_find_winning_call(cur);
|
||||
@@ -7702,7 +7682,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
libpri_copy_string(ctrl->ev.answer.useruserinfo, c->useruserinfo, sizeof(ctrl->ev.answer.useruserinfo));
|
||||
c->useruserinfo[0] = '\0';
|
||||
|
||||
if (!PRI_MASTER(ctrl)->manual_connect_ack) {
|
||||
if (!ctrl->manual_connect_ack) {
|
||||
q931_connect_acknowledge(ctrl, c, 0);
|
||||
} else {
|
||||
UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_CONNECT_REQUEST);
|
||||
@@ -7804,7 +7784,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
case Q931_CALL_STATE_ACTIVE:
|
||||
UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_ACTIVE);
|
||||
c->peercallstate = Q931_CALL_STATE_ACTIVE;
|
||||
if (PRI_MASTER(ctrl)->manual_connect_ack) {
|
||||
if (ctrl->manual_connect_ack) {
|
||||
ctrl->ev.e = PRI_EVENT_CONNECT_ACK;
|
||||
ctrl->ev.connect_ack.subcmds = &ctrl->subcmds;
|
||||
ctrl->ev.connect_ack.channel = q931_encode_channel(c);
|
||||
@@ -8185,7 +8165,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
return res;
|
||||
case Q931_HOLD:
|
||||
res = 0;
|
||||
if (!PRI_MASTER(ctrl)->hold_support) {
|
||||
if (!ctrl->hold_support) {
|
||||
/*
|
||||
* Blocking any calls from getting on HOLD effectively
|
||||
* disables HOLD/RETRIEVE.
|
||||
@@ -8587,7 +8567,7 @@ static const char *q931_dl_event2str(enum Q931_DL_EVENT event)
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void q931_dl_event(struct pri *link, enum Q931_DL_EVENT event)
|
||||
void q931_dl_event(struct q921_link *link, enum Q931_DL_EVENT event)
|
||||
{
|
||||
struct q931_call *cur;
|
||||
struct q931_call *call;
|
||||
@@ -8598,8 +8578,7 @@ void q931_dl_event(struct pri *link, enum Q931_DL_EVENT event)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the master - He has the call pool */
|
||||
ctrl = PRI_MASTER(link);
|
||||
ctrl = link->ctrl;
|
||||
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
|
||||
pri_message(ctrl, "TEI=%d DL event: %s(%d)\n", link->tei,
|
||||
|
||||
Reference in New Issue
Block a user