modem: Initial integration of libosmo-gprs-{llc,sndcp}
Change-Id: I820328009ccdd1f8112aeb163efa064ec1465d2a
This commit is contained in:
parent
2b11e9e97d
commit
53996bb3d8
|
@ -27,6 +27,8 @@ enum {
|
|||
DLUA,
|
||||
DGAPK,
|
||||
DTUN,
|
||||
DLLC,
|
||||
DSNDCP,
|
||||
};
|
||||
|
||||
extern const struct log_info log_info;
|
||||
|
|
|
@ -183,6 +183,22 @@ int gsm_random_imei(struct gsm_settings *set);
|
|||
|
||||
struct gprs_settings {
|
||||
struct llist_head apn_list;
|
||||
|
||||
/* RFC1144 TCP/IP header compression */
|
||||
struct {
|
||||
int active;
|
||||
int passive;
|
||||
int s01;
|
||||
} pcomp_rfc1144;
|
||||
|
||||
/* V.42vis data compression */
|
||||
struct {
|
||||
int active;
|
||||
int passive;
|
||||
int p0;
|
||||
int p1;
|
||||
int p2;
|
||||
} dcomp_v42bis;
|
||||
};
|
||||
|
||||
int gprs_settings_init(struct osmocom_ms *ms);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
noinst_HEADERS = \
|
||||
modem.h \
|
||||
llc.h \
|
||||
sndcp.h \
|
||||
vty.h \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct osmocom_ms;
|
||||
|
||||
int modem_llc_init(struct osmocom_ms *ms, const char *cipher_plugin_path);
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct osmocom_ms;
|
||||
struct osmobb_apn;
|
||||
|
||||
int modem_sndcp_init(struct osmocom_ms *ms);
|
||||
int modem_sndcp_sn_xid_req(struct osmobb_apn *apn);
|
||||
int modem_sndcp_sn_unitdata_req(struct osmobb_apn *apn, uint8_t *npdu, size_t npdu_len);
|
|
@ -153,6 +153,18 @@ static const struct log_info_cat default_categories[] = {
|
|||
.color = "\033[0;37m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DLLC] = {
|
||||
.name = "DLLC",
|
||||
.description = "GPRS Logical Link Control Protocol (LLC)",
|
||||
.color = "\033[0;38m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DSNDCP] = {
|
||||
.name = "DSNDCP",
|
||||
.description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
|
||||
.color = "\033[0;39m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
};
|
||||
|
||||
const struct log_info log_info = {
|
||||
|
|
|
@ -18,6 +18,8 @@ bin_PROGRAMS = modem
|
|||
modem_SOURCES = \
|
||||
$(top_srcdir)/src/common/main.c \
|
||||
app_modem.c \
|
||||
llc.c \
|
||||
sndcp.c \
|
||||
vty.c \
|
||||
$(NULL)
|
||||
modem_LDADD = \
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include <osmocom/bb/common/l1l2_interface.h>
|
||||
#include <osmocom/bb/common/sysinfo.h>
|
||||
#include <osmocom/bb/common/apn.h>
|
||||
#include <osmocom/bb/modem/llc.h>
|
||||
#include <osmocom/bb/modem/sndcp.h>
|
||||
#include <osmocom/bb/modem/vty.h>
|
||||
|
||||
#include <l1ctl_proto.h>
|
||||
|
@ -105,7 +107,7 @@ static int modem_tun_data_ind_cb(struct osmo_tundev *tun, struct msgb *msg)
|
|||
LOGPAPN(LOGL_DEBUG, apn, "system wants to transmit IPv%c pkt to %s (%zu bytes)\n",
|
||||
iph->version == 4 ? '4' : '6', osmo_sockaddr_ntop(&dst.u.sa, addrstr), pkt_len);
|
||||
|
||||
/* TODO: prepare & transmit SNDCP UNITDATA.req */
|
||||
rc = modem_sndcp_sn_unitdata_req(apn, msgb_data(msg), pkt_len);
|
||||
|
||||
free_ret:
|
||||
msgb_free(msg);
|
||||
|
@ -539,6 +541,8 @@ static int _modem_start(void)
|
|||
|
||||
int l23_app_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
l23_app_start = _modem_start;
|
||||
|
||||
log_set_category_filter(osmo_stderr_target, DLGLOBAL, 1, LOGL_DEBUG);
|
||||
|
@ -548,6 +552,16 @@ int l23_app_init(void)
|
|||
app_data.ms = osmocom_ms_alloc(l23_ctx, "1");
|
||||
OSMO_ASSERT(app_data.ms);
|
||||
|
||||
if ((rc = modem_llc_init(app_data.ms, NULL))) {
|
||||
LOGP(DLLC, LOGL_FATAL, "Failed initializing LLC layer\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((rc = modem_sndcp_init(app_data.ms))) {
|
||||
LOGP(DSNDCP, LOGL_FATAL, "Failed initializing SNDCP layer\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
|
||||
lapdm_channel_set_l3(&app_data.ms->lapdm_channel, &modem_rslms_cb, app_data.ms);
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/* GPRS LLC protocol implementation as per 3GPP TS 04.64 */
|
||||
/* (C) 2023 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/lienses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/crypt/kdf.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gprs/llc/llc_prim.h>
|
||||
#include <osmocom/gprs/llc/llc.h>
|
||||
#include <osmocom/gprs/sndcp/sndcp_prim.h>
|
||||
|
||||
#include <osmocom/bb/common/logging.h>
|
||||
#include <osmocom/bb/common/apn.h>
|
||||
#include <osmocom/bb/common/ms.h>
|
||||
#include <osmocom/bb/modem/llc.h>
|
||||
|
||||
static int modem_llc_handle_ll_gmm(struct osmo_gprs_llc_prim *llc_prim)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
switch (llc_prim->oph.primitive) {
|
||||
case OSMO_GPRS_LLC_LL_UNITDATA:
|
||||
break;
|
||||
case OSMO_GPRS_LLC_LL_RESET:
|
||||
case OSMO_GPRS_LLC_LL_ESTABLISH:
|
||||
case OSMO_GPRS_LLC_LL_XID:
|
||||
case OSMO_GPRS_LLC_LL_DATA:
|
||||
case OSMO_GPRS_LLC_LL_STATUS:
|
||||
default:
|
||||
LOGP(DLLC, LOGL_NOTICE, "%s(): Unexpected Rx LL prim %u\n",
|
||||
__func__, llc_prim->oph.primitive);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg = msgb_alloc(4096, "gsm0408_rx");
|
||||
msgb_tlli(msg) = llc_prim->ll.tlli;
|
||||
msgb_gmmh(msg) = msgb_put(msg, llc_prim->ll.l3_pdu_len);
|
||||
if (llc_prim->ll.l3_pdu_len > 0)
|
||||
memcpy(msgb_gmmh(msg), llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len);
|
||||
|
||||
//TODO: submit to GMM?
|
||||
//TODO: free msg?
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int modem_llc_handle_ll_sndcp(struct osmo_gprs_llc_prim *llc_prim)
|
||||
{
|
||||
int rc;
|
||||
switch (llc_prim->oph.primitive) {
|
||||
case OSMO_GPRS_LLC_LL_RESET:
|
||||
case OSMO_GPRS_LLC_LL_ESTABLISH:
|
||||
case OSMO_GPRS_LLC_LL_XID:
|
||||
case OSMO_GPRS_LLC_LL_DATA:
|
||||
case OSMO_GPRS_LLC_LL_UNITDATA:
|
||||
case OSMO_GPRS_LLC_LL_STATUS:
|
||||
/* Forward it to upper layers, pass owneserip over to SNDCP: */
|
||||
osmo_gprs_sndcp_prim_lower_up(llc_prim);
|
||||
rc = 1; /* Tell LLC that we take ownership of the prim. */
|
||||
break;
|
||||
default:
|
||||
LOGP(DLLC, LOGL_NOTICE, "%s(): Unexpected Rx LL prim %u\n",
|
||||
__func__, llc_prim->oph.primitive);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int modem_llc_prim_up_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data)
|
||||
{
|
||||
const char *pdu_name = osmo_gprs_llc_prim_name(llc_prim);
|
||||
int rc = 0;
|
||||
|
||||
switch (llc_prim->oph.sap) {
|
||||
case OSMO_GPRS_LLC_SAP_LLGM:
|
||||
LOGP(DLLC, LOGL_DEBUG, "%s(): Rx %s TLLI=0x%08x\n",
|
||||
__func__, pdu_name, llc_prim->llgmm.tlli);
|
||||
break;
|
||||
case OSMO_GPRS_LLC_SAP_LL:
|
||||
LOGP(DLLC, LOGL_DEBUG, "%s(): Rx %s TLLI=0x%08x SAPI=%s l3=[%s]\n",
|
||||
__func__, pdu_name, llc_prim->ll.tlli,
|
||||
osmo_gprs_llc_sapi_name(llc_prim->ll.sapi),
|
||||
osmo_hexdump(llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len));
|
||||
|
||||
switch (llc_prim->ll.sapi) {
|
||||
case OSMO_GPRS_LLC_SAPI_GMM:
|
||||
rc = modem_llc_handle_ll_gmm(llc_prim);
|
||||
break;
|
||||
case OSMO_GPRS_LLC_SAPI_SNDCP3:
|
||||
case OSMO_GPRS_LLC_SAPI_SNDCP5:
|
||||
case OSMO_GPRS_LLC_SAPI_SNDCP9:
|
||||
case OSMO_GPRS_LLC_SAPI_SNDCP11:
|
||||
rc = modem_llc_handle_ll_sndcp(llc_prim);
|
||||
break;
|
||||
case OSMO_GPRS_LLC_SAPI_TOM2:
|
||||
case OSMO_GPRS_LLC_SAPI_SMS:
|
||||
case OSMO_GPRS_LLC_SAPI_TOM8:
|
||||
LOGP(DLLC, LOGL_NOTICE, "%s(): Unimplemented Rx llc_sapi %s\n", __func__, pdu_name);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
default:
|
||||
LOGP(DLLC, LOGL_NOTICE, "%s(): Unexpected Rx llc_sapi %s\n", __func__, pdu_name);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGP(DLLC, LOGL_NOTICE, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int modem_llc_prim_down_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data)
|
||||
{
|
||||
const char *pdu_name = osmo_gprs_llc_prim_name(llc_prim);
|
||||
int rc = 0;
|
||||
|
||||
switch (llc_prim->oph.sap) {
|
||||
case OSMO_GPRS_LLC_SAP_GRR:
|
||||
LOGP(DLLC, LOGL_DEBUG, "%s(): Rx %s l3=[%s]\n", __func__, pdu_name,
|
||||
osmo_hexdump(llc_prim->grr.ll_pdu, llc_prim->grr.ll_pdu_len));
|
||||
break;
|
||||
default:
|
||||
LOGP(DLLC, LOGL_DEBUG, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int modem_llc_init(struct osmocom_ms *ms, const char *cipher_plugin_path)
|
||||
{
|
||||
int rc;
|
||||
rc = osmo_gprs_llc_init(OSMO_GPRS_LLC_LOCATION_MS, cipher_plugin_path);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
osmo_gprs_llc_set_log_cat(OSMO_GPRS_LLC_LOGC_LLC, DLLC);
|
||||
|
||||
osmo_gprs_llc_prim_set_up_cb(modem_llc_prim_up_cb, ms);
|
||||
osmo_gprs_llc_prim_set_down_cb(modem_llc_prim_down_cb, ms);
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/* GPRS SNDCP User/SN/SNSM interfaces as per 3GPP TS 04.65 */
|
||||
/* (C) 2023 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/lienses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/endian.h>
|
||||
#include <osmocom/core/tun.h>
|
||||
|
||||
#include <osmocom/gprs/llc/llc.h>
|
||||
#include <osmocom/gprs/llc/llc_prim.h>
|
||||
#include <osmocom/gprs/sndcp/sndcp_prim.h>
|
||||
#include <osmocom/gprs/sndcp/sndcp.h>
|
||||
|
||||
#include <osmocom/bb/common/logging.h>
|
||||
#include <osmocom/bb/common/apn.h>
|
||||
#include <osmocom/bb/common/ms.h>
|
||||
#include <osmocom/bb/modem/sndcp.h>
|
||||
|
||||
/* Received SN-XID.cnf from SNDCP layer: */
|
||||
static int modem_sndcp_handle_sn_xid_cnf(struct osmobb_apn *apn, struct osmo_gprs_sndcp_prim *sndcp_prim)
|
||||
{
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Rx SN-XID.cnf: TODO IMPLEMENT!\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Received SN-UNITDTA.ind from SNDCP layer: */
|
||||
static int modem_sndcp_handle_sn_unitdata_ind(struct osmobb_apn *apn, struct osmo_gprs_sndcp_prim *sndcp_prim)
|
||||
{
|
||||
const char *npdu_name = osmo_gprs_sndcp_prim_name(sndcp_prim);
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
|
||||
LOGP(DSNDCP, LOGL_DEBUG, "Rx %s TLLI=0x%08x SAPI=%s NSAPI=%u NPDU=[%s]\n",
|
||||
npdu_name,
|
||||
sndcp_prim->sn.tlli, osmo_gprs_llc_sapi_name(sndcp_prim->sn.sapi),
|
||||
sndcp_prim->sn.data_req.nsapi,
|
||||
osmo_hexdump(sndcp_prim->sn.data_ind.npdu, sndcp_prim->sn.data_ind.npdu_len));
|
||||
|
||||
msg = msgb_alloc(sndcp_prim->sn.data_ind.npdu_len, "tx_tun");
|
||||
memcpy(msgb_put(msg, sndcp_prim->sn.data_ind.npdu_len),
|
||||
sndcp_prim->sn.data_ind.npdu,
|
||||
sndcp_prim->sn.data_ind.npdu_len);
|
||||
rc = osmo_tundev_send(apn->tun, msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int modem_sndcp_prim_up_cb(struct osmo_gprs_sndcp_prim *sndcp_prim, void *user_data)
|
||||
{
|
||||
struct osmocom_ms *ms = user_data;
|
||||
struct osmobb_apn *apn;
|
||||
const char *npdu_name = osmo_gprs_sndcp_prim_name(sndcp_prim);
|
||||
int rc = 0;
|
||||
|
||||
if (sndcp_prim->oph.sap != OSMO_GPRS_SNDCP_SAP_SN) {
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Unexpected Rx %s\n", __func__, npdu_name);
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
|
||||
/* TODO: properly retrieve APN/PDP based on TLLI/SAPI/NSAPI: */
|
||||
apn = llist_first_entry_or_null(&ms->gprs.apn_list, struct osmobb_apn, list);
|
||||
if (!apn) {
|
||||
LOGP(DSNDCP, LOGL_NOTICE, "Unable to find destination APN: Rx %s\n", npdu_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (OSMO_PRIM_HDR(&sndcp_prim->oph)) {
|
||||
case OSMO_PRIM(OSMO_GPRS_SNDCP_SN_UNITDATA, PRIM_OP_INDICATION):
|
||||
rc = modem_sndcp_handle_sn_unitdata_ind(apn, sndcp_prim);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_GPRS_SNDCP_SN_XID, PRIM_OP_CONFIRM):
|
||||
rc = modem_sndcp_handle_sn_xid_cnf(apn, sndcp_prim);
|
||||
break;
|
||||
default:
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Rx %s UNIMPLEMENTED\n", __func__, npdu_name);
|
||||
break;
|
||||
};
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int modem_sndcp_prim_down_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data)
|
||||
{
|
||||
const char *pdu_name = osmo_gprs_llc_prim_name(llc_prim);
|
||||
int rc = 0;
|
||||
|
||||
if (llc_prim->oph.sap != OSMO_GPRS_LLC_SAP_LL) {
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
|
||||
switch (OSMO_PRIM_HDR(&llc_prim->oph)) {
|
||||
case OSMO_PRIM(OSMO_GPRS_LLC_LL_UNITDATA, PRIM_OP_REQUEST):
|
||||
LOGP(DSNDCP, LOGL_DEBUG, "%s(): Rx %s TLLI=0x%08x SAPI=%s L3=[%s]\n",
|
||||
__func__, pdu_name,
|
||||
llc_prim->ll.tlli, osmo_gprs_llc_sapi_name(llc_prim->ll.sapi),
|
||||
osmo_hexdump(llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len));
|
||||
rc = osmo_gprs_llc_prim_upper_down(llc_prim);
|
||||
rc = 1; /* Tell SNDCP layer we took msgb ownsership and transfer it to LLC */
|
||||
break;
|
||||
default:
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Rx %s UNIMPLEMENTED\n", __func__, pdu_name);
|
||||
break;
|
||||
};
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int modem_sndcp_prim_snsm_cb(struct osmo_gprs_sndcp_prim *sndcp_prim, void *user_data)
|
||||
{
|
||||
const char *npdu_name = osmo_gprs_sndcp_prim_name(sndcp_prim);
|
||||
|
||||
if (sndcp_prim->oph.sap != OSMO_GPRS_SNDCP_SAP_SNSM) {
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Unexpected Rx %s\n", __func__, npdu_name);
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
|
||||
LOGP(DSNDCP, LOGL_ERROR, "%s(): Rx %s UNIMPLEMENTED\n", __func__, npdu_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int modem_sndcp_init(struct osmocom_ms *ms)
|
||||
{
|
||||
int rc;
|
||||
rc = osmo_gprs_sndcp_init();
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
osmo_gprs_sndcp_set_log_cat(OSMO_GPRS_SNDCP_LOGC_SNDCP, DSNDCP);
|
||||
osmo_gprs_sndcp_set_log_cat(OSMO_GPRS_SNDCP_LOGC_SLHC, DSNDCP);
|
||||
|
||||
osmo_gprs_sndcp_prim_set_up_cb(modem_sndcp_prim_up_cb, ms);
|
||||
osmo_gprs_sndcp_prim_set_down_cb(modem_sndcp_prim_down_cb, ms);
|
||||
osmo_gprs_sndcp_prim_set_snsm_cb(modem_sndcp_prim_snsm_cb, ms);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int modem_sndcp_sn_xid_req(struct osmobb_apn *apn)
|
||||
{
|
||||
struct osmo_gprs_sndcp_prim *sndcp_prim;
|
||||
int rc;
|
||||
struct osmocom_ms *ms = apn->ms;
|
||||
struct gprs_settings *set = &ms->gprs;
|
||||
|
||||
/* TODO: look up PDP context IDs from ms once we have GMM layer. */
|
||||
uint32_t tlli = 0xe1c5d364;
|
||||
uint8_t sapi = OSMO_GPRS_LLC_SAPI_SNDCP3;
|
||||
uint8_t nsapi = 1;
|
||||
|
||||
sndcp_prim = osmo_gprs_sndcp_prim_alloc_sn_xid_req(tlli, sapi, nsapi);
|
||||
OSMO_ASSERT(sndcp_prim);
|
||||
sndcp_prim->sn.xid_req.pcomp_rfc1144.active = set->pcomp_rfc1144.active;
|
||||
sndcp_prim->sn.xid_req.pcomp_rfc1144.s01 = set->pcomp_rfc1144.s01;
|
||||
sndcp_prim->sn.xid_req.dcomp_v42bis.active = set->dcomp_v42bis.active;
|
||||
sndcp_prim->sn.xid_req.dcomp_v42bis.p0 = set->dcomp_v42bis.p0;
|
||||
sndcp_prim->sn.xid_req.dcomp_v42bis.p1 = set->dcomp_v42bis.p1;
|
||||
sndcp_prim->sn.xid_req.dcomp_v42bis.p2 = set->dcomp_v42bis.p2;
|
||||
rc = osmo_gprs_sndcp_prim_upper_down(sndcp_prim);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int modem_sndcp_sn_unitdata_req(struct osmobb_apn *apn, uint8_t *npdu, size_t npdu_len)
|
||||
{
|
||||
struct osmo_gprs_sndcp_prim *sndcp_prim;
|
||||
int rc;
|
||||
|
||||
/* TODO: look up PDP context IDs from apn->ms once we have GMM layer. */
|
||||
uint32_t tlli = 0xe1c5d364;
|
||||
uint8_t sapi = OSMO_GPRS_LLC_SAPI_SNDCP3;
|
||||
uint8_t nsapi = 1;
|
||||
|
||||
sndcp_prim = osmo_gprs_sndcp_prim_alloc_sn_unitdata_req(tlli, sapi, nsapi, npdu, npdu_len);
|
||||
OSMO_ASSERT(sndcp_prim);
|
||||
rc = osmo_gprs_sndcp_prim_upper_down(sndcp_prim);
|
||||
return rc;
|
||||
}
|
Loading…
Reference in New Issue