[gprs] LLC: Echo back the XID parameters that the MS requested
In order to finish PDP context activation and start the transfer
of SNDCP N-PDUs, we simply confirm to the MS whatever XID parameters
it requests. This of course has to be implemented with a proper
XID handshake at some other point.
diff --git a/openbsc/src/gprs_llc.c b/openbsc/src/gprs_llc.c
index dffca5e..9c75a3d 100644
--- a/openbsc/src/gprs_llc.c
+++ b/openbsc/src/gprs_llc.c
@@ -123,6 +123,7 @@
uint32_t fcs;
uint32_t fcs_calc;
uint8_t *data;
+ uint16_t data_len;
enum gprs_llc_cmd cmd;
};
@@ -291,8 +292,6 @@
static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph,
struct gprs_llc_lle *lle)
{
- struct msgb *resp;
-
switch (gph->cmd) {
case GPRS_LLC_SABM: /* Section 6.4.1.1 */
lle->v_sent = lle->v_ack = lle->v_recv = 0;
@@ -320,9 +319,15 @@
case GPRS_LLC_FRMR: /* Section 6.4.1.5 */
break;
case GPRS_LLC_XID: /* Section 6.4.1.6 */
- /* FIXME: implement XID negotiation */
- resp = msgb_alloc_headroom(4096, 1024, "LLC_XID");
- gprs_llc_tx_xid(lle, resp);
+ /* FIXME: implement XID negotiation using SNDCP */
+ {
+ struct msgb *resp;
+ uint8_t *xid;
+ resp = msgb_alloc_headroom(4096, 1024, "LLC_XID");
+ xid = msgb_put(resp, gph->data_len);
+ memcpy(xid, gph->data, gph->data_len);
+ gprs_llc_tx_xid(lle, resp);
+ }
break;
}
@@ -405,9 +410,11 @@
ghp->data += 1 + k;
break;
}
+ ghp->data_len = (llc_hdr + len - 3) - ghp->data;
} else if ((ctrl[0] & 0xc0) == 0x80) {
/* S (Supervisory) format */
ghp->data = NULL;
+ ghp->data_len = 0;
if (ctrl[0] & 0x20)
ghp->ack_req = 1;
@@ -431,6 +438,7 @@
} else if ((ctrl[0] & 0xe0) == 0xc0) {
/* UI (Unconfirmed Inforamtion) format */
ghp->data = ctrl + 2;
+ ghp->data_len = (llc_hdr + len - 3) - ghp->data;
ghp->seq_tx = (ctrl[0] & 0x7) << 6;
ghp->seq_tx |= (ctrl[1] >> 2);
@@ -448,28 +456,31 @@
} else {
/* U (Unnumbered) format: 1 1 1 P/F M4 M3 M2 M1 */
ghp->data = NULL;
+ ghp->data_len = 0;
switch (ctrl[0] & 0xf) {
- case 0:
+ case GPRS_LLC_U_NULL_CMD:
ghp->cmd = GPRS_LLC_NULL;
break;
- case 0x1:
+ case GPRS_LLC_U_DM_RESP:
ghp->cmd = GPRS_LLC_DM;
break;
- case 0x4:
+ case GPRS_LLC_U_DISC_CMD:
ghp->cmd = GPRS_LLC_DISC;
break;
- case 0x6:
+ case GPRS_LLC_U_UA_RESP:
ghp->cmd = GPRS_LLC_UA;
break;
- case 0x7:
+ case GPRS_LLC_U_SABM_CMD:
ghp->cmd = GPRS_LLC_SABM;
break;
- case 0x8:
+ case GPRS_LLC_U_FRMR_RESP:
ghp->cmd = GPRS_LLC_FRMR;
break;
- case 0xb:
+ case GPRS_LLC_U_XID:
ghp->cmd = GPRS_LLC_XID;
+ ghp->data = ctrl + 1;
+ ghp->data_len = (llc_hdr + len - 3) - ghp->data;
break;
default:
return -EIO;