|
|
|
@ -2,6 +2,9 @@ |
|
|
|
|
#include <osmocom/core/linuxlist.h> |
|
|
|
|
|
|
|
|
|
#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; |
|
|
|
|
} |
|
|
|
|