sgsn: First PDP CTX ACT test: TC_attach_pdp_act

Change-Id: Ia1bfaca99a2a70bb097e2ee44f54e4a31b849a1b
diff --git a/library/GSUP_Types.ttcn b/library/GSUP_Types.ttcn
index 0a21999..5e6b20a 100644
--- a/library/GSUP_Types.ttcn
+++ b/library/GSUP_Types.ttcn
@@ -105,7 +105,12 @@
 				 msisdn, tag = OSMO_GSUP_MSISDN_IE;
 				 hlr_number, tag = OSMO_GSUP_HLR_NUMBER_IE;
 				 cn_domain, tag = OSMO_GSUP_CN_DOMAIN_IE;
-				 charg_char, tag = OSMO_GSUP_CHARG_CHAR_IE)"
+				 pdp_info, tag = OSMO_GSUP_PDP_INFO_IE;
+				 apn, tag = OSMO_GSUP_ACCESS_POINT_NAME_IE;
+				 pdp_qos, tag = OSMO_GSUP_PDP_QOS_IE;
+				 pdp_type, tag = OSMO_GSUP_PDP_TYPE_IE;
+				 charg_char, tag = OSMO_GSUP_CHARG_CHAR_IE;
+			)"
 };
 
 type record of GSUP_IE GSUP_IEs;
@@ -116,7 +121,6 @@
 	GSUP_CancelType	cancel_type,
 	//boolean		pdp_info_compl,
 	//boolean		freeze_ptmsi,
-	GSUP_IEs	pdp_info,
 	GSUP_IEs	auth_tuple,
 	octetstring	auts,
 	octetstring	rand,
@@ -129,6 +133,11 @@
 	GSUP_MSISDN	msisdn,
 	octetstring	hlr_number,
 	GSUP_CnDomain	cn_domain,
+	/* PDP context + nested IEs */
+	GSUP_IEs	pdp_info,
+	octetstring	apn,
+	octetstring	pdp_qos,
+	OCT2		pdp_type,
 	octetstring	charg_char
 };
 
@@ -217,6 +226,35 @@
 	}
 }
 
+template GSUP_IE ts_GSUP_IE_PdpInfo(octetstring apn, octetstring pdp_type, octetstring pdp_qos) := {
+	tag := OSMO_GSUP_PDP_INFO_IE,
+	len := 0, /* overwritten */
+	val := {
+		pdp_info := {
+			valueof(ts_GSUP_IE_APN(apn)),
+			valueof(ts_GSUP_IE_PDP_TYPE(pdp_type)),
+			valueof(ts_GSUP_IE_PDP_QOS(pdp_qos))
+		}
+	}
+}
+
+template (value) GSUP_IE ts_GSUP_IE_PDP_TYPE(OCT2 pdp_type) := {
+	tag := OSMO_GSUP_PDP_TYPE_IE,
+	len := 0,
+	val := {
+		pdp_type := pdp_type
+	}
+}
+
+template (value) GSUP_IE ts_GSUP_IE_PDP_QOS(octetstring pdp_qos) := {
+	tag := OSMO_GSUP_PDP_QOS_IE,
+	len := 0,
+	val := {
+		pdp_qos := pdp_qos
+	}
+}
+
+
 template GSUP_PDU tr_GSUP(template GSUP_MessageType msgt := ?, template GSUP_IEs ies := *) := {
 	msg_type := msgt,
 	ies := ies
@@ -428,6 +466,14 @@
 	}
 }
 
+template (value) GSUP_IE ts_GSUP_IE_APN(octetstring apn) := {
+	tag := OSMO_GSUP_ACCESS_POINT_NAME_IE,
+	len := 0, /* overwritten */
+	val := {
+		apn := apn
+	}
+}
+
 
 
 } with { encode "RAW"; variant "FIELDORDER(msb)" }
diff --git a/library/GTP_Templates.ttcn b/library/GTP_Templates.ttcn
index 02a31b6..b64289b 100644
--- a/library/GTP_Templates.ttcn
+++ b/library/GTP_Templates.ttcn
@@ -280,6 +280,71 @@
 								sgsn_ip_data, msisdn, pco)), seq)
 	}
 
