forked from retronetworking/osmo-v5
Fixes for lapv5
This commit is contained in:
parent
aeae94c547
commit
513f3bba5a
53
src/lapv5.c
53
src/lapv5.c
|
@ -35,7 +35,9 @@
|
||||||
|
|
||||||
#include "v5x_internal.h"
|
#include "v5x_internal.h"
|
||||||
#include "v5x_protocol.h"
|
#include "v5x_protocol.h"
|
||||||
|
#include "v5x_le_port_fsm.h"
|
||||||
#include "lapv5.h"
|
#include "lapv5.h"
|
||||||
|
#include "layer1.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
#define LAPD_ADDR1(sapi, cr) ((((sapi) & 0x3f) << 2) | (((cr) & 0x1) << 1))
|
#define LAPD_ADDR1(sapi, cr) ((((sapi) & 0x3f) << 2) | (((cr) & 0x1) << 1))
|
||||||
|
@ -132,7 +134,7 @@ static struct lapv5_sap *lapv5_sap_alloc(struct lapv5_instance *li, uint16_t v5d
|
||||||
if (!sap)
|
if (!sap)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
LOGP(DLLAPD, LOGL_NOTICE, "(%s): LAPV5 Allocating SAP for V5_DLADDR=%u (dl=%p, sap=%p)\n",
|
LOGP(DLLAPD, LOGL_DEBUG, "(%s): LAPV5 Allocating SAP for V5_DLADDR=%u (dl=%p, sap=%p)\n",
|
||||||
name, v5dladdr, &sap->dl, sap);
|
name, v5dladdr, &sap->dl, sap);
|
||||||
|
|
||||||
sap->li = li;
|
sap->li = li;
|
||||||
|
@ -141,7 +143,7 @@ static struct lapv5_sap *lapv5_sap_alloc(struct lapv5_instance *li, uint16_t v5d
|
||||||
profile = &li->profile;
|
profile = &li->profile;
|
||||||
|
|
||||||
k = profile->k[0];
|
k = profile->k[0];
|
||||||
LOGP(DLLAPD, LOGL_NOTICE, "(%s): k=%d N200=%d N201=%d T200=%d.%d T203=%d.%d\n",
|
LOGP(DLLAPD, LOGL_DEBUG, "(%s): k=%d N200=%d N201=%d T200=%d.%d T203=%d.%d\n",
|
||||||
name, k, profile->n200, profile->n201, profile->t200_sec,
|
name, k, profile->n200, profile->n201, profile->t200_sec,
|
||||||
profile->t200_usec, profile->t203_sec, profile->t203_usec);
|
profile->t200_usec, profile->t203_sec, profile->t203_usec);
|
||||||
lapd_dl_init2(dl, k, 128, profile->n201, name);
|
lapd_dl_init2(dl, k, 128, profile->n201, name);
|
||||||
|
@ -167,7 +169,7 @@ static struct lapv5_sap *lapv5_sap_alloc(struct lapv5_instance *li, uint16_t v5d
|
||||||
/* Free SAP instance, including the datalink */
|
/* Free SAP instance, including the datalink */
|
||||||
static void lapv5_sap_free(struct lapv5_sap *sap)
|
static void lapv5_sap_free(struct lapv5_sap *sap)
|
||||||
{
|
{
|
||||||
LOGSAP(sap, LOGL_NOTICE, "LAPV5 Freeing SAP for DLADDR=%u (dl=%p, sap=%p)\n", sap->dladdr, &sap->dl, sap);
|
LOGSAP(sap, LOGL_DEBUG, "LAPV5 Freeing SAP for DLADDR=%u (dl=%p, sap=%p)\n", sap->dladdr, &sap->dl, sap);
|
||||||
|
|
||||||
/* free datalink structures and timers */
|
/* free datalink structures and timers */
|
||||||
lapd_dl_exit(&sap->dl);
|
lapd_dl_exit(&sap->dl);
|
||||||
|
@ -269,7 +271,7 @@ int lapv5_ph_data_ind(struct lapv5_instance *li, struct msgb *msg, int *error)
|
||||||
return lapd_ph_data_ind(msg, &lctx);
|
return lapd_ph_data_ind(msg, &lctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start a (user-side) SAP for the specified TEI/SAPI on the LAPD instance */
|
/* Start a (LE-side) SAP for the specified TEI/SAPI on the LAPD instance */
|
||||||
int lapv5_dl_est_req(struct lapv5_instance *li, uint16_t dladdr)
|
int lapv5_dl_est_req(struct lapv5_instance *li, uint16_t dladdr)
|
||||||
{
|
{
|
||||||
struct lapv5_sap *sap;
|
struct lapv5_sap *sap;
|
||||||
|
@ -284,18 +286,19 @@ int lapv5_dl_est_req(struct lapv5_instance *li, uint16_t dladdr)
|
||||||
if (!sap)
|
if (!sap)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
LOGSAP(sap, LOGL_NOTICE, "LAPV5 DL-ESTABLISH request DLADDR=%u\n", dladdr);
|
LOGSAP(sap, LOGL_DEBUG, "LAPV5 DL-ESTABLISH request DLADDR=%u\n", dladdr);
|
||||||
|
|
||||||
/* prepare prim */
|
/* prepare prim */
|
||||||
msg = msgb_alloc_headroom(DLSAP_MSGB_SIZE, DLSAP_MSGB_HEADROOM, "DL EST");
|
msg = msgb_alloc_headroom(DLSAP_MSGB_SIZE, DLSAP_MSGB_HEADROOM, "DL EST");
|
||||||
msg->l3h = msg->data;
|
msg->l3h = msg->data;
|
||||||
|
memset(&dp, 0, sizeof(dp));
|
||||||
osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
|
osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
|
||||||
|
|
||||||
/* send to L2 */
|
/* send to L2 */
|
||||||
return lapd_recv_dlsap(&dp, &sap->dl.lctx);
|
return lapd_recv_dlsap(&dp, &sap->dl.lctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop a (user-side) SAP for the specified TEI/SAPI on the LAPD instance */
|
/* Stop a (LE-side) SAP for the specified TEI/SAPI on the LAPD instance */
|
||||||
int lapv5_dl_rel_req(struct lapv5_instance *li, uint16_t dladdr)
|
int lapv5_dl_rel_req(struct lapv5_instance *li, uint16_t dladdr)
|
||||||
{
|
{
|
||||||
struct lapv5_sap *sap;
|
struct lapv5_sap *sap;
|
||||||
|
@ -306,11 +309,12 @@ int lapv5_dl_rel_req(struct lapv5_instance *li, uint16_t dladdr)
|
||||||
if (!sap)
|
if (!sap)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
LOGSAP(sap, LOGL_NOTICE, "LAPV5 DL-RELEASE request DLADDR=%u\n", dladdr);
|
LOGSAP(sap, LOGL_DEBUG, "LAPV5 DL-RELEASE request DLADDR=%u\n", dladdr);
|
||||||
|
|
||||||
/* prepare prim */
|
/* prepare prim */
|
||||||
msg = msgb_alloc_headroom(DLSAP_MSGB_SIZE, DLSAP_MSGB_HEADROOM, "DL REL");
|
msg = msgb_alloc_headroom(DLSAP_MSGB_SIZE, DLSAP_MSGB_HEADROOM, "DL REL");
|
||||||
msg->l3h = msg->data;
|
msg->l3h = msg->data;
|
||||||
|
memset(&dp, 0, sizeof(dp));
|
||||||
osmo_prim_init(&dp.oph, 0, PRIM_DL_REL, PRIM_OP_REQUEST, msg);
|
osmo_prim_init(&dp.oph, 0, PRIM_DL_REL, PRIM_OP_REQUEST, msg);
|
||||||
|
|
||||||
/* send to L2 */
|
/* send to L2 */
|
||||||
|
@ -325,13 +329,14 @@ int lapv5_dl_data_req(struct lapv5_instance *li, uint16_t dladdr, struct msgb *m
|
||||||
|
|
||||||
sap = lapv5_sap_find(li, dladdr);
|
sap = lapv5_sap_find(li, dladdr);
|
||||||
if (!sap) {
|
if (!sap) {
|
||||||
LOGLI(li, LOGL_INFO, "LAPV5 Tx on unknown DLADDR=%u\n", dladdr);
|
LOGLI(li, LOGL_NOTICE, "LAPV5 Tx on unknown DLADDR=%u\n", dladdr);
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare prim */
|
/* prepare prim */
|
||||||
msg->l3h = msg->data;
|
msg->l3h = msg->data;
|
||||||
|
memset(&dp, 0, sizeof(dp));
|
||||||
osmo_prim_init(&dp.oph, 0, PRIM_DL_DATA, PRIM_OP_REQUEST, msg);
|
osmo_prim_init(&dp.oph, 0, PRIM_DL_DATA, PRIM_OP_REQUEST, msg);
|
||||||
|
|
||||||
/* send to L2 */
|
/* send to L2 */
|
||||||
|
@ -395,10 +400,10 @@ static int send_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
|
||||||
|
|
||||||
switch (dp->oph.primitive) {
|
switch (dp->oph.primitive) {
|
||||||
case PRIM_DL_EST:
|
case PRIM_DL_EST:
|
||||||
LOGDL(dl, LOGL_NOTICE, "LAPD DL-ESTABLISH %s DLADDR=%u\n", op, dladdr);
|
LOGDL(dl, LOGL_DEBUG, "LAPD DL-ESTABLISH %s DLADDR=%u\n", op, dladdr);
|
||||||
break;
|
break;
|
||||||
case PRIM_DL_REL:
|
case PRIM_DL_REL:
|
||||||
LOGDL(dl, LOGL_NOTICE, "LAPD DL-RELEASE %s DLADDR=%u\n", op, dladdr);
|
LOGDL(dl, LOGL_DEBUG, "LAPD DL-RELEASE %s DLADDR=%u\n", op, dladdr);
|
||||||
lapv5_sap_free(sap);
|
lapv5_sap_free(sap);
|
||||||
/* note: sap and dl is now gone, don't use it anymore */
|
/* note: sap and dl is now gone, don't use it anymore */
|
||||||
break;
|
break;
|
||||||
|
@ -499,27 +504,25 @@ int lapv5ef_rx(struct v5x_link *link, struct msgb *msg)
|
||||||
case V5X_DLADDR_PSTN:
|
case V5X_DLADDR_PSTN:
|
||||||
/* hand-over to LAPD-DL instance for PSTN */
|
/* hand-over to LAPD-DL instance for PSTN */
|
||||||
li = link->interface->pstn.li;
|
li = link->interface->pstn.li;
|
||||||
/* TODO */
|
|
||||||
break;
|
break;
|
||||||
case V5X_DLADDR_CTRL:
|
case V5X_DLADDR_CTRL:
|
||||||
/* hand-over to LAPD-DL instance for CTRL */
|
/* hand-over to LAPD-DL instance for CTRL */
|
||||||
/* TODO */
|
|
||||||
li = link->interface->control.li;
|
li = link->interface->control.li;
|
||||||
break;
|
break;
|
||||||
case V52_DLADDR_BCC:
|
case V52_DLADDR_BCC:
|
||||||
|
/* hand-over to LAPD-DL instance for BCC */
|
||||||
li = link->interface->bcc.li;
|
li = link->interface->bcc.li;
|
||||||
/* TOOD: implement V5.2 */
|
|
||||||
msgb_free(msg);
|
|
||||||
break;
|
break;
|
||||||
case V52_DLADDR_PROTECTION:
|
case V52_DLADDR_PROTECTION:
|
||||||
li = link->interface->protection[0].li;
|
/* hand-over to LAPD-DL instance for PROTECTION */
|
||||||
/* TOOD: implement V5.2 */
|
if (link == link->interface->primary_link)
|
||||||
msgb_free(msg);
|
li = link->interface->protection.li[0];
|
||||||
|
if (link == link->interface->secondary_link)
|
||||||
|
li = link->interface->protection.li[1];
|
||||||
break;
|
break;
|
||||||
case V52_DLADDR_LCP:
|
case V52_DLADDR_LCP:
|
||||||
|
/* hand-over to LAPD-DL instance for LCP */
|
||||||
li = link->interface->lcp.li;
|
li = link->interface->lcp.li;
|
||||||
/* TOOD: implement V5.2 */
|
|
||||||
msgb_free(msg);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (efaddr >= 8176) {
|
if (efaddr >= 8176) {
|
||||||
|
@ -535,6 +538,11 @@ int lapv5ef_rx(struct v5x_link *link, struct msgb *msg)
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (!v5x_le_port_isdn_is_operational(v5up->port_fi)) {
|
||||||
|
LOGP(DV5EF, LOGL_NOTICE, "Dropping D-channel (AN->LE) message of non-operational ISDN port for EFaddr %d.\n", efaddr);
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
LOGP(DV5EF, LOGL_DEBUG, "Recevied frame for EFaddr %d: %s\n", efaddr, osmo_hexdump(msg->data, msg->len));
|
LOGP(DV5EF, LOGL_DEBUG, "Recevied frame for EFaddr %d: %s\n", efaddr, osmo_hexdump(msg->data, msg->len));
|
||||||
ph_socket_tx_msg(&v5up->ph_socket, 3, PH_PRIM_DATA_IND, msg->data, msg->len);
|
ph_socket_tx_msg(&v5up->ph_socket, 3, PH_PRIM_DATA_IND, msg->data, msg->len);
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
|
@ -556,13 +564,18 @@ int lapv5ef_tx(struct v5x_user_port *v5up, struct msgb *msg)
|
||||||
{
|
{
|
||||||
uint16_t efaddr = v5up->nr, efaddr_enc;
|
uint16_t efaddr = v5up->nr, efaddr_enc;
|
||||||
|
|
||||||
|
if (!v5x_le_port_isdn_is_operational(v5up->port_fi)) {
|
||||||
|
LOGP(DV5EF, LOGL_NOTICE, "Dropping D-channel (LE->AN) message of non-operational ISDN port for EFaddr %d.\n", efaddr);
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
/* relay function for LAPD of user ports */
|
/* relay function for LAPD of user ports */
|
||||||
LOGP(DV5EF, LOGL_DEBUG, "Sending frame for EFaddr %d: %s\n", efaddr, osmo_hexdump(msg->data, msg->len));
|
LOGP(DV5EF, LOGL_DEBUG, "Sending frame for EFaddr %d: %s\n", efaddr, osmo_hexdump(msg->data, msg->len));
|
||||||
msg->l2h = msgb_push(msg, 2);
|
msg->l2h = msgb_push(msg, 2);
|
||||||
efaddr_enc = v5x_l3_addr_enc(efaddr, 1);
|
efaddr_enc = v5x_l3_addr_enc(efaddr, 1);
|
||||||
msg->l2h[0] = efaddr_enc >> 8;
|
msg->l2h[0] = efaddr_enc >> 8;
|
||||||
msg->l2h[1] = efaddr_enc;
|
msg->l2h[1] = efaddr_enc;
|
||||||
ph_data_req_hack(msg, NULL);
|
ph_data_req_hdlc(msg, v5up->interface);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ struct lapv5_instance *lapv5_instance_alloc(int network_side,
|
||||||
int (*ph_data_req_cb)(struct msgb *msg, void *cbdata), void *ph_data_req_cbdata,
|
int (*ph_data_req_cb)(struct msgb *msg, void *cbdata), void *ph_data_req_cbdata,
|
||||||
int (*dl_receive_cb)(struct osmo_dlsap_prim *odp, uint16_t dladdr, void *rx_cbdata), void *dl_receive_cbdata,
|
int (*dl_receive_cb)(struct osmo_dlsap_prim *odp, uint16_t dladdr, void *rx_cbdata), void *dl_receive_cbdata,
|
||||||
const struct lapd_profile *profile, const char *name);
|
const struct lapd_profile *profile, const char *name);
|
||||||
|
void lapv5_instance_set_profile(struct lapv5_instance *li, const struct lapd_profile *profile);
|
||||||
|
void lapv5_instance_free(struct lapv5_instance *li);
|
||||||
|
|
||||||
int lapv5ef_rx(struct v5x_link *link, struct msgb *msg);
|
int lapv5ef_rx(struct v5x_link *link, struct msgb *msg);
|
||||||
int lapv5ef_tx(struct v5x_user_port *v5up, struct msgb *msg);
|
int lapv5ef_tx(struct v5x_user_port *v5up, struct msgb *msg);
|
||||||
|
|
Loading…
Reference in New Issue