From da0554b24b575561bb02ec42acba79cbec4ede0d Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 27 Nov 2022 14:14:13 +0100 Subject: [PATCH] Work on v5x_data.c and v5x_internal.h --- v5x_data.c | 74 ++++++++++++++++++++++++++++++++++++++++++-------- v5x_internal.h | 41 ++++++++++++++++++++-------- 2 files changed, 93 insertions(+), 22 deletions(-) diff --git a/v5x_data.c b/v5x_data.c index ee27213..98d5bdf 100644 --- a/v5x_data.c +++ b/v5x_data.c @@ -2,6 +2,9 @@ #include #include "v5x_internal.h" +#include "v5x_protocol.h" +#include "v51_le_ctrl.h" +#include "lapv5.h" static LLIST_HEAD(v5_instances); @@ -12,8 +15,6 @@ struct v5x_instance *v5x_instance_alloc(void *ctx) return NULL; INIT_LLIST_HEAD(&v5i->interfaces); - INIT_LLIST_HEAD(&v5i->user_ports); - /* TODO: allocate ctrl_fi */ llist_add_tail(&v5i->list, &v5_instances); @@ -49,7 +50,8 @@ static void v5x_link_init(struct v5x_link *v5l, struct v5x_interface *v5if, uint v5x_cchan_init(&v5l->c_channel[0], v5l, &v5l->ts[16], true); } -struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect) +struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect, + uint32_t id, uint8_t variant, int (*ph_data_req_cb)(struct msgb *msg, void *cbdata)) { struct v5x_interface *v5if = talloc_zero(v5i, struct v5x_interface); //struct v5x_link *v5l; @@ -57,6 +59,8 @@ struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dia v5if->instance = v5i; v5if->dialect = dialect; + v5if->id = id; + v5if->variant = variant; /* primary link must alwasy be present */ v5x_link_init(&v5if->links[0], v5if, 0); @@ -64,29 +68,77 @@ struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dia primary_c_chan = &v5if->primary_link->c_channel[0]; - - /* TODO: allocate fi */ - - //lapd_dl_init2(&v5if->control.dl, k, v_rnage, maxf, "control"); + v5if->control.ctrl = v51_ctrl_create(v5if, NULL, 0); + if (!v5if->control.ctrl) + return NULL; + v5if->control.li = lapv5_instance_alloc(1, ph_data_req_cb, v5if, v5x_rcv, v5if, &lapd_profile_lapv5dl, "control"); v5if->control.c_chan = primary_c_chan; - //lapd_dl_init2(&v5if->pstn.dl, k, v_rnage, maxf, "pstn"); + v5if->pstn.li = lapv5_instance_alloc(1, ph_data_req_cb, v5if, v5x_rcv, v5if, &lapd_profile_lapv5dl, "pstn"); v5if->pstn.c_chan = primary_c_chan; if (v5if->dialect == V5X_DIALECT_V52) { - //lapd_dl_init2(&v5if->lcp.dl, k, v_rnage, maxf, "lcp"); + v5if->lcp.li = lapv5_instance_alloc(1, ph_data_req_cb, v5if, v5x_rcv, v5if, &lapd_profile_lapv5dl, "lcp"); v5if->lcp.c_chan = primary_c_chan; - //lapd_dl_init2(&v5if->bcc.dl, k, v_rnage, maxf, "bcc"); + v5if->bcc.li = lapv5_instance_alloc(1, ph_data_req_cb, v5if, v5x_rcv, v5if, &lapd_profile_lapv5dl, "bcc"); v5if->bcc.c_chan = primary_c_chan; - //lapd_dl_init2(&v5if->protection[0].dl, k, v_rnage, maxf, "protection0"); + v5if->protection[0].li = lapv5_instance_alloc(1, ph_data_req_cb, v5if, v5x_rcv, v5if, &lapd_profile_lapv5dl, "protection0"); v5if->protection[0].c_chan = primary_c_chan; //protection[1] ? } + INIT_LLIST_HEAD(&v5if->user_ports); + llist_add_tail(&v5if->list, &v5i->interfaces); return v5if; } + +struct v5x_user_port *v5x_user_port_create(struct v5x_interface *v5if, uint16_t nr, bool is_isdn) +{ + struct v5x_user_port *v5up; + + v5up = talloc_zero(v5if, struct v5x_user_port); + if (!v5up) + return NULL; + v5up->inst = v5if; + v5up->is_isdn = is_isdn; + v5up->ctrl = v51_ctrl_create(NULL, v5up, nr); + if (!v5up->ctrl) + return NULL; + if (is_isdn) { + /* TODO: allocate fi + v5up->state = v52_isdn_state_create(v5up, nr); + if (!v5up->state) + return NULL; + */ + } else { + /* TODO: allocate fi + v5up->state = v52_pstn_state_create(v5up, nr); + if (!v5up->state) + return NULL; + v5up->pstn.proto = v52_pstn_protocol_create(v5up, nr); + if (!v5up->pstn.proto) + return NULL; + */ + } + v5up->nr = nr; + + llist_add_tail(&v5up->list, &v5if->user_ports); + + return v5up; +} + +struct v5x_user_port *v5x_user_port_find(struct v5x_interface *v5if, uint16_t nr) +{ + struct v5x_user_port *v5up; + + llist_for_each_entry(v5up, &v5if->user_ports, list) { + if (v5up->nr == nr) + return v5up; + } + return NULL; +} diff --git a/v5x_internal.h b/v5x_internal.h index 6e760b4..a3ea750 100644 --- a/v5x_internal.h +++ b/v5x_internal.h @@ -25,6 +25,7 @@ #include #include +#include #include struct osmo_fsm_inst; @@ -37,6 +38,7 @@ enum v5x_dialect { /* forward-declarations */ struct v5x_interface; struct v5x_instance; +struct v5x_user_port; struct v5x_link; /* A C-channel is a 64k timeslot used for signalling */ @@ -67,6 +69,8 @@ struct v5x_interface { struct llist_head list; /* instance.interfaces */ struct v5x_instance *instance; /* back-pointer */ enum v5x_dialect dialect; + uint32_t id; /* interface id */ + uint8_t variant; /* provitioning variant */ struct v5x_link *primary_link; /* one of the links below */ struct v5x_link *secondary_link; /* one of the links below */ /* 1..16 links in one interface */ @@ -74,50 +78,65 @@ struct v5x_interface { struct osmo_fsm_inst *fi; /* Interface FSM instance */ struct { - struct lapd_datalink dl; /* Control data link */ + struct v5x_ctrl_proto *ctrl; /* common control instance */ + struct lapv5_instance *li; /* Control data link */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */ } control; struct { - struct lapd_datalink dl; /* Link control data link */ + struct lapv5_instance *li; /* Link control data link */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */ struct osmo_fsm_inst *fi; /* Link Control FSM instance */ } lcp; struct { - struct lapd_datalink dl; /* PSTN data link */ + struct lapv5_instance *li; /* PSTN data link */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */ } pstn; struct { - struct lapd_datalink dl; /* BCC data link */ + struct lapv5_instance *li; /* BCC data link */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */ } bcc; struct { - struct lapd_datalink dl; /* Protection data link 1 + 2 */ + struct lapv5_instance *li; /* Protection data link 1 + 2 */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */ } protection[2]; + + struct llist_head user_ports; /* list of v5x_user_port */ +}; + +struct v5x_ctrl_proto { + struct v5x_user_port *v5up; /* back pointer, if port control is used */ + struct v5x_interface *v5if; /* back pointer, if common control is used */ + struct osmo_fsm_inst *fi; /* control FSM */ + struct llist_head tx_queue; /* list of message to be transmitted */ + struct msgb *tx_msg; /* copy of unacked message, for second try */ }; /* one user-facing port (subscriber line) */ struct v5x_user_port { struct llist_head list; /* part of v5x_instance.ports */ - struct v5x_instance *inst; /* back-pointer to instance we're part of */ + struct v5x_interface *inst; /* back-pointer to instance we're part of */ uint16_t nr; /* port-number in decoded form (0..32767) */ bool is_isdn; /* is this port an ISDN port? */ + struct v5x_ctrl_proto *ctrl; /* port control instance */ +#if 0 + struct v5x_state_port *state; /* port state instance */ struct { - struct osmo_fsm_inst *ctrl_fi; /* control protocol FSM instance */ - struct osmo_fsm_inst *fi; /* port state FSM instance */ } isdn; struct { + struct v5x_pstn_proto *proto; /* PSTN protocol instance */ } pstn; +#endif }; struct v5x_instance { struct llist_head list; /* part of global list of instances */ struct llist_head interfaces; /* v5x_interface.list */ - struct llist_head user_ports; /* list of v5x_user_port */ - struct osmo_fsm_inst *ctrl_fi; /* common control FSM */ }; struct v5x_instance *v5x_instance_alloc(void *ctx); -struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect); +struct v5x_interface *v5x_interface_alloc(struct v5x_instance *v5i, enum v5x_dialect dialect, + uint32_t id, uint8_t variant, int (*ph_data_req_cb)(struct msgb *msg, void *cbdata)); +struct v5x_user_port *v5x_user_port_create(struct v5x_interface *v5if, uint16_t nr, bool is_isdn); +struct v5x_user_port *v5x_user_port_find(struct v5x_interface *v5if, uint16_t nr);