+
+	template NSAPI_GTPC ts_NSAPI(BIT4 nsapi) := {
+		type_gtpc := '14'O,
+		nsapi := nsapi,
+		unused := '0000'B
+	}
+
+	template ReorderingRequired ts_ReorderReq(boolean req := false) := {
+		type_gtpc := '08'O,
+		reordreq := bool2bit(req),
+		spare := '0000000'B
+	}
+
+	template GTPC_PDUs ts_CreatePdpRespPDU(OCT1 cause, OCT4 teid_data, OCT4 teid_ctrl, BIT4 nsapi,
+						octetstring ggsn_ip_sign, octetstring ggsn_ip_data,
+						template EndUserAddress eua := omit,
+						template ProtConfigOptions pco := omit) := {
+		createPDPContextResponse := {
+			cause := { '00'O, cause },
+			reorderingRequired := ts_ReorderReq(false),
+			recovery := omit,
+			teidDataI := {
+				type_gtpc := '00'O,
+				teidDataI := teid_data
+			},
+			teidControlPlane := {
+				type_gtpc := '00'O,
+				teidControlPlane := teid_ctrl
+			},
+			nsapi := ts_NSAPI(nsapi),
+			chargingID := omit,
+			endUserAddress := eua,
+			protConfigOptions := pco,
+			ggsn_addr_controlPlane := ts_GsnAddr(ggsn_ip_sign),
+			ggsn_addr_traffic := ts_GsnAddr(ggsn_ip_data),
+			alt_ggsn_addr_controlPane := omit,
+			alt_ggsn_addr_traffic := omit,
+			qualityOfServiceProfile := ts_QosDefault,
+			commonFlags := omit,
+			aPN_Restriction := omit,
+			mS_InfoChangeReportingAction := omit,
+			bearerControlMode := omit,
+			evolvedAllocationRetentionPriorityI := omit,
+			extendedCommonFlag := omit,
+			csg_information_reporting_action := omit,
+			aPN_AMBR := omit,
+			gGSN_BackOffTime := omit,
+			private_extension_gtpc := omit
+		}
+	}
+
+	template Gtp1cUnitdata ts_GTPC_CreatePdpResp(GtpPeer peer, uint16_t seq, OCT4 teid,
+						 OCT1 cause,
+						 OCT4 teid_ctrl, OCT4 teid_data,
+						 BIT4 nsapi, octetstring ggsn_ip_sign,
+						 octetstring ggsn_ip_data,
+						 template EndUserAddress eua := omit,
+						 template ProtConfigOptions pco := omit) := {
+		peer := peer,
+		gtpc := ts_GTP1C_PDU(createPDPContextResponse, teid,
+					valueof(ts_CreatePdpRespPDU(cause, teid_data, teid_ctrl, nsapi,
+								ggsn_ip_sign, ggsn_ip_data,
+								eua, pco)), seq)
+	}
+
 	/* PCO send base template */
 	template ProtConfigOptions ts_PCO := {
 		type_gtpc := '84'O,
diff --git a/library/L3_Templates.ttcn b/library/L3_Templates.ttcn
index 9bd74db..73d2818 100644
--- a/library/L3_Templates.ttcn
+++ b/library/L3_Templates.ttcn
@@ -1766,6 +1766,130 @@
 	}
 }
 
+
+function ts_ApnTLV(template (omit) octetstring apn) return template (omit) AccessPointNameTLV {
+	if (istemplatekind(apn, "omit")) {
+		return omit;
+	} else {
+		var template (omit) AccessPointNameTLV ret := {
+			elementIdentifier := '28'O,
+			lengthIndicator := 0, /* overwritten */
+			accessPointNameValue := apn
+		}
+		return ret;
+	}
+}
+
+function ts_PcoTLV(template (omit) ProtocolConfigOptionsV pco)
+					return template (omit) ProtocolConfigOptionsTLV {
+	if (istemplatekind(pco, "omit")) {
+		return omit;
+	} else {
+		var template (omit) ProtocolConfigOptionsTLV ret := {
+			elementIdentifier := '27'O,
+			lengthIndicator := 0, /* overwritten */
+			protocolConfigOptionsV := pco
+		}
+		return ret;
+	}
+}
+
+template (value) PDU_L3_MS_SGSN ts_SM_ACT_PDP_REQ(BIT3 tid, BIT4 nsapi, BIT4 sapi, QoSV qos,
+						  PDPAddressV addr,
+						  template (omit) octetstring apn := omit,
+						  template (omit) ProtocolConfigOptionsV pco := omit
+						) := {
+	discriminator := '0000'B, /* overwritten */
+	tiOrSkip := {
+		transactionId := {
+			tio := tid,
+			tiFlag := '0'B,
+			tIExtension := omit
+		}
+	},
+	msgs := {
+		gprs_sm := {
+			activatePDPContextRequest := {
+				messageType := '00000000'B, /* overwritten */
+				requestedNSAPI := { nsapi, '0000'B },
+				requestedLLCSAPI := { sapi, '0000'B },
+				requestedQoS := {
+					lengthIndicator := 0, /* overwritten */
+					qoSV := qos
+				},
+				requestedPDPaddress := {
+					lengthIndicator := 0, /* overwritten */
+					pdpAddressV := addr
+				},
+				accessPointName := ts_ApnTLV(apn),
+				protocolConfigOpts := ts_PcoTLV(pco),
+				requestType := omit,
+				deviceProperties := omit,
+				nBIFOM_Container := omit
+			}
+		}
+	}
+}
+
+template PDU_L3_SGSN_MS tr_SM_ACT_PDP_REJ(template BIT3 tid := ?, template OCT1 cause := ?) := {
+	discriminator := '1010'B,
+	tiOrSkip := {
+		transactionId := {
+			tio := tid,
+			tiFlag := '1'B,
+			tIExtension := omit
+		}
+	},
+	msgs := {
+		gprs_sm := {
+			activatePDPContextReject := {
+				messageType := '01001111'B,
+				smCause := cause,
+				protocolConfigOpts := *,
+				backOffTimer := *,
+				reAttemptIndicator := *,
+				nBIFOM_Container := *
+			}
+		}
+	}
+}
+
+template PDU_L3_SGSN_MS tr_SM_ACT_PDP_ACCEPT(template BIT3 tid := ?, template BIT4 sapi := ?,
+					     template QoSV qos := ?)
+:= {
+	discriminator := '1010'B,
+	tiOrSkip := {
+		transactionId := {
+			tio := tid,
+			tiFlag := '1'B,
+			tIExtension := omit
+		}
+	},
+	msgs := {
+		gprs_sm := {
+			activatePDPContextAccept := {
+				messageType := '01000010'B,
+				negotiatedLLCSAPI := { sapi, '0000'B },
+				negotiatedQoS := {
+					lengthIndicator := ?,
+					qoSV := qos
+				},
+				radioPriority := ?,
+				spare := '0000'B,
+				pdpAddress := *,
+				protocolConfigOpts := *,
+				packetFlowID := *,
+				sMCause2 := *,
+				connectivityType := *,
+				wLANOffloadIndication := *,
+				nBIFOM_Container := *
+			}
+		}
+	}
+}
+
+
+
 private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring {
 	var integer suffix_len := tot_len - lengthof(prefix);
 	var charstring suffix_ch := int2str(suffix);