Commit f9c3c8d0 authored by Richard Mudgett's avatar Richard Mudgett

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
parent 53c14299
This diff is collapsed.
......@@ -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;
}
}
......
......@@ -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 = &current->next, current = current->next) {
if (current == doomed) {
......@@ -413,7 +405,6 @@ struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
struct pri_cc_record *cc_record;
long record_id;
ctrl = PRI_MASTER(ctrl);
record_id = pri_cc_new_id(ctrl);
if (record_id < 0) {
return NULL;
......@@ -424,7 +415,7 @@ struct pri_cc_record *pri_cc_new_record(struct pri *ctrl, q931_call *call)
}
/* Initialize the new record */
cc_record->master = ctrl;
cc_record->ctrl = ctrl;
cc_record->record_id = record_id;
cc_record->call_linkage_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
cc_record->ccbs_reference_id = CC_PTMP_INVALID_ID;/* So it will never be found this way */
......@@ -975,7 +966,7 @@ static unsigned char *enc_qsig_cc_request(struct pri *ctrl,
//msg.args.qsig.CcbsRequest.can_retain_service = 0;
switch (PRI_MASTER(ctrl)->cc.option.signaling_retention_req) {
switch (ctrl->cc.option.signaling_retention_req) {
case 0:/* Want release signaling link. */
cc_record->option.retain_signaling_link = 0;
......@@ -1954,7 +1945,6 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
struct q931_party_number party_a_number;
const struct pri_cc_record *cc_record;
unsigned char *new_pos;
struct pri *master;
unsigned idx;
pos = facility_encode_header(ctrl, pos, end, NULL);
......@@ -1966,8 +1956,7 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
msg.invoke_id = invoke->invoke_id;
msg.operation = invoke->operation;
master = PRI_MASTER(ctrl);
msg.args.etsi.CCBSInterrogate.recall_mode = master->cc.option.recall_mode;
msg.args.etsi.CCBSInterrogate.recall_mode = ctrl->cc.option.recall_mode;
/* Convert the given party A number. */
q931_party_number_init(&party_a_number);
......@@ -1979,7 +1968,7 @@ static unsigned char *enc_etsi_ptmp_cc_interrogate_rsp_general(struct pri *ctrl,
/* Build the CallDetails list. */
idx = 0;
for (cc_record = master->cc.pool; cc_record; cc_record = cc_record->next) {
for (cc_record = ctrl->cc.pool; cc_record; cc_record = cc_record->next) {
if (cc_record->ccbs_reference_id == CC_PTMP_INVALID_ID
|| (!cc_record->is_ccnr) != (invoke->operation == ROSE_ETSI_CCBSInterrogate)) {
/*
......@@ -2087,7 +2076,7 @@ int pri_cc_interrogate_rsp(struct pri *ctrl, q931_call *call, const struct rose_
{
int encode_result;
if (!PRI_MASTER(ctrl)->cc_support) {
if (!ctrl->cc_support) {
/* Call completion is disabled. */
return send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
......@@ -2134,7 +2123,7 @@ void pri_cc_ptmp_request(struct pri *ctrl, q931_call *call, const struct rose_ms
{
struct pri_cc_record *cc_record;
if (!PRI_MASTER(ctrl)->cc_support) {
if (!ctrl->cc_support) {
/* Call completion is disabled. */
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
......@@ -2191,7 +2180,7 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
/* Ignore CC request message since it did not come in on the correct message. */
return;
}
if (!PRI_MASTER(ctrl)->cc_support) {
if (!ctrl->cc_support) {
/* Call completion is disabled. */
rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
......@@ -2270,7 +2259,6 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
*/
void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const struct rose_msg_invoke *invoke)
{
struct pri *master;
struct pri_cc_record *cc_record;
struct q931_party_address party_a;
struct q931_party_address party_b;
......@@ -2279,8 +2267,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
/* Ignore CC request message since it did not come in on the correct message. */
return;
}
master = PRI_MASTER(ctrl);
if (!master->cc_support) {
if (!ctrl->cc_support) {
/* Call completion is disabled. */
rose_error_msg_encode(ctrl, call, Q931_ANY_MESSAGE, invoke->invoke_id,
ROSE_ERROR_QSIG_LongTermRejection);
......@@ -2302,7 +2289,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
rose_copy_subaddress_to_q931(ctrl, &party_b.subaddress,
&invoke->args.qsig.CcbsRequest.subaddr_b);
cc_record = pri_cc_find_by_addressing(master, &party_a, &party_b,
cc_record = pri_cc_find_by_addressing(ctrl, &party_a, &party_b,
invoke->args.qsig.CcbsRequest.q931ie.length,
invoke->args.qsig.CcbsRequest.q931ie.contents);
if (!cc_record || cc_record->state != CC_STATE_AVAILABLE) {
......@@ -2321,7 +2308,7 @@ void pri_cc_qsig_request(struct pri *ctrl, q931_call *call, int msgtype, const s
} else {
/* The originator does not care. Do how we are configured. */
cc_record->option.retain_signaling_link =
master->cc.option.signaling_retention_rsp;
ctrl->cc.option.signaling_retention_rsp;
}
if (!cc_record->party_a.number.valid || cc_record->party_a.number.str[0] == '\0') {
/*
......@@ -2805,7 +2792,7 @@ static void pri_cc_timeout_t_retention(void *data)
struct pri_cc_record *cc_record = data;
cc_record->t_retention = 0;
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RETENTION);
}
/*!
......@@ -2857,7 +2844,7 @@ static void pri_cc_timeout_extended_t_ccbs1(void *data)
struct pri_cc_record *cc_record = data;
cc_record->fsm.ptmp.extended_t_ccbs1 = 0;
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_EXTENDED_T_CCBS1);
}
/*!
......@@ -2911,7 +2898,7 @@ static void pri_cc_timeout_t_supervision(void *data)
struct pri_cc_record *cc_record = data;
cc_record->t_supervision = 0;
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_SUPERVISION);
}
/*!
......@@ -2991,7 +2978,7 @@ static void pri_cc_timeout_t_recall(void *data)
struct pri_cc_record *cc_record = data;
cc_record->t_recall = 0;
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_TIMEOUT_T_RECALL);
}
/*!
......@@ -3755,7 +3742,7 @@ static void pri_cc_indirect_status_rsp_a(void *data)
struct pri_cc_record *cc_record = data;
cc_record->t_indirect = 0;
q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_rsp_a);
q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_rsp_a);
}
/*!
......@@ -3904,7 +3891,7 @@ static void pri_cc_indirect_status_a(void *data)
struct pri_cc_record *cc_record = data;
cc_record->t_indirect = 0;
q931_cc_indirect(cc_record->master, cc_record, pri_cc_fill_status_a);
q931_cc_indirect(cc_record->ctrl, cc_record, pri_cc_fill_status_a);
}
/*!
......@@ -4261,7 +4248,7 @@ static void pri_cc_post_hangup_signaling(void *data)
struct pri_cc_record *cc_record = data;
cc_record->t_indirect = 0;
q931_cc_timeout(cc_record->master, cc_record, CC_EVENT_HANGUP_SIGNALING);
q931_cc_timeout(cc_record->ctrl, cc_record, CC_EVENT_HANGUP_SIGNALING);
}
/*!
......@@ -6850,7 +6837,7 @@ long pri_cc_available(struct pri *ctrl, q931_call *call)
break;
}
cc_record->call_linkage_id = linkage_id;
cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
cc_record->signaling = ctrl->link.dummy_call;
} else {
cc_record = pri_cc_new_record(ctrl, call);
if (!cc_record) {
......@@ -6894,7 +6881,7 @@ void pri_cc_qsig_determine_available(struct pri *ctrl, q931_call *call)
return;
}
if (!PRI_MASTER(ctrl)->cc_support) {
if (!ctrl->cc_support) {
/*
* Blocking the cc-available event effectively
* disables call completion for outgoing calls.
......
......@@ -1859,7 +1859,7 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
if (!BRI_NT_PTMP(ctrl)) {
return -1;
}
call = PRI_MASTER(ctrl)->dummy_call;
call = ctrl->link.dummy_call;
if (!call) {
return -1;
}
......@@ -3825,7 +3825,6 @@ int pri_mcid_req_send(struct pri *ctrl, q931_call *call)
void pri_mcid_enable(struct pri *ctrl, int enable)
{
if (ctrl) {
ctrl = PRI_MASTER(ctrl);
ctrl->mcid_support = enable ? 1 : 0;
}
}
......@@ -3882,7 +3881,7 @@ void rose_handle_reject(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
* Look for the original invocation message on the
* broadcast dummy call reference call first.
*/
orig_call = PRI_MASTER(ctrl)->dummy_call;
orig_call = ctrl->link.dummy_call;
if (orig_call) {
apdu = pri_call_apdu_find(orig_call, reject->invoke_id);
}
......@@ -3966,7 +3965,7 @@ void rose_handle_error(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *
* Look for the original invocation message on the
* broadcast dummy call reference call first.
*/
orig_call = PRI_MASTER(ctrl)->dummy_call;
orig_call = ctrl->link.dummy_call;
if (orig_call) {
apdu = pri_call_apdu_find(orig_call, error->invoke_id);
}
......@@ -4042,7 +4041,7 @@ void rose_handle_result(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
* Look for the original invocation message on the
* broadcast dummy call reference call first.
*/
orig_call = PRI_MASTER(ctrl)->dummy_call;
orig_call = ctrl->link.dummy_call;
if (orig_call) {
apdu = pri_call_apdu_find(orig_call, result->invoke_id);
}
......@@ -4099,7 +4098,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
break;
#endif /* Not handled yet */
case ROSE_ETSI_CallDeflection:
if (!PRI_MASTER(ctrl)->deflection_support) {
if (!ctrl->deflection_support) {
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
break;
......@@ -4167,7 +4166,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
&deflection);
break;
case ROSE_ETSI_CallRerouting:
if (!PRI_MASTER(ctrl)->deflection_support) {
if (!ctrl->deflection_support) {
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
break;
......@@ -4365,7 +4364,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
break;
#endif /* Not handled yet */
case ROSE_ETSI_EctExecute:
if (!PRI_MASTER(ctrl)->transfer_support) {
if (!ctrl->transfer_support) {
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
break;
......@@ -4390,7 +4389,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
break;
#endif /* Not handled yet */
case ROSE_ETSI_EctLinkIdRequest:
if (!PRI_MASTER(ctrl)->transfer_support) {
if (!ctrl->transfer_support) {
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_ResourceUnavailable);
break;
......@@ -4430,7 +4429,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
break;
#endif /* defined(STATUS_REQUEST_PLACE_HOLDER) */
case ROSE_ETSI_CallInfoRetain:
if (!PRI_MASTER(ctrl)->cc_support) {
if (!ctrl->cc_support) {
/*
* Blocking the cc-available event effectively
* disables call completion for outgoing calls.
......@@ -4445,7 +4444,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
if (!cc_record) {
break;
}
cc_record->signaling = PRI_MASTER(ctrl)->dummy_call;
cc_record->signaling = ctrl->link.dummy_call;
/*
* Since we received this facility, we will not be allocating any
* reference and linkage id's.
......@@ -4645,7 +4644,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
pri_cc_event(ctrl, call, cc_record, CC_EVENT_REMOTE_USER_FREE);
break;
case ROSE_ETSI_CCBS_T_Available:
if (!PRI_MASTER(ctrl)->cc_support) {
if (!ctrl->cc_support) {
/*
* Blocking the cc-available event effectively
* disables call completion for outgoing calls.
......@@ -4669,7 +4668,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
/* Don't even dignify this with a response. */
break;
}
if (!PRI_MASTER(ctrl)->mcid_support) {
if (!ctrl->mcid_support) {
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
break;
......@@ -4877,7 +4876,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
break;
#endif /* Not handled yet */
case ROSE_QSIG_CallRerouting:
if (!PRI_MASTER(ctrl)->deflection_support) {
if (!ctrl->deflection_support) {
send_facility_error(ctrl, call, invoke->invoke_id,
ROSE_ERROR_Gen_NotSubscribed);
break;
......
......@@ -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;
}
......
......@@ -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