aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-05-02 23:11:50 +0200
committerHarald Welte <laforge@gnumonks.org>2010-05-04 07:20:44 +0200
commit421cba4b08e3a179aa9297bd67fe192d99751277 (patch)
tree5c6a2b72a2a08aa9b86f3c819a6bb7f323bb1d63
parentba850c529e31c1a48dd7fa9db677061f80510b2a (diff)
[gprs] SGSN SM: Provide IPv4 PDP address in PDP CTX ACT ACCEPT
The message looks now fine (from wireshark point of view). However, we cannot simply echo back the QoS parameters, as the meaning in uplink and downlink connection is not the same.
-rw-r--r--openbsc/include/openbsc/gsm_04_08_gprs.h21
-rw-r--r--openbsc/src/gsm_04_08_gprs.c38
2 files changed, 45 insertions, 14 deletions
diff --git a/openbsc/include/openbsc/gsm_04_08_gprs.h b/openbsc/include/openbsc/gsm_04_08_gprs.h
index 86adea156..c953742cc 100644
--- a/openbsc/include/openbsc/gsm_04_08_gprs.h
+++ b/openbsc/include/openbsc/gsm_04_08_gprs.h
@@ -108,15 +108,6 @@ struct gsm48_act_pdp_ctx_req {
uint8_t data[0];
} __attribute__((packed));
-/* Chapter 9.5.2 / Table 9.5.2 */
-struct gsm48_act_pdp_ctx_ack {
- uint8_t llc_sapi;
- uint8_t qos_lv[4];
- uint8_t radio_prio:4,
- spare:4;
- uint8_t data[0];
-} __attribute__((packed));
-
/* Chapter 10.5.5.14 / Table 10.5.147 */
enum gsm48_gmm_cause {
GMM_CAUSE_IMSI_UNKNOWN = 0x02,
@@ -180,6 +171,18 @@ enum gsm48_pdp_state {
PDP_S_MODIFY_PENDING,
};
+/* Table 10.5.155/3GPP TS 24.008 */
+enum gsm48_pdp_type_org {
+ PDP_TYPE_ORG_ETSI = 0x00,
+ PDP_TYPE_ORG_IETF = 0x01,
+};
+enum gsm48_pdp_type_nr {
+ PDP_TYPE_N_ETSI_RESERVED = 0x00,
+ PDP_TYPE_N_ETSI_PPP = 0x01,
+ PDP_TYPE_N_IETF_IPv4 = 0x21,
+ PDP_TYPE_N_IETF_IPv6 = 0x57,
+};
+
int gprs_tlli_type(uint32_t tlli);
struct gsm_bts *gsm48_bts_by_ra_id(struct gsm_network *net,
diff --git a/openbsc/src/gsm_04_08_gprs.c b/openbsc/src/gsm_04_08_gprs.c
index 1eb4ab213..16c1a2574 100644
--- a/openbsc/src/gsm_04_08_gprs.c
+++ b/openbsc/src/gsm_04_08_gprs.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#include <openbsc/db.h>
#include <osmocore/msgb.h>
@@ -536,6 +537,27 @@ static int gsm0408_rcv_gmm(struct msgb *msg)
return rc;
}
+static void msgb_put_pdp_addr_ipv4(struct msgb *msg, uint32_t ipaddr)
+{
+ uint8_t v[6];
+
+ v[0] = PDP_TYPE_ORG_IETF;
+ v[1] = PDP_TYPE_N_IETF_IPv4;
+ *(uint32_t *)(v+2) = htonl(ipaddr);
+
+ msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
+}
+
+static void msgb_put_pdp_addr_ppp(struct msgb *msg)
+{
+ uint8_t v[2];
+
+ v[0] = PDP_TYPE_ORG_ETSI;
+ v[1] = PDP_TYPE_N_ETSI_PPP;
+
+ msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
+}
+
/* Section 9.5.2: Ativate PDP Context Accept */
static int gsm48_tx_gsm_act_pdp_acc(struct msgb *old_msg, struct gsm48_act_pdp_ctx_req *req)
{
@@ -552,11 +574,17 @@ static int gsm48_tx_gsm_act_pdp_acc(struct msgb *old_msg, struct gsm48_act_pdp_c
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
gh->msg_type = GSM48_MT_GSM_ACT_PDP_ACK;
- act_ack = (struct gsm48_act_pdp_ctx_ack *)
- msgb_put(msg, sizeof(*act_ack));
- act_ack->llc_sapi = req->req_llc_sapi;
- memcpy(act_ack->qos_lv, req->data, sizeof(act_ack->qos_lv));
- //act_ack->radio_prio = 4;
+
+ /* Negotiated LLC SAPI */
+ msgb_v_put(msg, req->req_llc_sapi);
+ /* copy QoS parameters from original request */
+ msgb_lv_put(msg, req->data[0], req->data+1);
+ /* Radio priority 10.5.7.2 */
+ msgb_v_put(msg, 4);
+ /* PDP address */
+ msgb_put_pdp_addr_ipv4(msg, 0x01020304);
+ /* Optional: Protocol configuration options */
+ /* Optional: Packet Flow Identifier */
return gsm48_gmm_sendmsg(msg, 0);
}