forked from retronetworking/osmo-v5
Dynamically open and close b-channels depending on the usage
This commit is contained in:
parent
a4483db3af
commit
ebfab5792d
52
src/layer1.c
52
src/layer1.c
|
@ -261,11 +261,11 @@ static void raw_rx_cb(struct e1inp_ts *ts, struct msgb *msg)
|
|||
osmo_revbytebits_buf(msg->data, msg->len);
|
||||
|
||||
/* if assigned and active, send B-channel data to socket interface */
|
||||
if (v5up->ts[0] && v5up->ts[0]->nr == ts->num && v5up->ts_activated[0]) {
|
||||
if (v5up->ts[0] && v5up->ts[0]->nr == ts->num && v5up->ts[0]->b_activated) {
|
||||
echo_rx(&v5up->ep[0], msg->data, msg->len);
|
||||
ph_socket_tx_msg(&v5up->ph_socket, 1, PH_PRIM_DATA_IND, msg->data, msg->len);
|
||||
}
|
||||
if (v5up->ts[1] && v5up->ts[1]->nr == ts->num && v5up->ts_activated[1]) {
|
||||
if (v5up->ts[1] && v5up->ts[1]->nr == ts->num && v5up->ts[1]->b_activated) {
|
||||
echo_rx(&v5up->ep[1], msg->data, msg->len);
|
||||
ph_socket_tx_msg(&v5up->ph_socket, 2, PH_PRIM_DATA_IND, msg->data, msg->len);
|
||||
}
|
||||
|
@ -355,6 +355,50 @@ int ph_data_req_dl_prot(struct msgb *msg, void *cbdata)
|
|||
return e1inp_ts_send_hdlc(ts, msg);
|
||||
}
|
||||
|
||||
int ph_activate_req(struct v5x_timeslot *ts)
|
||||
{
|
||||
struct e1inp_line *e1_line;
|
||||
struct e1inp_ts *e1_ts;
|
||||
int rc;
|
||||
|
||||
if (ts->b_activated)
|
||||
return 0;
|
||||
|
||||
e1_line = e1_line_from_link(ts->link);
|
||||
if (!e1_line)
|
||||
return -EINVAL;
|
||||
e1_ts = &e1_line->ts[ts->nr - 1];
|
||||
|
||||
e1inp_ts_config_raw(e1_ts, e1_line, raw_rx_cb);
|
||||
rc = e1inp_line_update(e1_line);
|
||||
|
||||
ts->b_activated = 1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ph_deactivate_req(struct v5x_timeslot *ts)
|
||||
{
|
||||
struct e1inp_line *e1_line;
|
||||
struct e1inp_ts *e1_ts;
|
||||
int rc;
|
||||
|
||||
if (!ts->b_activated)
|
||||
return 0;
|
||||
|
||||
e1_line = e1_line_from_link(ts->link);
|
||||
if (!e1_line)
|
||||
return -EINVAL;
|
||||
e1_ts = &e1_line->ts[ts->nr - 1];
|
||||
|
||||
e1_ts->type = E1INP_TS_TYPE_NONE;
|
||||
rc = e1inp_line_update(e1_line);
|
||||
|
||||
ts->b_activated = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send raw (B-channel) data to E1 interface */
|
||||
static int ph_data_req_raw(struct v5x_link *v5l, struct msgb *msg, int ts_nr)
|
||||
{
|
||||
|
@ -414,7 +458,7 @@ void ph_socket_rx_cb(ph_socket_t *s, int channel, uint8_t prim, uint8_t *data, i
|
|||
struct msgb *msg = msgb_alloc_headroom(length + 32, 32, "V5 EF MSG");
|
||||
memcpy(msgb_put(msg, length), data, length);
|
||||
lapv5ef_tx(v5up, msg);
|
||||
} else if ((channel == 1 || channel == 2) && v5up->ts[channel - 1]) {
|
||||
} else if ((channel == 1 || channel == 2) && v5up->ts[channel - 1] && v5up->ts[channel - 1]->b_activated) {
|
||||
echo_tx(&v5up->ep[channel - 1], data, length);
|
||||
struct msgb *msg = msgb_alloc_headroom(length + 32, 32, "B MSG");
|
||||
memcpy(msgb_put(msg, length), data, length);
|
||||
|
@ -471,7 +515,7 @@ int e1_init(void)
|
|||
//e1inp_sign_link_create(e1_ts, E1INP_SIGN_NONE, NULL, 115/*TEI*/, 0/*SAPI*/);
|
||||
e1inp_ts_config_hdlc(e1_ts, e1_line, hdlc_rx_cb);
|
||||
} else
|
||||
e1inp_ts_config_raw(e1_ts, e1_line, raw_rx_cb);
|
||||
e1_ts->type = E1INP_TS_TYPE_NONE;
|
||||
}
|
||||
|
||||
e1inp_line_update(e1_line);
|
||||
|
|
|
@ -11,6 +11,8 @@ enum l1_signal_prim {
|
|||
};
|
||||
|
||||
int v5x_l1_signal_snd(struct v5x_link *v5l, enum l1_signal_prim prim);
|
||||
int ph_activate_req(struct v5x_timeslot *ts);
|
||||
int ph_deactivate_req(struct v5x_timeslot *ts);
|
||||
int ph_data_req_hdlc(struct msgb *msg, struct v5x_interface *v5if);
|
||||
int ph_data_req_dl_cc(struct msgb *msg, void *cbdata);
|
||||
int ph_data_req_dl_prot(struct msgb *msg, void *cbdata);
|
||||
|
|
|
@ -654,9 +654,9 @@ DEFUN(cfg_echo, cfg_echo_cmd,
|
|||
struct v5x_user_port *v5up = vty->index;
|
||||
|
||||
v5up->echo_configured = 1;
|
||||
if (v5up->ts_activated[0])
|
||||
if (v5up->ts[0] && v5up->ts[0]->b_activated)
|
||||
v5x_echo_reset(&v5up->ep[0], v5up->echo_configured);
|
||||
if (v5up->ts_activated[1])
|
||||
if (v5up->ts[1] && v5up->ts[1]->b_activated)
|
||||
v5x_echo_reset(&v5up->ep[1], v5up->echo_configured);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -668,9 +668,9 @@ DEFUN(cfg_no_echo, cfg_no_echo_cmd,
|
|||
struct v5x_user_port *v5up = vty->index;
|
||||
|
||||
v5up->echo_configured = 0;
|
||||
if (v5up->ts_activated[0])
|
||||
if (v5up->ts[0] && v5up->ts[0]->b_activated)
|
||||
v5x_echo_reset(&v5up->ep[0], v5up->echo_configured);
|
||||
if (v5up->ts_activated[1])
|
||||
if (v5up->ts[1] && v5up->ts[1]->b_activated)
|
||||
v5x_echo_reset(&v5up->ep[1], v5up->echo_configured);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -166,11 +166,11 @@ int v5x_link_destroy(struct v5x_link *v5l)
|
|||
if ((v5up = v5l->ts[i].v5up)) {
|
||||
if (v5up->ts[0] == &v5l->ts[i]) {
|
||||
v5up->ts[0] = NULL;
|
||||
v5up->ts_activated[0] = 0;
|
||||
ph_deactivate_req(&v5l->ts[i]);
|
||||
}
|
||||
if (v5up->ts[1] == &v5l->ts[i]) {
|
||||
v5up->ts[1] = NULL;
|
||||
v5up->ts_activated[1] = 0;
|
||||
ph_deactivate_req(&v5l->ts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,7 @@ struct v5x_timeslot {
|
|||
struct v5x_link *link; /* back-pointer */
|
||||
struct v5x_user_port *v5up; /* user port that this TS is assigned to */
|
||||
bool b_channel; /* channel can be used as b-channel */
|
||||
bool b_activated; /* activated (b-channel) at libosmo-abis */
|
||||
};
|
||||
|
||||
/* one physical E1 interface used within a V5.2 interface */
|
||||
|
@ -281,7 +282,6 @@ struct v5x_user_port {
|
|||
struct v5x_ctrl_proto *ctrl; /* port control protocol instance */
|
||||
struct osmo_fsm_inst *port_fi; /* port FSM */
|
||||
struct v5x_timeslot *ts[2]; /* two time slots */
|
||||
uint8_t ts_activated[2]; /* set if data stream is active */
|
||||
struct {
|
||||
} isdn;
|
||||
struct {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "v52_le_bcc_fsm.h"
|
||||
#include "v52_le_pp_fsm.h"
|
||||
#include "v5x_le_management.h"
|
||||
#include "layer1.h"
|
||||
#include "logging.h"
|
||||
|
||||
void v5x_le_mgmt_init(void)
|
||||
|
@ -438,11 +439,11 @@ static void flush_link(struct v5x_link *v5l)
|
|||
if ((v5up = v5l->ts[t].v5up)) {
|
||||
if (v5up->ts[0] == &v5l->ts[t]) {
|
||||
v5up->ts[0] = NULL;
|
||||
v5up->ts_activated[0] = 0;
|
||||
ph_deactivate_req(&v5l->ts[t]);
|
||||
}
|
||||
if (v5up->ts[1] == &v5l->ts[t]) {
|
||||
v5up->ts[1] = NULL;
|
||||
v5up->ts_activated[1] = 0;
|
||||
ph_deactivate_req(&v5l->ts[t]);
|
||||
}
|
||||
v5l->ts[t].v5up = NULL;
|
||||
}
|
||||
|
@ -564,18 +565,18 @@ void v5x_le_channel_assign(struct v5x_user_port *v5up, int channel)
|
|||
"%d.\n", (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5l->id);
|
||||
return;
|
||||
}
|
||||
if (v5up->ts_activated[channel - 1])
|
||||
if (v5up->ts[channel - 1]->b_activated)
|
||||
return;
|
||||
LOGP(DV5MGMT, LOGL_DEBUG, "Activating channel %d for %s port %d at TS %d of link %d.\n",
|
||||
channel, (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr,
|
||||
v5up->ts[channel - 1]->nr, v5up->ts[channel - 1]->link->id);
|
||||
v5up->ts_activated[channel - 1] = 1;
|
||||
ph_activate_req(v5up->ts[channel - 1]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* channel already assigned, just activate it, if not already */
|
||||
if (v5up->ts[channel - 1]) {
|
||||
v5up->ts_activated[channel - 1] = 1;
|
||||
ph_activate_req(v5up->ts[channel - 1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -620,27 +621,27 @@ void v5x_le_channel_unassign(struct v5x_user_port *v5up, int channel)
|
|||
|
||||
/* the channels are pre-assigned with V5.1, so only activation state is set */
|
||||
if (v5if->dialect == V5X_DIALECT_V51) {
|
||||
if (!v5up->ts_activated[channel - 1])
|
||||
return;
|
||||
if (!v5up->ts[channel - 1]) {
|
||||
LOGP(DV5MGMT, LOGL_ERROR, "Cannot deactivate channel, because no TS is assigned for %s port "
|
||||
"%d.\n", (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr);
|
||||
return;
|
||||
}
|
||||
if (!v5up->ts[channel - 1]->b_activated)
|
||||
return;
|
||||
LOGP(DV5MGMT, LOGL_DEBUG, "Deactivating channel %d for %s port %d at TS %d of link %d.\n",
|
||||
channel, (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr,
|
||||
v5up->ts[channel - 1]->nr, v5up->ts[channel - 1]->link->id);
|
||||
v5up->ts_activated[channel - 1] = 0;
|
||||
ph_deactivate_req(v5up->ts[channel - 1]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* deactivate */
|
||||
v5up->ts_activated[channel - 1] = 0;
|
||||
|
||||
/* if not assigned */
|
||||
if (!v5up->ts[channel - 1])
|
||||
return;
|
||||
|
||||
/* deactivate */
|
||||
ph_deactivate_req(v5up->ts[channel - 1]);
|
||||
|
||||
/* unassign or abort ongoing BCC allocation */
|
||||
v52_le_bcc_mdu_snd(v5if, v5up->nr, v5up->type == V5X_USER_TYPE_ISDN, v5up->ts[channel - 1]->link->id,
|
||||
v5up->ts[channel - 1]->nr, 1, channel, NULL, 0, MDU_BCC_deallocation_req);
|
||||
|
@ -679,7 +680,7 @@ int v52_le_bcc_mdu_rcv(struct v5x_interface *v5if, uint8_t link_id, uint8_t ts,
|
|||
case MDU_BCC_allocation_conf:
|
||||
LOGP(DV5MGMT, LOGL_INFO, "Assigned channel %d for %s port %d at TS %d of link %d.\n",
|
||||
channel, (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr, ts, link_id);
|
||||
v5up->ts_activated[channel - 1] = 1;
|
||||
ph_activate_req(v5up->ts[channel - 1]);
|
||||
break;
|
||||
case MDU_BCC_deallocation_conf:
|
||||
LOGP(DV5MGMT, LOGL_INFO, "Unassigned channel %d for %s port %d at TS %d of link %d.\n",
|
||||
|
|
Loading…
Reference in New Issue