Work on v5x_le_pstn_fsm.c

This commit is contained in:
Andreas Eversberg 2022-12-26 14:44:39 +01:00
parent fe66653df6
commit 5f227fb417
2 changed files with 157 additions and 126 deletions

View File

@ -131,7 +131,7 @@ static struct msgb *v5x_enc_establish(struct v5x_user_port *v5up, uint8_t *cond_
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_ESTABLISH;
/* optional conditional IE */
@ -151,7 +151,7 @@ static struct msgb *v5x_enc_establish_ack(struct v5x_user_port *v5up, uint8_t *c
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_ESTABLISH_ACK;
/* optional conditional IE */
@ -172,7 +172,7 @@ static struct msgb *v5x_enc_signal(struct v5x_user_port *v5up, uint8_t seq_nr, u
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_SIGNAL;
/* Sequence-number */
@ -195,7 +195,7 @@ static struct msgb *v5x_enc_signal_ack(struct v5x_user_port *v5up, uint8_t seq_n
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_SIGNAL_ACK;
/* Sequence-number */
@ -214,7 +214,7 @@ static struct msgb *v5x_enc_status_enquiry(struct v5x_user_port *v5up)
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_STATUS_ENQUIRY;
return msg;
@ -230,7 +230,7 @@ static struct msgb *v5x_enc_disconnect(struct v5x_user_port *v5up, uint8_t *stea
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_DISCONNECT;
/* optional conditional IE */
@ -250,7 +250,7 @@ static struct msgb *v5x_enc_disconnect_compl(struct v5x_user_port *v5up, uint8_t
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_DISCONNECT_COMPLETE;
/* optional conditional IE */
@ -271,7 +271,7 @@ static struct msgb *v5x_enc_protocol_param(struct v5x_user_port *v5up, uint8_t s
l3h = (struct v5x_l3_hdr *) msgb_put(msg, sizeof(*l3h));
l3h->pdisc = V5X_CTRL_PDISC;
l3h->l3_addr = ntohs(v5x_l3_addr_enc(v5up->nr, false));
l3h->l3_addr = htons(v5x_l3_addr_enc(v5up->nr, false));
l3h->msg_type = V5X_CTRL_MSGT_PROTOCOL_PARAMETER;
/* Sequence-number */
@ -343,16 +343,98 @@ static void rcv_fe(struct osmo_fsm_inst *fi, enum v5x_fe_prim prim, const struct
}
}
v5x_pstn_rcv_fe(pstn->v5up, prim, msg);
v5x_le_pstn_fe_rcv(pstn->v5up, prim, msg);
}
static void rcv_mdu(struct osmo_fsm_inst *fi, enum v5x_mgmt_prim prim)
{
struct v5x_pstn_proto *pstn = fi->priv;
v5x_pstn_rcv_mdu(pstn->v5up, prim);
v5x_le_pstn_mdu_rcv(pstn->v5up, prim);
}
void v5x_le_pstn_fe_snd(struct v5x_user_port *v5up, enum v5x_fe_prim prim, struct msgb *msg)
{
struct v5x_pstn_proto *pstn = v5up->pstn.proto;
struct osmo_fsm_inst *fi = pstn->fi;
enum v5x_le_pstn_fsm_event event;
int rc;
OSMO_ASSERT(msg);
switch (prim) {
case FE_establish_req:
event = V5x_PSTN_LE_FE_establish_req;
break;
case FE_establish_ack_req:
event = V5x_PSTN_LE_FE_establish_ack_req;
break;
case FE_line_signal_req:
event = V5x_PSTN_LE_FE_line_signal_req;
break;
case FE_protocol_param_req:
event = V5x_PSTN_LE_FE_protocol_param_req;
break;
case FE_disconnect_req:
event = V5x_PSTN_LE_FE_disconnect_req;
break;
case FE_disconnect_compl_req:
event = V5x_PSTN_LE_FE_disconnect_compl_req;
break;
default:
LOGP(DV5PSTN, LOGL_NOTICE, "Got invalid prim %d at this protocol\n", prim);
return;
}
/* send event to FSM */
rc = osmo_fsm_inst_dispatch(fi, event, msg);
if (rc < 0)
msgb_free(msg);
}
void v5x_le_pstn_mdu_snd(struct v5x_user_port *v5up, enum v5x_mgmt_prim prim)
{
struct v5x_pstn_proto *pstn = v5up->pstn.proto;
struct osmo_fsm_inst *fi = pstn->fi;
enum v5x_le_pstn_fsm_event event;
switch (prim) {
case MDU_CTRL_port_blocked:
event = V5x_PSTN_LE_MDU_CTRL_port_blocked;
break;
case MDU_CTRL_port_unblocked:
event = V5x_PSTN_LE_MDU_CTRL_port_unblocked;
break;
case MDU_CTRL_port_restart_req:
event = V5x_PSTN_LE_MDU_CTRL_restart_req;
break;
case MDU_CTRL_port_restart_compl:
event = V5x_PSTN_LE_MDU_CTRL_restart_compl_req;
break;
default:
LOGP(DV5PSTN, LOGL_NOTICE, "Got invalid prim %d at this protocol\n", prim);
return;
}
/* send event to FSM */
osmo_fsm_inst_dispatch(fi, event, NULL);
}
/***********************************************************************/
/* lower layer interface */
/***********************************************************************/
static void dl_send(struct osmo_fsm_inst *fi, struct msgb *msg)
{
struct v5x_pstn_proto *pstn = fi->priv;
v5x_dl_snd(pstn->v5up->interface, V5X_DLADDR_PSTN, msg);
}
/***********************************************************************/
/* PSTN state FSM */
/***********************************************************************/
static void start_timer_Tr(struct v5x_pstn_proto *pstn)
{
LOGP(DV5PSTN, LOGL_DEBUG, "Start timer Tr\n");
@ -423,77 +505,6 @@ static void start_timer(struct osmo_fsm_inst *fi, enum v5x_le_pstn_fsm_event eve
osmo_timer_schedule(&fi->timer, timeout, 0);
}
void v5x_le_pstn_fe_snd(struct v5x_user_port *v5up, enum v5x_fe_prim prim, struct msgb *msg)
{
struct v5x_pstn_proto *pstn = v5up->pstn.proto;
struct osmo_fsm_inst *fi = pstn->fi;
enum v5x_le_pstn_fsm_event event;
int rc;
OSMO_ASSERT(msg);
switch (prim) {
case FE_establish_req:
event = V5x_PSTN_LE_FE_establish_req;
break;
case FE_establish_ack_req:
event = V5x_PSTN_LE_FE_establish_ack_req;
break;
case FE_line_signal_req:
event = V5x_PSTN_LE_FE_line_signal_req;
break;
case FE_protocol_param_req:
event = V5x_PSTN_LE_FE_protocol_param_req;
break;
case FE_disconnect_req:
event = V5x_PSTN_LE_FE_disconnect_req;
break;
case FE_disconnect_compl_req:
event = V5x_PSTN_LE_FE_disconnect_compl_req;
break;
default:
LOGP(DV5PSTN, LOGL_NOTICE, "Got invalid prim %d at this protocol\n", prim);
return;
}
/* send event to FSM */
rc = osmo_fsm_inst_dispatch(fi, event, msg);
if (rc < 0)
msgb_free(msg);
}
void v5x_le_pstn_mdu_snd(struct v5x_user_port *v5up, enum v5x_mgmt_prim prim)
{
struct v5x_pstn_proto *pstn = v5up->pstn.proto;
struct osmo_fsm_inst *fi = pstn->fi;
enum v5x_le_pstn_fsm_event event;
switch (prim) {
case MDU_CTRL_port_blocked:
event = V5x_PSTN_LE_MDU_CTRL_port_blocked;
break;
case MDU_CTRL_port_unblocked:
event = V5x_PSTN_LE_MDU_CTRL_port_unblocked;
break;
case MDU_CTRL_port_restart_req:
event = V5x_PSTN_LE_MDU_CTRL_restart_req;
break;
case MDU_CTRL_port_restart_compl:
event = V5x_PSTN_LE_MDU_CTRL_restart_compl_req;
break;
default:
LOGP(DV5PSTN, LOGL_NOTICE, "Got invalid prim %d at this protocol\n", prim);
return;
}
/* send event to FSM */
osmo_fsm_inst_dispatch(fi, event, NULL);
}
/***********************************************************************/
/* PSTN state FSM */
/***********************************************************************/
static int v5x_le_pstn_fsm_timer_cb(struct osmo_fsm_inst *fi)
{
struct v5x_pstn_proto *pstn = fi->priv;
@ -526,7 +537,7 @@ static void do_status_enquiry(struct osmo_fsm_inst *fi)
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, 1);
/* send STATUS ENQUIRY */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
}
static void do_establish_request(struct osmo_fsm_inst *fi, struct msgb *msg)
@ -544,7 +555,7 @@ static void do_establish_request(struct osmo_fsm_inst *fi, struct msgb *msg)
msgb_free(pstn->tx_msg);
pstn->tx_msg = msgb_copy(msg, NULL);
/* send ESTABLISH */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_establish(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_establish(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
}
@ -584,7 +595,7 @@ static void do_disconnect_with_error(struct osmo_fsm_inst *fi)
pstn->tx_msg = NULL;
}
/* send DISCONNECT */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect(pstn->v5up, NULL, 0));
/* send MDU-error_indication */
rcv_mdu(fi, MDU_error_ind);
}
@ -675,12 +686,14 @@ static void pstn_le0_out_of_service(struct osmo_fsm_inst *fi, uint32_t event, vo
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, pstn->timeout_count + 1);
/* send STATUS ENQUIRY again */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
} else {
/* send MDU-error_indication */
rcv_mdu(fi, MDU_error_ind);
}
break;
default:
OSMO_ASSERT(0);
}
}
@ -704,7 +717,7 @@ static void pstn_le1_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
break;
case V5x_PSTN_LE_DISCONNECT:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
break;
case V5x_PSTN_LE_ESTABLISH_ACK:
case V5x_PSTN_LE_SIGNAL:
@ -743,12 +756,14 @@ static void pstn_le1_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, pstn->timeout_count + 1);
/* send STATUS ENQUIRY again */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
} else {
/* do several thing here */
do_disconnect_with_error(fi);
}
break;
default:
OSMO_ASSERT(0);
}
}
@ -766,7 +781,7 @@ static void pstn_le2_path_initiated_le(struct osmo_fsm_inst *fi, uint32_t event,
break;
case V5x_PSTN_LE_DISCONNECT:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_disconnect_complete(fi, tp);
break;
@ -780,7 +795,7 @@ static void pstn_le2_path_initiated_le(struct osmo_fsm_inst *fi, uint32_t event,
/* stop T1 */
stop_timer(fi);
/* send ESTABLISH ACK */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_establish_ack(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_establish_ack(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
break;
case V5x_PSTN_LE_ESTABLISH_ACK:
@ -822,7 +837,7 @@ static void pstn_le2_path_initiated_le(struct osmo_fsm_inst *fi, uint32_t event,
msgb_free(pstn->tx_msg);
pstn->tx_msg = msgb_copy(msg, NULL);
/* send DISCONNECT */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_disconnect(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
break;
case V5x_PSTN_LE_FE_disconnect_compl_req:
@ -839,7 +854,7 @@ static void pstn_le2_path_initiated_le(struct osmo_fsm_inst *fi, uint32_t event,
break;
case V5x_PSTN_LE_MDU_CTRL_restart_req:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_restart(fi);
break;
@ -853,8 +868,7 @@ static void pstn_le2_path_initiated_le(struct osmo_fsm_inst *fi, uint32_t event,
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T1, 2);
/* send ESTABLISH again */
OSMO_ASSERT(pstn->tx_msg);
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_establish(pstn->v5up, pstn->tx_msg->data,
pstn->tx_msg->len));
dl_send(fi, v5x_enc_establish(pstn->v5up, pstn->tx_msg->data, pstn->tx_msg->len));
} else {
/* do several thing here */
do_disconnect_with_error(fi);
@ -866,12 +880,14 @@ static void pstn_le2_path_initiated_le(struct osmo_fsm_inst *fi, uint32_t event,
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, pstn->timeout_count + 1);
/* send STATUS ENQUIRY again */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
} else {
/* do several thing here */
do_disconnect_with_error(fi);
}
break;
default:
OSMO_ASSERT(0);
}
}
@ -893,7 +909,7 @@ static void pstn_le3_path_initiated_an(struct osmo_fsm_inst *fi, uint32_t event,
break;
case V5x_PSTN_LE_DISCONNECT:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_disconnect_complete(fi, tp);
break;
@ -905,7 +921,7 @@ static void pstn_le3_path_initiated_an(struct osmo_fsm_inst *fi, uint32_t event,
/* change state to LE4 */
osmo_fsm_inst_state_chg(fi, V5x_LE_PTSN_S_LE4_PATH_ACTIVE, 0, 0);
/* send ESTABLISH ACK */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_establish_ack(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_establish_ack(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
break;
case V5x_PSTN_LE_ESTABLISH_ACK:
@ -940,7 +956,7 @@ static void pstn_le3_path_initiated_an(struct osmo_fsm_inst *fi, uint32_t event,
msgb_free(pstn->tx_msg);
pstn->tx_msg = msgb_copy(msg, NULL);
/* Send DISCONNECT */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_disconnect(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
break;
case V5x_PSTN_LE_FE_disconnect_compl_req:
@ -950,7 +966,7 @@ static void pstn_le3_path_initiated_an(struct osmo_fsm_inst *fi, uint32_t event,
/* stop all timers */
stop_timer(fi);
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
break;
case V5x_PSTN_LE_MDU_CTRL_port_blocked:
@ -962,7 +978,7 @@ static void pstn_le3_path_initiated_an(struct osmo_fsm_inst *fi, uint32_t event,
break;
case V5x_PSTN_LE_MDU_CTRL_restart_req:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_restart(fi);
break;
@ -975,12 +991,14 @@ static void pstn_le3_path_initiated_an(struct osmo_fsm_inst *fi, uint32_t event,
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, pstn->timeout_count + 1);
/* send STATUS ENQUIRY again */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
} else {
/* do several thing here */
do_disconnect_with_error(fi);
}
break;
default:
OSMO_ASSERT(0);
}
}
@ -998,7 +1016,7 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
break;
case V5x_PSTN_LE_DISCONNECT:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_disconnect_complete(fi, tp);
break;
@ -1012,13 +1030,14 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, 1);
/* send STATUS ENQUIRY */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
break;
case V5x_PSTN_LE_SIGNAL:
/* get sequence number and check if msg is in sequence */
seq_nr = *TLVP_VAL(tp, V5X_CTRL_IEI_SEQUENCE_NR) & 0x7f;
if (pstn->S_r == seq_nr) {
LOGP(DV5PSTN, LOGL_DEBUG, "Received expected 'receive' sequence number: S(R)=%d == M(R)=%d\n", pstn->S_r, seq_nr);
LOGP(DV5PSTN, LOGL_DEBUG, "Received expected 'receive' sequence number: S(R)=%d == M(R)=%d\n",
pstn->S_r, seq_nr);
/* start Tr, if not pending */
if (!osmo_timer_pending(&pstn->timer_Tr))
start_timer_Tr(pstn);
@ -1027,7 +1046,8 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
/* send FE-signal_indication */
rcv_fe(fi, FE_line_signal_ind, tp);
} else {
LOGP(DV5PSTN, LOGL_ERROR, "Invalid 'receive' sequence number: S(R)=%d != M(R)=%d\n", pstn->S_r, seq_nr);
LOGP(DV5PSTN, LOGL_ERROR, "Invalid 'receive' sequence number: S(R)=%d != M(R)=%d\n",
pstn->S_r, seq_nr);
/* send FE-signal_indication */
rcv_fe(fi, FE_line_signal_ind, tp);
/* do several thing here */
@ -1039,7 +1059,8 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
unacked = (pstn->S_s - pstn->S_a) & 127;
acked = (pstn->S_s - seq_nr) & 127;
if (acked <= unacked) {
LOGP(DV5PSTN, LOGL_DEBUG, "Received expected 'transmit' sequence number: M(R)=%d is inside S(A)=%d...S(S)=%d range\n", seq_nr, pstn->S_a, pstn->S_s);
LOGP(DV5PSTN, LOGL_DEBUG, "Received expected 'transmit' sequence number: M(R)=%d is inside "
"S(A)=%d...S(S)=%d range\n", seq_nr, pstn->S_a, pstn->S_s);
LOGP(DV5PSTN, LOGL_DEBUG, "We had %d unacked messages, now we have %d acked messages.\n", unacked, acked);
/* update acknowledge sequence number */
pstn->S_a = seq_nr;
@ -1053,7 +1074,8 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
start_timer_Tt(pstn);
}
} else {
LOGP(DV5PSTN, LOGL_ERROR, "Invalid 'transmit' sequence number: M(R)=%d not inside S(A)=%d...S(S)=%d range\n", seq_nr, pstn->S_a, pstn->S_s);
LOGP(DV5PSTN, LOGL_ERROR, "Invalid 'transmit' sequence number: M(R)=%d not inside "
"S(A)=%d...S(S)=%d range\n", seq_nr, pstn->S_a, pstn->S_s);
/* do several thing here */
do_disconnect_with_error(fi);
}
@ -1079,15 +1101,13 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
msgb_free(pstn->tx_msg);
pstn->tx_msg = msgb_copy(msg, NULL);
/* send SIGNAL */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_signal(pstn->v5up, pstn->S_s, msg->data,
msg->len));
dl_send(fi, v5x_enc_signal(pstn->v5up, pstn->S_s, msg->data, msg->len));
msgb_free(msg);
/* increment send sequence number */
pstn->S_s = (pstn->S_s + 1) & 127;
} else {
/* send SIGNAL */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_signal(pstn->v5up, pstn->S_s, msg->data,
msg->len));
dl_send(fi, v5x_enc_signal(pstn->v5up, pstn->S_s, msg->data, msg->len));
msgb_free(msg);
/* do several thing here */
do_disconnect_with_error(fi);
@ -1099,15 +1119,13 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
/* start Tt */
start_timer_Tt(pstn);
/* send SIGNAL */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_protocol_param(pstn->v5up, pstn->S_s, msg->data,
msg->len));
dl_send(fi, v5x_enc_protocol_param(pstn->v5up, pstn->S_s, msg->data, msg->len));
msgb_free(msg);
/* increment send sequence number */
pstn->S_s = (pstn->S_s + 1) & 127;
} else {
/* send SIGNAL */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_protocol_param(pstn->v5up, pstn->S_s, msg->data,
msg->len));
dl_send(fi, v5x_enc_protocol_param(pstn->v5up, pstn->S_s, msg->data, msg->len));
msgb_free(msg);
/* do several thing here */
do_disconnect_with_error(fi);
@ -1125,7 +1143,7 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
msgb_free(pstn->tx_msg);
pstn->tx_msg = msgb_copy(msg, NULL);
/* Send DISCONNECT */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect(pstn->v5up, msg->data, msg->len));
dl_send(fi, v5x_enc_disconnect(pstn->v5up, msg->data, msg->len));
msgb_free(msg);
break;
case V5x_PSTN_LE_FE_disconnect_compl_req:
@ -1141,7 +1159,7 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
break;
case V5x_PSTN_LE_MDU_CTRL_restart_req:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_restart(fi);
break;
@ -1154,7 +1172,7 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, pstn->timeout_count + 1);
/* send STATUS ENQUIRY again */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
} else {
/* do several thing here */
do_disconnect_with_error(fi);
@ -1162,14 +1180,17 @@ static void pstn_le4_path_active(struct osmo_fsm_inst *fi, uint32_t event, void
break;
case V5x_PSTN_LE_TIMEOUT_Tr:
/* send SIGNAL ACK */
LOGP(DV5PSTN, LOGL_DEBUG, "Sending recent 'receive' sequence number: S(R)=%d as acknowledge.\n", pstn->S_r);
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_signal_ack(pstn->v5up, pstn->S_r));
LOGP(DV5PSTN, LOGL_DEBUG, "Sending recent 'receive' sequence number: S(R)=%d as acknowledge.\n",
pstn->S_r);
dl_send(fi, v5x_enc_signal_ack(pstn->v5up, pstn->S_r));
break;
case V5x_PSTN_LE_TIMEOUT_Tt:
/* do several thing here */
LOGP(DV5PSTN, LOGL_ERROR, "Aborting, because of missing acknowledge of outstanding 'transmit' sequence number: S(A)=%d...S(S)=%d\n", pstn->S_a, pstn->S_s);
do_disconnect_with_error(fi);
break;
default:
OSMO_ASSERT(0);
}
}
@ -1225,7 +1246,7 @@ static void pstn_le5_path_disconnect_req(struct osmo_fsm_inst *fi, uint32_t even
break;
case V5x_PSTN_LE_MDU_CTRL_restart_req:
/* send DISCONNECT COMPLETE */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect_compl(pstn->v5up, NULL, 0));
/* do several thing here */
do_restart(fi);
break;
@ -1235,10 +1256,10 @@ static void pstn_le5_path_disconnect_req(struct osmo_fsm_inst *fi, uint32_t even
case V5x_PSTN_LE_TIMEOUT_T3:
/* send DISCONNECT again */
if (pstn->tx_msg)
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect(pstn->v5up, pstn->tx_msg->data,
dl_send(fi, v5x_enc_disconnect(pstn->v5up, pstn->tx_msg->data,
pstn->tx_msg->len));
else
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_disconnect(pstn->v5up, NULL, 0));
dl_send(fi, v5x_enc_disconnect(pstn->v5up, NULL, 0));
/* start T3 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T3, pstn->timeout_count + 1);
/* third timeout ? */
@ -1247,6 +1268,8 @@ static void pstn_le5_path_disconnect_req(struct osmo_fsm_inst *fi, uint32_t even
rcv_mdu(fi, MDU_error_ind);
}
break;
default:
OSMO_ASSERT(0);
}
}
@ -1297,12 +1320,14 @@ static void pstn_le6_port_blocked(struct osmo_fsm_inst *fi, uint32_t event, void
/* start T4 */
start_timer(fi, V5x_PSTN_LE_TIMEOUT_T4, pstn->timeout_count + 1);
/* send STATUS ENQUIRY again */
v5x_snd(pstn->v5up->inst, V5X_DLADDR_PSTN, v5x_enc_status_enquiry(pstn->v5up));
dl_send(fi, v5x_enc_status_enquiry(pstn->v5up));
} else {
/* send MDU-error_indication */
rcv_mdu(fi, MDU_error_ind);
}
break;
default:
OSMO_ASSERT(0);
}
}
@ -1521,6 +1546,11 @@ void v5x_le_pstn_destroy(struct v5x_pstn_proto *pstn)
talloc_free(pstn);
}
const char *v5x_le_pstn_state_name(struct v5x_pstn_proto *pstn)
{
return v5x_le_pstn_fsm_states[pstn->fi->state].name;
}
void v5x_le_pstn_init(void)
{
int rc;
@ -1530,13 +1560,12 @@ void v5x_le_pstn_init(void)
LOGP(DV5PSTN, LOGL_NOTICE, "Using V5x PSTN protocol\n");
}
/***********************************************************************
* V5 Message receiving / decoding
***********************************************************************/
/* receive message from lower (DL) layer */
int v5x_le_pstn_rcv(struct v5x_user_port *v5up, uint16_t l3_addr, uint8_t msg_type, const struct tlv_parsed *tp)
int v5x_le_pstn_dl_rcv(struct v5x_user_port *v5up, uint8_t msg_type, const struct tlv_parsed *tp)
{
enum v5x_le_pstn_fsm_event event;

View File

@ -1,7 +1,9 @@
struct v5x_pstn_proto *v5x_le_pstn_create(struct v5x_user_port *v5up, uint16_t nr);
void v5x_le_pstn_destroy(struct v5x_pstn_proto *pstn);
const char *v5x_le_pstn_state_name(struct v5x_pstn_proto *pstn);
const char *v5x_l1_fsm_state_name(struct v5x_l1_proto *l1);
void v5x_le_pstn_init(void);
void v5x_le_pstn_fe_snd(struct v5x_user_port *v5up, enum v5x_fe_prim prim, struct msgb *msg);
void v5x_le_pstn_mdu_snd(struct v5x_user_port *v5up, enum v5x_mgmt_prim prim);
int v5x_le_pstn_rcv(struct v5x_user_port *v5up, uint16_t l3_addr, uint8_t msg_type, const struct tlv_parsed *tp);
int v5x_le_pstn_dl_rcv(struct v5x_user_port *v5up, uint8_t msg_type, const struct tlv_parsed *tp);