Work on v5x_data.c and v5x_internal.h

This commit is contained in:
Andreas Eversberg 2022-11-27 14:14:13 +01:00
parent 7498809d2d
commit da0554b24b
2 changed files with 93 additions and 22 deletions

View File

@ -2,6 +2,9 @@
#include <osmocom/core/linuxlist.h> #include <osmocom/core/linuxlist.h>
#include "v5x_internal.h" #include "v5x_internal.h"
#include "v5x_protocol.h"
#include "v51_le_ctrl.h"
#include "lapv5.h"
static LLIST_HEAD(v5_instances); static LLIST_HEAD(v5_instances);
@ -12,8 +15,6 @@ struct v5x_instance *v5x_instance_alloc(void *ctx)
return NULL; return NULL;
INIT_LLIST_HEAD(&v5i->interfaces); INIT_LLIST_HEAD(&v5i->interfaces);
INIT_LLIST_HEAD(&v5i->user_ports);
/* TODO: allocate ctrl_fi */
llist_add_tail(&v5i->list, &v5_instances); 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); 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_interface *v5if = talloc_zero(v5i, struct v5x_interface);
//struct v5x_link *v5l; //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->instance = v5i;
v5if->dialect = dialect; v5if->dialect = dialect;
v5if->id = id;
v5if->variant = variant;
/* primary link must alwasy be present */ /* primary link must alwasy be present */
v5x_link_init(&v5if->links[0], v5if, 0); 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]; primary_c_chan = &v5if->primary_link->c_channel[0];
v5if->control.ctrl = v51_ctrl_create(v5if, NULL, 0);
/* TODO: allocate fi */ if (!v5if->control.ctrl)
return NULL;
//lapd_dl_init2(&v5if->control.dl, k, v_rnage, maxf, "control"); 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; 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; v5if->pstn.c_chan = primary_c_chan;
if (v5if->dialect == V5X_DIALECT_V52) { 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; 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; 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; v5if->protection[0].c_chan = primary_c_chan;
//protection[1] ? //protection[1] ?
} }
INIT_LLIST_HEAD(&v5if->user_ports);
llist_add_tail(&v5if->list, &v5i->interfaces); llist_add_tail(&v5if->list, &v5i->interfaces);
return v5if; 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;
}

View File

@ -25,6 +25,7 @@
#include <stdint.h> #include <stdint.h>
#include <osmocom/core/utils.h> #include <osmocom/core/utils.h>
#include <osmocom/core/fsm.h>
#include <osmocom/gsm/lapd_core.h> #include <osmocom/gsm/lapd_core.h>
struct osmo_fsm_inst; struct osmo_fsm_inst;
@ -37,6 +38,7 @@ enum v5x_dialect {
/* forward-declarations */ /* forward-declarations */
struct v5x_interface; struct v5x_interface;
struct v5x_instance; struct v5x_instance;
struct v5x_user_port;
struct v5x_link; struct v5x_link;
/* A C-channel is a 64k timeslot used for signalling */ /* A C-channel is a 64k timeslot used for signalling */
@ -67,6 +69,8 @@ struct v5x_interface {
struct llist_head list; /* instance.interfaces */ struct llist_head list; /* instance.interfaces */
struct v5x_instance *instance; /* back-pointer */ struct v5x_instance *instance; /* back-pointer */
enum v5x_dialect dialect; 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 *primary_link; /* one of the links below */
struct v5x_link *secondary_link; /* one of the links below */ struct v5x_link *secondary_link; /* one of the links below */
/* 1..16 links in one interface */ /* 1..16 links in one interface */
@ -74,50 +78,65 @@ struct v5x_interface {
struct osmo_fsm_inst *fi; /* Interface FSM instance */ struct osmo_fsm_inst *fi; /* Interface FSM instance */
struct { 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 */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} control; } control;
struct { 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 v5x_c_channel *c_chan; /* pointer to active C-channel */
struct osmo_fsm_inst *fi; /* Link Control FSM instance */ struct osmo_fsm_inst *fi; /* Link Control FSM instance */
} lcp; } lcp;
struct { 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 */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} pstn; } pstn;
struct { 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 */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} bcc; } bcc;
struct { 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 */ struct v5x_c_channel *c_chan; /* pointer to active C-channel */
} protection[2]; } 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) */ /* one user-facing port (subscriber line) */
struct v5x_user_port { struct v5x_user_port {
struct llist_head list; /* part of v5x_instance.ports */ 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) */ uint16_t nr; /* port-number in decoded form (0..32767) */
bool is_isdn; /* is this port an ISDN port? */ 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 {
struct osmo_fsm_inst *ctrl_fi; /* control protocol FSM instance */
struct osmo_fsm_inst *fi; /* port state FSM instance */
} isdn; } isdn;
struct { struct {
struct v5x_pstn_proto *proto; /* PSTN protocol instance */
} pstn; } pstn;
#endif
}; };
struct v5x_instance { struct v5x_instance {
struct llist_head list; /* part of global list of instances */ struct llist_head list; /* part of global list of instances */
struct llist_head interfaces; /* v5x_interface.list */ 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_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);