mirror of https://gerrit.osmocom.org/libosmocore
frame_relay: Add status call-backs for link + DLC status changes
Change-Id: Iec19db4e48642c3fcb0aa11fa7787b8323fd0e5a Related: Os#4999
This commit is contained in:
parent
943133cad8
commit
2cc1d4d7df
|
@ -87,11 +87,15 @@ struct osmo_fr_link {
|
|||
/* list of data link connections at this link */
|
||||
struct llist_head dlc_list;
|
||||
|
||||
/* optional call-back to be called for each PDU received on an unknown DLC */
|
||||
int (*unknown_dlc_rx_cb)(void *cb_data, struct msgb *msg);
|
||||
void *unknown_dlc_rx_cb_data;
|
||||
|
||||
/* call-back to be called for transmitting on the underlying hardware */
|
||||
int (*tx_cb)(void *data, struct msgb *msg);
|
||||
void *tx_cb_data;
|
||||
/* optional call-back to be called each time the status changes active/inactive */
|
||||
void (*status_cb)(struct osmo_fr_link *link, void *cb_data, bool active);
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
/* Frame Relay Data Link Connection */
|
||||
|
@ -113,8 +117,11 @@ struct osmo_fr_dlc {
|
|||
* NET must wait until USER confirms it implicitly by a seq number check */
|
||||
bool state_send;
|
||||
|
||||
/* call-back to be called for each PDU received on this DLC */
|
||||
int (*rx_cb)(void *cb_data, struct msgb *msg);
|
||||
void *rx_cb_data;
|
||||
/* optional call-back to be called each time the status changes active/inactive */
|
||||
void (*status_cb)(struct osmo_fr_dlc *dlc, void *cb_data, bool active);
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
/* allocate a frame relay network */
|
||||
|
|
|
@ -189,6 +189,18 @@ static inline void dlci_to_q922(uint8_t *hdr, uint16_t dlci)
|
|||
hdr[1] = ((dlci << 4) & 0xF0) | 0x01;
|
||||
}
|
||||
|
||||
static void dlc_set_active(struct osmo_fr_dlc *dlc, bool active)
|
||||
{
|
||||
if (active == dlc->active)
|
||||
return;
|
||||
|
||||
dlc->active = active;
|
||||
|
||||
LOGPFRL(dlc->link, LOGL_NOTICE, "DLCI %u became %s\n", dlc->dlci, active ? "active" : "inactive");
|
||||
if (dlc->status_cb)
|
||||
dlc->status_cb(dlc, dlc->cb_data, active);
|
||||
}
|
||||
|
||||
/* allocate a message buffer and put Q.933 Annex A headers (L2 + L3) */
|
||||
static struct msgb *q933_msgb_alloc(uint16_t dlci, uint8_t prot_disc, uint8_t msg_type)
|
||||
{
|
||||
|
@ -285,7 +297,7 @@ static int tx_lmi_q933_status_enq(struct osmo_fr_link *link, uint8_t rep_type)
|
|||
msgb_tlv_put(resp, Q933_IEI_REPORT_TYPE, 1, &rep_type);
|
||||
msgb_put_link_int_verif(resp, link);
|
||||
|
||||
return link->tx_cb(link->tx_cb_data, resp);
|
||||
return link->tx_cb(link->cb_data, resp);
|
||||
}
|
||||
|
||||
/* Send a Q.933 STATUS of given type over given link */
|
||||
|
@ -327,7 +339,7 @@ static int tx_lmi_q933_status(struct osmo_fr_link *link, uint8_t rep_type)
|
|||
break;
|
||||
}
|
||||
|
||||
return link->tx_cb(link->tx_cb_data, resp);
|
||||
return link->tx_cb(link->cb_data, resp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -369,7 +381,7 @@ static int rx_lmi_q933_status_enq(struct msgb *msg, struct tlv_parsed *tp)
|
|||
continue;
|
||||
|
||||
if (dlc->add) {
|
||||
dlc->active = link->state;
|
||||
dlc_set_active(dlc, link->state);
|
||||
dlc->add = false;
|
||||
}
|
||||
|
||||
|
@ -417,11 +429,11 @@ static void check_link_state(struct osmo_fr_link *link, bool valid)
|
|||
|
||||
LOGPFRL(link, LOGL_NOTICE, "Link failed\n");
|
||||
link->state = false;
|
||||
if (link->role == FR_ROLE_USER_EQUIPMENT)
|
||||
return;
|
||||
if (link->status_cb)
|
||||
link->status_cb(link, link->cb_data, link->state);
|
||||
|
||||
llist_for_each_entry(dlc, &link->dlc_list, list) {
|
||||
dlc->active = false;
|
||||
dlc_set_active(dlc, false);
|
||||
}
|
||||
} else {
|
||||
/* good link */
|
||||
|
@ -430,16 +442,21 @@ static void check_link_state(struct osmo_fr_link *link, bool valid)
|
|||
|
||||
LOGPFRL(link, LOGL_NOTICE, "Link recovered\n");
|
||||
link->state = true;
|
||||
if (link->status_cb)
|
||||
link->status_cb(link, link->cb_data, link->state);
|
||||
|
||||
if (link->role == FR_ROLE_USER_EQUIPMENT) {
|
||||
/* make sure the next STATUS ENQUIRY is for a full
|
||||
* status report to get the configred DLCs ASAP */
|
||||
link->polling_count = 0;
|
||||
/* we must not proceed further below if we're in user role,
|
||||
* as otherwise link recovery would set all DLCs as active */
|
||||
return;
|
||||
}
|
||||
|
||||
llist_for_each_entry(dlc, &link->dlc_list, list) {
|
||||
if (!dlc->add && !dlc->del)
|
||||
dlc->active = true;
|
||||
dlc_set_active(dlc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +525,7 @@ static int parse_full_pvc_status(struct osmo_fr_link *link, struct tlv_parsed *t
|
|||
* using the optional single PVC asynchronous status report.
|
||||
* Ignoring the delete. */
|
||||
dlc->add = pvc->new;
|
||||
dlc->active = pvc->active;
|
||||
dlc_set_active(dlc, pvc->active);
|
||||
dlc->del = 0;
|
||||
}
|
||||
|
||||
|
@ -523,7 +540,7 @@ static int parse_full_pvc_status(struct osmo_fr_link *link, struct tlv_parsed *t
|
|||
}
|
||||
|
||||
if (!found) {
|
||||
dlc->active = false;
|
||||
dlc_set_active(dlc, false);
|
||||
dlc->del = true;
|
||||
}
|
||||
}
|
||||
|
@ -575,7 +592,7 @@ static int parse_link_pvc_status(struct osmo_fr_link *link, struct tlv_parsed *t
|
|||
dlc->del = 1;
|
||||
} else {
|
||||
dlc->add = pvc->new;
|
||||
dlc->active = pvc->active;
|
||||
dlc_set_active(dlc, pvc->active);
|
||||
dlc->del = 0;
|
||||
}
|
||||
}
|
||||
|
@ -771,7 +788,7 @@ int osmo_fr_rx(struct msgb *msg)
|
|||
if (dlc->dlci == dlci) {
|
||||
/* dispatch to handler of respective DLC */
|
||||
msg->dst = dlc;
|
||||
return dlc->rx_cb(dlc->rx_cb_data, msg);
|
||||
return dlc->rx_cb(dlc->cb_data, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -816,7 +833,7 @@ int osmo_fr_tx_dlc(struct msgb *msg)
|
|||
dlci_to_q922(frh, dlc->dlci);
|
||||
|
||||
msg->dst = link;
|
||||
return link->tx_cb(link->tx_cb_data, msg);
|
||||
return link->tx_cb(link->cb_data, msg);
|
||||
}
|
||||
|
||||
/* Every T391 seconds, the user equipment sends a STATUS ENQUIRY
|
||||
|
|
|
@ -198,7 +198,7 @@ static struct priv_vc *fr_alloc_vc(struct gprs_ns2_vc_bind *bind,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
priv->dlc->rx_cb_data = nsvc;
|
||||
priv->dlc->cb_data = nsvc;
|
||||
priv->dlc->rx_cb = fr_dlci_rx_cb;
|
||||
|
||||
return priv;
|
||||
|
@ -756,7 +756,7 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
|
|||
}
|
||||
|
||||
fr_link->tx_cb = fr_tx_cb;
|
||||
fr_link->tx_cb_data = bind;
|
||||
fr_link->cb_data = bind;
|
||||
priv->link = fr_link;
|
||||
|
||||
priv->ifindex = rc = devname2ifindex(netif);
|
||||
|
|
Loading…
Reference in New Issue