[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.
diff --git a/openbsc/include/openbsc/gsm_04_08_gprs.h b/openbsc/include/openbsc/gsm_04_08_gprs.h
index 86adea1..c953742 100644
--- a/openbsc/include/openbsc/gsm_04_08_gprs.h
+++ b/openbsc/include/openbsc/gsm_04_08_gprs.h
@@ -108,15 +108,6 @@
 	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 @@
 	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 1eb4ab2..16c1a25 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 @@
 	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 @@
 	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);
 }