From f9c3c8d02616fb151b900b85df624f6a10edda92 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 21 Oct 2010 17:30:41 +0000 Subject: [PATCH] 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 --- pri.c | 305 ++++++++++++++++++++------------ pri_aoc.c | 15 +- pri_cc.c | 51 ++---- pri_facility.c | 27 ++- pri_internal.h | 115 +++--------- pri_q921.h | 66 ++++++- pri_q931.h | 4 +- prisched.c | 15 -- q921.c | 472 +++++++++++++++++++++++++------------------------ q931.c | 107 +++++------ 10 files changed, 600 insertions(+), 577 deletions(-) diff --git a/pri.c b/pri.c index 36ee69c..d5ac4c5 100644 --- a/pri.c +++ b/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 (link) { + struct q931_call *call; + + call = link->dummy_call; + if (call) { + pri_schedule_del(call->pri, call->retranstimer); + call->retranstimer = 0; + pri_call_apdu_queue_cleanup(call); + } + free(link); + } +} + +/*! + * \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 (p) { + if (ctrl) { struct q931_call *call; - call = p->dummy_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(p->msg_line); - free(p->sched.timer); - free(p); + free(ctrl->msg_line); + free(ctrl->sched.timer); + free(ctrl); } } -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 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; } } diff --git a/pri_aoc.c b/pri_aoc.c index 23d7be6..8b385e5 100644 --- a/pri_aoc.c +++ b/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; } } diff --git a/pri_cc.c b/pri_cc.c index 407e24b..b68127b 100644 --- a/pri_cc.c +++ b/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. diff --git a/pri_facility.c b/pri_facility.c index dc4b5c4..f32f8f1 100644 --- a/pri_facility.c +++ b/pri_facility.c @@ -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; diff --git a/pri_internal.h b/pri_internal.h index c83329c..74abc58 100644 --- a/pri_internal.h +++ b/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; } diff --git a/pri_q921.h b/pri_q921.h index 12d3997..46a0d28 100644 --- a/pri_q921.h +++ b/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); diff --git a/pri_q931.h b/pri_q931.h index aed19bd..7704407 100644 --- a/pri_q931.h +++ b/pri_q931.h @@ -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); diff --git a/prisched.c b/prisched.c index 08b28f6..cc5845e 100644 --- a/prisched.c +++ b/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) { diff --git a/q921.c b/q921.c index 924cb0a..8dad1ca 100644 --- a/q921.c +++ b/q921.c @@ -53,11 +53,11 @@ (hf).h.tei = (link)->tei; \ } while(0) -static void q921_dump_pri(struct pri *link, char direction_tag); -static void q921_establish_data_link(struct pri *link); -static void q921_mdl_error(struct pri *link, char error); -static void q921_mdl_remove(struct pri *link); -static void q921_restart_ptp_link_if_needed(struct pri *link); +static void q921_dump_pri(struct q921_link *link, char direction_tag); +static void q921_establish_data_link(struct q921_link *link); +static void q921_mdl_error(struct q921_link *link, char error); +static void q921_mdl_remove(struct q921_link *link); +static void q921_restart_ptp_link_if_needed(struct q921_link *link); /*! * \internal @@ -91,11 +91,11 @@ static const char *q921_state2str(enum q921_state state) return "Unknown state"; } -static void q921_setstate(struct pri *link, int newstate) +static void q921_setstate(struct q921_link *link, int newstate) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { /* * Suppress displaying these state transitions: @@ -104,14 +104,14 @@ static void q921_setstate(struct pri *link, int newstate) * Q921 keeps flipping back and forth between these two states * when it has nothing better to do. */ - switch (link->q921_state) { + switch (link->state) { case Q921_MULTI_FRAME_ESTABLISHED: case Q921_TIMER_RECOVERY: switch (newstate) { case Q921_MULTI_FRAME_ESTABLISHED: case Q921_TIMER_RECOVERY: /* Suppress displaying this state transition. */ - link->q921_state = newstate; + link->state = newstate; return; default: break; @@ -120,27 +120,27 @@ static void q921_setstate(struct pri *link, int newstate) default: break; } - if (link->q921_state != newstate) { + if (link->state != newstate) { pri_message(ctrl, "Changing from state %d(%s) to %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state), + link->state, q921_state2str(link->state), newstate, q921_state2str(newstate)); } } - link->q921_state = newstate; + link->state = newstate; } -static void q921_discard_iqueue(struct pri *link) +static void q921_discard_iqueue(struct q921_link *link) { struct q921_frame *f, *p; - f = link->txqueue; + f = link->tx_queue; while (f) { p = f; f = f->next; /* Free frame */ free(p); } - link->txqueue = NULL; + link->tx_queue = NULL; } static int q921_transmit(struct pri *ctrl, q921_h *h, int len) @@ -168,12 +168,12 @@ static int q921_transmit(struct pri *ctrl, q921_h *h, int len) return 0; } -static void q921_send_tei(struct pri *link, int message, int ri, int ai, int iscommand) +static void q921_send_tei(struct pri *ctrl, int message, int ri, int ai, int iscommand) { q921_u *f; - struct pri *ctrl; + struct q921_link *link; - ctrl = PRI_MASTER(link); + link = &ctrl->link; if (!(f = calloc(1, sizeof(*f) + 5))) return; @@ -195,10 +195,10 @@ static void q921_send_tei(struct pri *link, int message, int ri, int ai, int isc static void t202_expire(void *vlink) { - struct pri *link = vlink; + struct q921_link *link = vlink; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; /* Start the TEI request timer. */ pri_schedule_del(ctrl, link->t202_timer); @@ -214,8 +214,8 @@ static void t202_expire(void *vlink) link->t202_timer = 0; } pri_error(ctrl, "Unable to receive TEI from network in state %d(%s)!\n", - link->q921_state, q921_state2str(link->q921_state)); - switch (link->q921_state) { + link->state, q921_state2str(link->state)); + switch (link->state) { case Q921_ASSIGN_AWAITING_TEI: break; case Q921_ESTABLISH_AWAITING_TEI: @@ -235,18 +235,18 @@ static void t202_expire(void *vlink) q921_send_tei(ctrl, Q921_TEI_IDENTITY_REQUEST, link->ri, Q921_TEI_GROUP, 1); } -static void q921_tei_request(struct pri *link) +static void q921_tei_request(struct q921_link *link) { link->n202_counter = 0; t202_expire(link); } -static void q921_send_dm(struct pri *link, int fbit) +static void q921_send_dm(struct q921_link *link, int fbit) { q921_h h; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; Q921_INIT(link, h); h.u.m3 = 0; /* M3 = 0 */ @@ -270,12 +270,12 @@ static void q921_send_dm(struct pri *link, int fbit) q921_transmit(ctrl, &h, 4); } -static void q921_send_disc(struct pri *link, int pbit) +static void q921_send_disc(struct q921_link *link, int pbit) { q921_h h; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; Q921_INIT(link, h); h.u.m3 = 2; /* M3 = 2 */ @@ -299,12 +299,12 @@ static void q921_send_disc(struct pri *link, int pbit) q921_transmit(ctrl, &h, 4); } -static void q921_send_ua(struct pri *link, int fbit) +static void q921_send_ua(struct q921_link *link, int fbit) { q921_h h; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; Q921_INIT(link, h); h.u.m3 = 3; /* M3 = 3 */ @@ -328,12 +328,12 @@ static void q921_send_ua(struct pri *link, int fbit) q921_transmit(ctrl, &h, 3); } -static void q921_send_sabme(struct pri *link) +static void q921_send_sabme(struct q921_link *link) { q921_h h; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; Q921_INIT(link, h); h.u.m3 = 3; /* M3 = 3 */ @@ -357,15 +357,15 @@ static void q921_send_sabme(struct pri *link) q921_transmit(ctrl, &h, 3); } -static int q921_ack_packet(struct pri *link, int num) +static int q921_ack_packet(struct q921_link *link, int num) { struct q921_frame *f; struct q921_frame *prev; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; - for (prev = NULL, f = link->txqueue; f; prev = f, f = f->next) { + for (prev = NULL, f = link->tx_queue; f; prev = f, f = f->next) { if (!f->transmitted) { break; } @@ -375,14 +375,14 @@ static int q921_ack_packet(struct pri *link, int num) if (prev) prev->next = f->next; else - link->txqueue = f->next; + link->tx_queue = f->next; if (ctrl->debug & PRI_DEBUG_Q921_DUMP) { pri_message(ctrl, - "-- ACKing N(S)=%d, txqueue head is N(S)=%d (-1 is empty, -2 is not transmitted)\n", + "-- ACKing N(S)=%d, tx_queue head is N(S)=%d (-1 is empty, -2 is not transmitted)\n", f->h.n_s, - link->txqueue - ? link->txqueue->transmitted - ? link->txqueue->h.n_s + link->tx_queue + ? link->tx_queue->transmitted + ? link->tx_queue->h.n_s : -2 : -1); } @@ -398,11 +398,11 @@ static void t203_expire(void *vlink); static void t200_expire(void *vlink); #define restart_t200(link) reschedule_t200(link) -static void reschedule_t200(struct pri *link) +static void reschedule_t200(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_DUMP) pri_message(ctrl, "-- Restarting T200 timer\n"); @@ -411,11 +411,11 @@ static void reschedule_t200(struct pri *link) } #if 0 -static void reschedule_t203(struct pri *link) +static void reschedule_t203(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_DUMP) pri_message(ctrl, "-- Restarting T203 timer\n"); @@ -425,9 +425,9 @@ static void reschedule_t203(struct pri *link) #endif #if 0 -static int q921_unacked_iframes(struct pri *link) +static int q921_unacked_iframes(struct q921_link *link) { - struct q921_frame *f = link->txqueue; + struct q921_frame *f = link->tx_queue; int cnt = 0; while(f) { @@ -440,11 +440,11 @@ static int q921_unacked_iframes(struct pri *link) } #endif -static void start_t203(struct pri *link) +static void start_t203(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (link->t203_timer) { if (ctrl->debug & PRI_DEBUG_Q921_DUMP) @@ -456,11 +456,11 @@ static void start_t203(struct pri *link) link->t203_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T203], t203_expire, link); } -static void stop_t203(struct pri *link) +static void stop_t203(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (link->t203_timer) { if (ctrl->debug & PRI_DEBUG_Q921_DUMP) @@ -473,11 +473,11 @@ static void stop_t203(struct pri *link) } } -static void start_t200(struct pri *link) +static void start_t200(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (link->t200_timer) { if (ctrl->debug & PRI_DEBUG_Q921_DUMP) @@ -489,11 +489,11 @@ static void start_t200(struct pri *link) link->t200_timer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T200], t200_expire, link); } -static void stop_t200(struct pri *link) +static void stop_t200(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (link->t200_timer) { if (ctrl->debug & PRI_DEBUG_Q921_DUMP) @@ -507,15 +507,15 @@ static void stop_t200(struct pri *link) } /* This is the equivalent of the I-Frame queued up path in Figure B.7 in MULTI_FRAME_ESTABLISHED */ -static int q921_send_queued_iframes(struct pri *link) +static int q921_send_queued_iframes(struct q921_link *link) { struct pri *ctrl; struct q921_frame *f; int frames_txd = 0; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; - for (f = link->txqueue; f; f = f->next) { + for (f = link->tx_queue; f; f = f->next) { if (!f->transmitted) { /* This frame has not been sent yet. */ break; @@ -591,12 +591,12 @@ static int q921_send_queued_iframes(struct pri *link) return frames_txd; } -static void q921_reject(struct pri *link, int pf) +static void q921_reject(struct q921_link *link, int pf) { q921_h h; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; Q921_INIT(link, h); h.s.x0 = 0; /* Always 0 */ @@ -621,12 +621,12 @@ static void q921_reject(struct pri *link, int pf) q921_transmit(ctrl, &h, 4); } -static void q921_rr(struct pri *link, int pbit, int cmd) +static void q921_rr(struct q921_link *link, int pbit, int cmd) { q921_h h; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; Q921_INIT(link, h); h.s.x0 = 0; /* Always 0 */ @@ -659,7 +659,7 @@ static void q921_rr(struct pri *link, int pbit, int cmd) q921_transmit(ctrl, &h, 4); } -static void transmit_enquiry(struct pri *link) +static void transmit_enquiry(struct q921_link *link) { if (!link->own_rx_busy) { q921_rr(link, 1, 1); @@ -672,10 +672,10 @@ static void transmit_enquiry(struct pri *link) static void t200_expire(void *vlink) { - struct pri *link = vlink; + struct q921_link *link = vlink; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_DUMP) { pri_message(ctrl, "%s\n", __FUNCTION__); @@ -684,7 +684,7 @@ static void t200_expire(void *vlink) link->t200_timer = 0; - switch (link->q921_state) { + switch (link->state) { case Q921_MULTI_FRAME_ESTABLISHED: link->RC = 0; transmit_enquiry(link); @@ -707,7 +707,7 @@ static void t200_expire(void *vlink) } else { q921_mdl_error(link, 'I'); q921_establish_data_link(link); - link->l3initiated = 0; + link->l3_initiated = 0; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); } break; @@ -739,19 +739,19 @@ static void t200_expire(void *vlink) default: /* Looks like someone forgot to stop the T200 timer. */ pri_error(ctrl, "T200 expired in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } } /* This is sending a DL-UNIT-DATA request */ -int q921_transmit_uiframe(struct pri *link, void *buf, int len) +int q921_transmit_uiframe(struct q921_link *link, void *buf, int len) { uint8_t ubuf[512]; q921_h *h = (void *)&ubuf[0]; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (len >= 512) { pri_error(ctrl, "Requested to send UI-frame larger than 512 bytes!\n"); @@ -787,23 +787,25 @@ int q921_transmit_uiframe(struct pri *link, void *buf, int len) return 0; } -static struct pri *pri_find_tei(struct pri *ctrl, int sapi, int tei) +static struct q921_link *pri_find_tei(struct pri *ctrl, int sapi, int tei) { - for (; ctrl; ctrl = ctrl->subchannel) { - if (ctrl->tei == tei && ctrl->sapi == sapi) - return ctrl; + struct q921_link *link; + + for (link = &ctrl->link; link; link = link->next) { + if (link->tei == tei && link->sapi == sapi) + return link; } return NULL; } /* This is the equivalent of a DL-DATA request, as well as the I-frame queued up outcome */ -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) { q921_frame *f, *prev=NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (PTMP_MODE(ctrl)) { if (link->tei == Q921_TEI_GROUP) { @@ -811,7 +813,7 @@ int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr) return 0; } if (BRI_TE_PTMP(ctrl)) { - switch (link->q921_state) { + switch (link->state) { case Q921_TEI_UNASSIGNED: q921_setstate(link, Q921_ESTABLISH_AWAITING_TEI); q921_tei_request(link); @@ -828,11 +830,11 @@ int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr) } /* Figure B.7/Q.921 Page 70 */ - switch (link->q921_state) { + switch (link->state) { case Q921_TEI_ASSIGNED: /* If we aren't in a state compatiable with DL-DATA requests, start getting us there here */ q921_establish_data_link(link); - link->l3initiated = 1; + link->l3_initiated = 1; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); /* For all rest, we've done the work to get us up prior to this and fall through */ case Q921_ESTABLISH_AWAITING_TEI: @@ -840,7 +842,7 @@ int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr) case Q921_AWAITING_ESTABLISHMENT: case Q921_MULTI_FRAME_ESTABLISHED: /* Find queue tail. */ - for (f = link->txqueue; f; f = f->next) { + for (f = link->tx_queue; f; f = f->next) { prev = f; } @@ -870,14 +872,14 @@ int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr) if (prev) prev->next = f; else - link->txqueue = f; + link->tx_queue = f; - if (link->q921_state != Q921_MULTI_FRAME_ESTABLISHED) { + if (link->state != Q921_MULTI_FRAME_ESTABLISHED) { if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Just queued I-frame since in state %d(%s)\n", link->tei, - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); } break; } @@ -902,7 +904,7 @@ int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr) case Q921_AWAITING_RELEASE: default: pri_error(ctrl, "Cannot transmit frames in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return 0; @@ -910,17 +912,17 @@ int q921_transmit_iframe(struct pri *link, void *buf, int len, int cr) static void t203_expire(void *vlink) { - struct pri *link = vlink; + struct q921_link *link = vlink; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_DUMP) pri_message(ctrl, "%s\n", __FUNCTION__); link->t203_timer = 0; - switch (link->q921_state) { + switch (link->state) { case Q921_MULTI_FRAME_ESTABLISHED: transmit_enquiry(link); link->RC = 0; @@ -929,22 +931,22 @@ static void t203_expire(void *vlink) default: /* Looks like someone forgot to stop the T203 timer. */ pri_error(ctrl, "T203 expired in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } } -static void q921_dump_iqueue_info(struct pri *link) +static void q921_dump_iqueue_info(struct q921_link *link) { struct pri *ctrl; struct q921_frame *f; int pending = 0, unacked = 0; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; unacked = pending = 0; - for (f = link->txqueue; f; f = f->next) { + for (f = link->tx_queue; f; f = f->next) { if (f->transmitted) { unacked++; } else { @@ -1131,18 +1133,18 @@ void q921_dump(struct pri *ctrl, q921_h *h, int len, int showraw, int txrx) } } -static void q921_dump_pri(struct pri *link, char direction_tag) +static void q921_dump_pri(struct q921_link *link, char direction_tag) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; pri_message(ctrl, "%c TEI: %d State %d(%s)\n", - direction_tag, link->tei, link->q921_state, q921_state2str(link->q921_state)); + direction_tag, link->tei, link->state, q921_state2str(link->state)); pri_message(ctrl, "%c V(A)=%d, V(S)=%d, V(R)=%d\n", direction_tag, link->v_a, link->v_s, link->v_r); - pri_message(ctrl, "%c K=%d, RC=%d, l3initiated=%d, reject_except=%d, ack_pend=%d\n", - direction_tag, ctrl->timers[PRI_TIMER_K], link->RC, link->l3initiated, + pri_message(ctrl, "%c K=%d, RC=%d, l3_initiated=%d, reject_except=%d, ack_pend=%d\n", + direction_tag, ctrl->timers[PRI_TIMER_K], link->RC, link->l3_initiated, link->reject_exception, link->acknowledge_pending); pri_message(ctrl, "%c T200_id=%d, N200=%d, T203_id=%d\n", direction_tag, link->t200_timer, ctrl->timers[PRI_TIMER_N200], link->t203_timer); @@ -1150,7 +1152,7 @@ static void q921_dump_pri(struct pri *link, char direction_tag) static void q921_dump_pri_by_h(struct pri *ctrl, char direction_tag, q921_h *h) { - struct pri *link; + struct q921_link *link; if (!ctrl) { return; @@ -1159,9 +1161,10 @@ static void q921_dump_pri_by_h(struct pri *ctrl, char direction_tag, q921_h *h) if (BRI_NT_PTMP(ctrl)) { link = pri_find_tei(ctrl, h->h.sapi, h->h.tei); } else if (BRI_TE_PTMP(ctrl)) { - link = ctrl->subchannel; + /* We're operating on the specific TEI link */ + link = ctrl->link.next; } else { - link = ctrl; + link = &ctrl->link; } if (link) { @@ -1174,8 +1177,8 @@ static void q921_dump_pri_by_h(struct pri *ctrl, char direction_tag, q921_h *h) static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) { int ri; - struct pri *sub; - struct pri *link; + struct q921_link *sub; + struct q921_link *link; pri_event *res = NULL; int tei; @@ -1213,8 +1216,8 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) /* Find a TEI that is not allocated. */ tei = 64; do { - for (sub = ctrl; sub->subchannel; sub = sub->subchannel) { - if (sub->subchannel->tei == tei) { + for (sub = &ctrl->link; sub->next; sub = sub->next) { + if (sub->next->tei == tei) { /* This TEI is already assigned, try next one. */ ++tei; if (tei < Q921_TEI_GROUP) { @@ -1225,27 +1228,27 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) return NULL; } } - } while (sub->subchannel); + } while (sub->next); if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "Allocating new TEI %d\n", tei); } - sub->subchannel = __pri_new_tei(-1, ctrl->localtype, ctrl->switchtype, ctrl, NULL, NULL, NULL, tei, 1); - if (!sub->subchannel) { - pri_error(ctrl, "Unable to allocate D-channel for new TEI %d\n", tei); + sub->next = pri_link_new(ctrl, Q921_SAPI_CALL_CTRL, tei); + if (!sub->next) { + pri_error(ctrl, "Unable to allocate layer 2 link for new TEI %d\n", tei); return NULL; } - q921_setstate(sub->subchannel, Q921_TEI_ASSIGNED); + q921_setstate(sub->next, Q921_TEI_ASSIGNED); q921_send_tei(ctrl, Q921_TEI_IDENTITY_ASSIGNED, ri, tei, 1); break; case Q921_TEI_IDENTITY_ASSIGNED: if (!BRI_TE_PTMP(ctrl)) return NULL; - /* Assuming we're operating on the sub here */ - link = ctrl->subchannel; + /* Assuming we're operating on the specific TEI link here */ + link = ctrl->link.next; - switch (link->q921_state) { + switch (link->state) { case Q921_ASSIGN_AWAITING_TEI: case Q921_ESTABLISH_AWAITING_TEI: break; @@ -1269,7 +1272,7 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) pri_message(ctrl, "Got assigned TEI %d\n", tei); } - switch (link->q921_state) { + switch (link->state) { case Q921_ASSIGN_AWAITING_TEI: q921_setstate(link, Q921_TEI_ASSIGNED); ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP; @@ -1277,7 +1280,7 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) break; case Q921_ESTABLISH_AWAITING_TEI: q921_establish_data_link(link); - link->l3initiated = 1; + link->l3_initiated = 1; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP; res = &ctrl->ev; @@ -1290,10 +1293,10 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) if (!BRI_TE_PTMP(ctrl)) return NULL; - /* Assuming we're operating on the sub here */ - link = ctrl->subchannel; + /* Assuming we're operating on the specific TEI link here */ + link = ctrl->link.next; - if (link->q921_state < Q921_TEI_ASSIGNED) { + if (link->state < Q921_TEI_ASSIGNED) { /* We do not have a TEI. */ return NULL; } @@ -1307,10 +1310,10 @@ static pri_event *q921_receive_MDL(struct pri *ctrl, q921_u *h, int len) if (!BRI_TE_PTMP(ctrl)) return NULL; - /* Assuming we're operating on the sub here */ - link = ctrl->subchannel; + /* Assuming we're operating on the specific TEI link here */ + link = ctrl->link.next; - if (link->q921_state < Q921_TEI_ASSIGNED) { + if (link->state < Q921_TEI_ASSIGNED) { /* We do not have a TEI. */ return NULL; } @@ -1337,7 +1340,7 @@ static int is_command(struct pri *ctrl, q921_h *h) return command; } -static void q921_clear_exception_conditions(struct pri *link) +static void q921_clear_exception_conditions(struct q921_link *link) { link->own_rx_busy = 0; link->peer_rx_busy = 0; @@ -1345,15 +1348,15 @@ static void q921_clear_exception_conditions(struct pri *link) link->acknowledge_pending = 0; } -static pri_event *q921_sabme_rx(struct pri *link, q921_h *h) +static pri_event *q921_sabme_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; enum Q931_DL_EVENT delay_q931_dl_event; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; - switch (link->q921_state) { + switch (link->state) { case Q921_TIMER_RECOVERY: /* Timer recovery state handling is same as multiframe established */ case Q921_MULTI_FRAME_ESTABLISHED: @@ -1402,25 +1405,25 @@ static pri_event *q921_sabme_rx(struct pri *link, q921_h *h) break; default: pri_error(ctrl, "Cannot handle SABME in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static pri_event *q921_disc_rx(struct pri *link, q921_h *h) +static pri_event *q921_disc_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Got DISC\n", link->tei); } - switch (link->q921_state) { + switch (link->state) { case Q921_TEI_ASSIGNED: case Q921_AWAITING_ESTABLISHMENT: q921_send_dm(link, h->u.p_f); @@ -1435,32 +1438,32 @@ static pri_event *q921_disc_rx(struct pri *link, q921_h *h) /* DL-RELEASE indication */ q931_dl_event(link, Q931_DL_EVENT_DL_RELEASE_IND); stop_t200(link); - if (link->q921_state == Q921_MULTI_FRAME_ESTABLISHED) + if (link->state == Q921_MULTI_FRAME_ESTABLISHED) stop_t203(link); q921_setstate(link, Q921_TEI_ASSIGNED); q921_restart_ptp_link_if_needed(link); break; default: pri_error(ctrl, "Don't know what to do with DISC in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static void q921_mdl_remove(struct pri *link) +static void q921_mdl_remove(struct q921_link *link) { int mdl_free_me; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "MDL-REMOVE: Removing TEI %d\n", link->tei); } if (BRI_NT_PTMP(ctrl)) { - if (link == ctrl) { + if (link == &ctrl->link) { pri_error(ctrl, "Bad bad bad! Cannot MDL-REMOVE master\n"); return; } @@ -1469,7 +1472,7 @@ static void q921_mdl_remove(struct pri *link) mdl_free_me = 0; } - switch (link->q921_state) { + switch (link->state) { case Q921_TEI_ASSIGNED: /* XXX: deviation! Since we don't have a UI queue, we just discard our I-queue */ q921_discard_iqueue(link); @@ -1506,7 +1509,7 @@ static void q921_mdl_remove(struct pri *link) break; default: pri_error(ctrl, "MDL-REMOVE when in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); return; } @@ -1521,7 +1524,7 @@ static void q921_mdl_remove(struct pri *link) link->mdl_free_me = mdl_free_me; } -static int q921_mdl_handle_network_error(struct pri *link, char error) +static int q921_mdl_handle_network_error(struct q921_link *link, char error) { int handled = 0; struct pri *ctrl; @@ -1543,7 +1546,7 @@ static int q921_mdl_handle_network_error(struct pri *link, char error) case 'K': break; default: - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; pri_error(ctrl, "Network MDL can't handle error of type %c\n", error); break; } @@ -1551,7 +1554,7 @@ static int q921_mdl_handle_network_error(struct pri *link, char error) return handled; } -static int q921_mdl_handle_cpe_error(struct pri *link, char error) +static int q921_mdl_handle_cpe_error(struct q921_link *link, char error) { int handled = 0; struct pri *ctrl; @@ -1573,7 +1576,7 @@ static int q921_mdl_handle_cpe_error(struct pri *link, char error) case 'K': break; default: - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; pri_error(ctrl, "CPE MDL can't handle error of type %c\n", error); break; } @@ -1581,12 +1584,12 @@ static int q921_mdl_handle_cpe_error(struct pri *link, char error) return handled; } -static int q921_mdl_handle_ptp_error(struct pri *link, char error) +static int q921_mdl_handle_ptp_error(struct q921_link *link, char error) { int handled = 0; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; /* This is where we act a bit like L3 instead of L2, since we've got an L3 that depends on us * keeping L2 automatically alive and happy for point to point links */ @@ -1600,7 +1603,7 @@ static int q921_mdl_handle_ptp_error(struct pri *link, char error) q921_discard_iqueue(link); q921_establish_data_link(link); q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); - link->l3initiated = 1; + link->l3_initiated = 1; ctrl->schedev = 1; ctrl->ev.gen.e = PRI_EVENT_DCHAN_DOWN; @@ -1626,21 +1629,21 @@ static int q921_mdl_handle_ptp_error(struct pri *link, char error) return handled; } -static void q921_restart_ptp_link_if_needed(struct pri *link) +static void q921_restart_ptp_link_if_needed(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (PTP_MODE(ctrl)) { - q921_mdl_error(ctrl, 'Z'); + q921_mdl_error(&ctrl->link, 'Z'); } } -static void q921_mdl_handle_error(struct pri *link, char error, int errored_state) +static void q921_mdl_handle_error(struct q921_link *link, char error, int errored_state) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (PTP_MODE(ctrl)) { q921_mdl_handle_ptp_error(link, error); @@ -1655,7 +1658,7 @@ static void q921_mdl_handle_error(struct pri *link, char error, int errored_stat static void q921_mdl_handle_error_callback(void *vlink) { - struct pri *link = vlink; + struct q921_link *link = vlink; q921_mdl_handle_error(link, link->mdl_error, link->mdl_error_state); @@ -1664,22 +1667,19 @@ static void q921_mdl_handle_error_callback(void *vlink) if (link->mdl_free_me) { struct pri *ctrl; - struct pri *freep = NULL, *prev, *cur; + struct q921_link *freep; + struct q921_link *prev; - ctrl = PRI_MASTER(link); - prev = ctrl; - cur = ctrl->subchannel; + ctrl = link->ctrl; - while (cur) { - if (cur == link) { - prev->subchannel = cur->subchannel; - freep = cur; + freep = NULL; + for (prev = &ctrl->link; prev->next; prev = prev->next) { + if (prev->next == link) { + prev->next = link->next; + freep = link; break; } - prev = cur; - cur = cur->subchannel; } - if (freep == NULL) { pri_error(ctrl, "Huh!? no match found in list for TEI %d\n", -link->tei); return; @@ -1689,16 +1689,16 @@ static void q921_mdl_handle_error_callback(void *vlink) pri_message(ctrl, "Freeing TEI of %d\n", -freep->tei); } - __pri_free_tei(freep); + pri_link_destroy(freep); } } -static void q921_mdl_error(struct pri *link, char error) +static void q921_mdl_error(struct q921_link *link, char error) { int is_debug_q921_state; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; /* Log the MDL-ERROR event when detected. */ is_debug_q921_state = (ctrl->debug & PRI_DEBUG_Q921_STATE); @@ -1706,20 +1706,20 @@ static void q921_mdl_error(struct pri *link, char error) case 'A': pri_message(ctrl, "TEI=%d MDL-ERROR (A): Got supervisory frame with F=1 in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); break; case 'B': case 'E': pri_message(ctrl, "TEI=%d MDL-ERROR (%c): DM (F=%c) in state %d(%s)\n", link->tei, error, (error == 'B') ? '1' : '0', - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; case 'C': case 'D': if (is_debug_q921_state || PTP_MODE(ctrl)) { pri_message(ctrl, "TEI=%d MDL-ERROR (%c): UA (F=%c) in state %d(%s)\n", link->tei, error, (error == 'C') ? '1' : '0', - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); } break; case 'F': @@ -1738,7 +1738,7 @@ static void q921_mdl_error(struct pri *link, char error) * reasons 1-3 above. */ pri_message(ctrl, "TEI=%d MDL-ERROR (F): SABME in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); } break; case 'G': @@ -1746,7 +1746,7 @@ static void q921_mdl_error(struct pri *link, char error) if (is_debug_q921_state) { pri_message(ctrl, "TEI=%d MDL-ERROR (G): T200 expired N200 times sending SABME in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); } break; case 'H': @@ -1754,7 +1754,7 @@ static void q921_mdl_error(struct pri *link, char error) if (is_debug_q921_state) { pri_message(ctrl, "TEI=%d MDL-ERROR (H): T200 expired N200 times sending DISC in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); } break; case 'I': @@ -1762,13 +1762,13 @@ static void q921_mdl_error(struct pri *link, char error) if (is_debug_q921_state) { pri_message(ctrl, "TEI=%d MDL-ERROR (I): T200 expired N200 times sending RR/RNR in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); } break; case 'J': /* N(R) not within ack window. */ pri_error(ctrl, "TEI=%d MDL-ERROR (J): N(R) error in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); break; case 'K': /* @@ -1776,19 +1776,19 @@ static void q921_mdl_error(struct pri *link, char error) * The other end does not like what we are doing at all for some reason. */ pri_error(ctrl, "TEI=%d MDL-ERROR (K): FRMR in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); break; case 'Z': if (is_debug_q921_state) { /* Fake MDL-ERROR to kick start PTP L2 link back up. */ pri_message(ctrl, "TEI=%d MDL-ERROR (Z): Kick starting L2 link in state %d(%s)\n", - link->tei, link->q921_state, q921_state2str(link->q921_state)); + link->tei, link->state, q921_state2str(link->state)); } break; default: pri_message(ctrl, "TEI=%d MDL-ERROR (%c): in state %d(%s)\n", - link->tei, error, link->q921_state, q921_state2str(link->q921_state)); + link->tei, error, link->state, q921_state2str(link->state)); break; } @@ -1800,23 +1800,23 @@ static void q921_mdl_error(struct pri *link, char error) return; } link->mdl_error = error; - link->mdl_error_state = link->q921_state; + link->mdl_error_state = link->state; link->mdl_timer = pri_schedule_event(ctrl, 0, q921_mdl_handle_error_callback, link); } -static pri_event *q921_ua_rx(struct pri *link, q921_h *h) +static pri_event *q921_ua_rx(struct q921_link *link, q921_h *h) { struct pri *ctrl; pri_event *res = NULL; enum Q931_DL_EVENT delay_q931_dl_event; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Got UA\n", link->tei); } - switch (link->q921_state) { + switch (link->state) { case Q921_TEI_ASSIGNED: case Q921_MULTI_FRAME_ESTABLISHED: case Q921_TIMER_RECOVERY: @@ -1833,14 +1833,14 @@ static pri_event *q921_ua_rx(struct pri *link, q921_h *h) } delay_q931_dl_event = Q931_DL_EVENT_NONE; - if (!link->l3initiated) { + if (!link->l3_initiated) { if (link->v_s != link->v_a) { q921_discard_iqueue(link); /* DL-ESTABLISH indication */ delay_q931_dl_event = Q931_DL_EVENT_DL_ESTABLISH_IND; } } else { - link->l3initiated = 0; + link->l3_initiated = 0; /* DL-ESTABLISH confirm */ delay_q931_dl_event = Q931_DL_EVENT_DL_ESTABLISH_CONFIRM; } @@ -1873,20 +1873,20 @@ static pri_event *q921_ua_rx(struct pri *link, q921_h *h) break; default: pri_error(ctrl, "Don't know what to do with UA in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static void q921_enquiry_response(struct pri *link) +static void q921_enquiry_response(struct q921_link *link) { struct pri *ctrl; if (link->own_rx_busy) { /* XXX : TODO later sometime */ - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; pri_error(ctrl, "Implement me %s: own_rx_busy\n", __FUNCTION__); //q921_rnr(link); } else { @@ -1896,22 +1896,22 @@ static void q921_enquiry_response(struct pri *link) link->acknowledge_pending = 0; } -static void n_r_error_recovery(struct pri *link) +static void n_r_error_recovery(struct q921_link *link) { q921_mdl_error(link, 'J'); q921_establish_data_link(link); - link->l3initiated = 0; + link->l3_initiated = 0; } -static void update_v_a(struct pri *link, int n_r) +static void update_v_a(struct q921_link *link, int n_r) { int idealcnt = 0, realcnt = 0; int x; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; /* Cancel each packet as necessary */ if (ctrl->debug & PRI_DEBUG_Q921_DUMP) @@ -1928,7 +1928,7 @@ static void update_v_a(struct pri *link, int n_r) link->v_a = n_r; } -static int n_r_is_valid(struct pri *link, int n_r) +static int n_r_is_valid(struct q921_link *link, int n_r) { int x; @@ -1942,13 +1942,13 @@ static int n_r_is_valid(struct pri *link, int n_r) } } -static int q921_invoke_retransmission(struct pri *link, int n_r); +static int q921_invoke_retransmission(struct q921_link *link, int n_r); -static pri_event *timer_recovery_rr_rej_rx(struct pri *link, q921_h *h) +static pri_event *timer_recovery_rr_rej_rx(struct q921_link *link, q921_h *h) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; /* Figure B.7/Q.921 Page 74 */ link->peer_rx_busy = 0; @@ -1989,12 +1989,12 @@ n_r_error_out: return NULL; } -static pri_event *q921_rr_rx(struct pri *link, q921_h *h) +static pri_event *q921_rr_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; #if 0 /* Don't flood debug trace with RR if not really looking at Q.921 layer. */ if (ctrl->debug & PRI_DEBUG_Q921_STATE) { @@ -2002,7 +2002,7 @@ static pri_event *q921_rr_rx(struct pri *link, q921_h *h) } #endif - switch (link->q921_state) { + switch (link->state) { case Q921_TIMER_RECOVERY: res = timer_recovery_rr_rej_rx(link, h); break; @@ -2048,14 +2048,14 @@ static pri_event *q921_rr_rx(struct pri *link, q921_h *h) break; default: pri_error(ctrl, "Don't know what to do with RR in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static int q921_invoke_retransmission(struct pri *link, int n_r) +static int q921_invoke_retransmission(struct q921_link *link, int n_r) { int frames_txd = 0; int frames_supposed_to_tx = 0; @@ -2063,10 +2063,10 @@ static int q921_invoke_retransmission(struct pri *link, int n_r) unsigned int local_v_s = link->v_s; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; /* All acked frames should already have been removed from the queue. */ - for (f = link->txqueue; f && f->transmitted; f = f->next) { + for (f = link->tx_queue; f && f->transmitted; f = f->next) { if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Retransmitting frame N(S)=%d now!\n", link->tei, f->h.n_s); @@ -2090,18 +2090,18 @@ static int q921_invoke_retransmission(struct pri *link, int n_r) return frames_txd; } -static pri_event *q921_rej_rx(struct pri *link, q921_h *h) +static pri_event *q921_rej_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Got REJ N(R)=%d\n", link->tei, h->s.n_r); } - switch (link->q921_state) { + switch (link->state) { case Q921_TIMER_RECOVERY: res = timer_recovery_rr_rej_rx(link, h); break; @@ -2140,30 +2140,30 @@ static pri_event *q921_rej_rx(struct pri *link, q921_h *h) break; default: pri_error(ctrl, "Don't know what to do with REJ in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static pri_event *q921_frmr_rx(struct pri *link, q921_h *h) +static pri_event *q921_frmr_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Got FRMR\n", link->tei); } - switch (link->q921_state) { + switch (link->state) { case Q921_TIMER_RECOVERY: case Q921_MULTI_FRAME_ESTABLISHED: q921_mdl_error(link, 'K'); q921_establish_data_link(link); - link->l3initiated = 0; + link->l3_initiated = 0; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); break; case Q921_TEI_ASSIGNED: @@ -2179,23 +2179,23 @@ static pri_event *q921_frmr_rx(struct pri *link, q921_h *h) break; default: pri_error(ctrl, "Don't know what to do with FRMR in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static pri_event *q921_iframe_rx(struct pri *link, q921_h *h, int len) +static pri_event *q921_iframe_rx(struct q921_link *link, q921_h *h, int len) { struct pri *ctrl; pri_event *eres = NULL; int res = 0; int delay_q931_receive; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; - switch (link->q921_state) { + switch (link->state) { case Q921_TIMER_RECOVERY: case Q921_MULTI_FRAME_ESTABLISHED: delay_q931_receive = 0; @@ -2240,7 +2240,7 @@ static pri_event *q921_iframe_rx(struct pri *link, q921_h *h, int len) n_r_error_recovery(link); q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); } else { - if (link->q921_state == Q921_TIMER_RECOVERY) { + if (link->state == Q921_TIMER_RECOVERY) { update_v_a(link, h->i.n_r); } else { if (link->peer_rx_busy) { @@ -2277,31 +2277,31 @@ static pri_event *q921_iframe_rx(struct pri *link, q921_h *h, int len) break; default: pri_error(ctrl, "Don't know what to do with an I-frame in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return eres; } -static pri_event *q921_dm_rx(struct pri *link, q921_h *h) +static pri_event *q921_dm_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Got DM\n", link->tei); } - switch (link->q921_state) { + switch (link->state) { case Q921_TEI_ASSIGNED: if (h->u.p_f) break; /* else */ q921_establish_data_link(link); - link->l3initiated = 1; + link->l3_initiated = 1; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); break; case Q921_AWAITING_ESTABLISHMENT: @@ -2331,7 +2331,7 @@ static pri_event *q921_dm_rx(struct pri *link, q921_h *h) q921_mdl_error(link, 'E'); q921_establish_data_link(link); - link->l3initiated = 0; + link->l3_initiated = 0; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); break; case Q921_TIMER_RECOVERY: @@ -2341,30 +2341,30 @@ static pri_event *q921_dm_rx(struct pri *link, q921_h *h) q921_mdl_error(link, 'E'); } q921_establish_data_link(link); - link->l3initiated = 0; + link->l3_initiated = 0; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); break; default: pri_error(ctrl, "Don't know what to do with DM frame in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static pri_event *q921_rnr_rx(struct pri *link, q921_h *h) +static pri_event *q921_rnr_rx(struct q921_link *link, q921_h *h) { pri_event *res = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, "TEI=%d Got RNR N(R)=%d\n", link->tei, h->s.n_r); } - switch (link->q921_state) { + switch (link->state) { case Q921_MULTI_FRAME_ESTABLISHED: link->peer_rx_busy = 1; if (!is_command(ctrl, h)) { @@ -2436,14 +2436,14 @@ static pri_event *q921_rnr_rx(struct pri *link, q921_h *h) break; default: pri_error(ctrl, "Don't know what to do with RNR in state %d(%s)\n", - link->q921_state, q921_state2str(link->q921_state)); + link->state, q921_state2str(link->state)); break; } return res; } -static void q921_acknowledge_pending_check(struct pri *link) +static void q921_acknowledge_pending_check(struct q921_link *link) { if (link->acknowledge_pending) { link->acknowledge_pending = 0; @@ -2451,9 +2451,9 @@ static void q921_acknowledge_pending_check(struct pri *link) } } -static void q921_statemachine_check(struct pri *link) +static void q921_statemachine_check(struct q921_link *link) { - switch (link->q921_state) { + switch (link->state) { case Q921_MULTI_FRAME_ESTABLISHED: q921_send_queued_iframes(link); q921_acknowledge_pending_check(link); @@ -2466,13 +2466,13 @@ static void q921_statemachine_check(struct pri *link) } } -static pri_event *__q921_receive_qualified(struct pri *link, q921_h *h, int len) +static pri_event *__q921_receive_qualified(struct q921_link *link, q921_h *h, int len) { int res; pri_event *ev = NULL; struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; switch(h->h.data[0] & Q921_FRAMETYPE_MASK) { case 0: @@ -2580,7 +2580,7 @@ static pri_event *q921_handle_unmatched_frame(struct pri *ctrl, q921_h *h, int l if (BRI_NT_PTMP(ctrl)) { if (ctrl->debug & PRI_DEBUG_Q921_STATE) { pri_message(ctrl, - "Could not find candidate subchannel for received frame with SAPI/TEI of %d/%d.\n", + "Could not find a layer 2 link for received frame with SAPI/TEI of %d/%d.\n", h->h.sapi, h->h.tei); pri_message(ctrl, "Sending TEI release, in order to re-establish TEI state\n"); } @@ -2597,7 +2597,7 @@ static pri_event *q921_handle_unmatched_frame(struct pri *ctrl, q921_h *h, int l static pri_event *__q921_receive(struct pri *ctrl, q921_h *h, int len) { pri_event *ev = NULL; - struct pri *link; + struct q921_link *link; /* Discard FCS */ len -= 2; @@ -2621,14 +2621,15 @@ static pri_event *__q921_receive(struct pri *ctrl, q921_h *h, int len) } if (BRI_TE_PTMP(ctrl)) { - link = ctrl->subchannel; + /* We're operating on the specific TEI link */ + link = ctrl->link.next; if (h->h.sapi == link->sapi - && ((link->q921_state >= Q921_TEI_ASSIGNED + && ((link->state >= Q921_TEI_ASSIGNED && h->h.tei == link->tei) || h->h.tei == Q921_TEI_GROUP)) { ev = __q921_receive_qualified(link, h, len); } - /* Only support reception on our single subchannel */ + /* Only support reception on our specific TEI link */ } else if (BRI_NT_PTMP(ctrl)) { link = pri_find_tei(ctrl, h->h.sapi, h->h.tei); if (link) { @@ -2636,8 +2637,9 @@ static pri_event *__q921_receive(struct pri *ctrl, q921_h *h, int len) } else { ev = q921_handle_unmatched_frame(ctrl, h, len); } - } else if (PTP_MODE(ctrl) && (h->h.sapi == ctrl->sapi) && (h->h.tei == ctrl->tei)) { - ev = __q921_receive_qualified(ctrl, h, len); + } else if (PTP_MODE(ctrl) + && h->h.sapi == ctrl->link.sapi && h->h.tei == ctrl->link.tei) { + ev = __q921_receive_qualified(&ctrl->link, h, len); } else { ev = NULL; } @@ -2659,7 +2661,7 @@ pri_event *q921_receive(struct pri *ctrl, q921_h *h, int len) return e; } -static void q921_establish_data_link(struct pri *link) +static void q921_establish_data_link(struct q921_link *link) { q921_clear_exception_conditions(link); link->RC = 0; @@ -2676,11 +2678,11 @@ static void nt_ptmp_dchannel_up(void *vpri) ctrl->ev.gen.e = PRI_EVENT_DCHAN_UP; } -void q921_start(struct pri *link) +void q921_start(struct q921_link *link) { struct pri *ctrl; - ctrl = PRI_MASTER(link); + ctrl = link->ctrl; if (PTMP_MODE(ctrl)) { if (TE_MODE(ctrl)) { q921_setstate(link, Q921_ASSIGN_AWAITING_TEI); @@ -2692,7 +2694,7 @@ void q921_start(struct pri *link) } else { /* PTP mode, no need for TEI management junk */ q921_establish_data_link(link); - link->l3initiated = 1; + link->l3_initiated = 1; q921_setstate(link, Q921_AWAITING_ESTABLISHMENT); } } diff --git a/q931.c b/q931.c index 34fafeb..764dfd8 100644 --- a/q931.c +++ b/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,