TTCN-3 definitions for BSSMAP-LE and BSSLAP protocols

Both are part of GSM LCS and are spoken between BSC and SMLC

Change-Id: If31830be2c8e1b624579f6663e74955763db9d0e
diff --git a/library/BSSMAP_LE_Templates.ttcn b/library/BSSMAP_LE_Templates.ttcn
new file mode 100644
index 0000000..70805e7
--- /dev/null
+++ b/library/BSSMAP_LE_Templates.ttcn
@@ -0,0 +1,434 @@
+module BSSMAP_LE_Templates {
+
+/* BSSMAP-LE Templates, building on top of BSSAP_LE_Types.
+ *
+ * (C) 2017-2020 by Harald Welte <laforge@gnumonks.org>
+ * contributions by sysmocom - s.f.m.c. GmbH
+ * All rights reserved.
+ *
+ * Released under the terms of GNU General Public License, Version 2 or
+ * (at your option) any later version.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+import from General_Types all;
+import from Osmocom_Types all;
+import from GSM_Types all;
+import from BSSAP_Types all;
+import from BSSAP_LE_Types all;
+import from BSSMAP_Templates all;
+import from L3_Templates all;
+
+function ts_BSSMAP_LE_LcsCause(template (omit) BSSMAP_LE_LcsCause cause)
+return template (omit) BSSMAP_LE_IE_LcsCause {
+	if (istemplatekind(cause, "omit")) {
+		return omit;
+	}
+	var template (omit) BSSMAP_LE_IE_LcsCause ie := {
+		iei := BSSMAP_LE_IEI_IMSI,
+		len := 0,
+		cause := cause,
+		diag_val := omit
+	}
+	return ie;
+}
+function tr_BSSMAP_LE_LcsCause(template BSSMAP_LE_LcsCause cause)
+return template BSSMAP_LE_IE_LcsCause {
+	if (istemplatekind(cause, "omit")) {
+		return omit;
+	}
+	var template BSSMAP_LE_IE_LcsCause ie := {
+		iei := BSSMAP_LE_IEI_IMSI,
+		len := ?,
+		cause := cause,
+		diag_val := *
+	}
+	return ie;
+}
+
+
+function ts_BSSMAP_LE_GeographicLoc(template (omit) octetstring loc)
+return template (omit) BSSMAP_LE_IE_GeographicLoc {
+	if (istemplatekind(loc, "omit")) {
+		return omit;
+	}
+	var template (omit) BSSMAP_LE_IE_GeographicLoc ie := {
+		iei := BSSMAP_LE_IEI_GEO_LOCATION,
+		len := 0,
+		location := loc
+	}
+	return ie;
+}
+function tr_BSSMAP_LE_GeographicLoc(template octetstring loc)
+return template BSSMAP_LE_IE_GeographicLoc {
+	if (istemplatekind(loc, "omit")) {
+		return omit;
+	}
+	var template BSSMAP_LE_IE_GeographicLoc ie := {
+		iei := BSSMAP_LE_IEI_GEO_LOCATION,
+		len := ?,
+		location := loc
+	}
+	return ie;
+}
+
+
+
+
+template (value) PDU_BSSAP_LE ts_BSSAP_LE_BSSMAP := {
+	discriminator := '0'B,
+	spare := '0000000'B,
+	dlci := omit,
+	lengthIndicator := 0,	/* overwritten by codec */
+	pdu := {
+		bssmap := -
+	}
+}
+
+template (present) PDU_BSSAP_LE tr_BSSAP_LE_BSSMAP := {
+	discriminator := '0'B,
+	spare := '0000000'B,
+	dlci := *,
+	lengthIndicator := ?,
+	pdu := {
+		bssmap := ?
+	}
+}
+
+template (value) PDU_BSSAP_LE ts_BSSAP_LE_DTAP(octetstring dtap, template (value) OCT1 dlci) := {
+	discriminator := '1'B,
+	spare := '0000000'B,
+	dlci := dlci,
+	lengthIndicator := 0,	/* overwritten by codec */
+	pdu := {
+		dtap := dtap
+	}
+}
+
+template (present) PDU_BSSAP_LE tr_BSSAP_LE_DTAP := {
+	discriminator := '1'B,
+	spare := '0000000'B,
+	dlci := *,
+	lengthIndicator := ?,
+	pdu := {
+		dtap := ?
+	}
+}
+
+function ts_BSSMAP_LE_IMSI(template (omit) hexstring imsi) return template (omit) BSSMAP_LE_IE_IMSI {
+	if (istemplatekind(imsi, "omit")) {
+		return omit;
+	}
+	template (value) BSSMAP_LE_IE_IMSI res := {
+		iei := BSSMAP_LE_IEI_IMSI,
+		len := 0,
+		imsi := ts_MI_IMSI(valueof(imsi))
+	};
+	return res;
+}
+function tr_BSSMAP_LE_IMSI(template hexstring imsi) return template BSSMAP_LE_IE_IMSI {
+	if (istemplatekind(imsi, "omit")) {
+		return omit;
+	}
+	template BSSMAP_LE_IE_IMSI res := {
+		iei := BSSMAP_LE_IEI_IMSI,
+		len := ?,
+		imsi := tr_MI_IMSI(imsi)
+	};
+	return res;
+}
+
+template (value) BSSMAP_LE_IE_LocationType ts_BSSMAP_LE_LocType(template (value) BSSMAP_LE_LocInfo li,
+								template (omit) BSSMAP_LE_PosMethod pm := omit) := {
+	iei := BSSMAP_LE_IEI_LOCATION_TYPE,
+	len := 0,
+	loc_info := li,
+	pos_method := pm
+}
+template (present) BSSMAP_LE_IE_LocationType tr_BSSMAP_LE_LocType(template (present) BSSMAP_LE_LocInfo li,
+								  template BSSMAP_LE_PosMethod pm := omit) := {
+	iei := BSSMAP_LE_IEI_LOCATION_TYPE,
+	len := ?,
+	loc_info := li,
+	pos_method := pm
+}
+
+
+/* Section 9.1 */
+template (value) PDU_BSSAP_LE ts_BSMAP_LE_PerfLocReq(BSSMAP_LE_LocInfo loc_info := BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC,
+						     template (value) BSSMAP_IE_CellIdentifier cell_id,
+						     template (omit) hexstring imsi)
+
+modifies ts_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			perf_loc_req := {
+				msg_type := BSSMAP_LE_PERFORM_LOC_REQ,
+				location_type := ts_BSSMAP_LE_LocType(loc_info),
+				cell_id := cell_id,
+				cm3 := omit,
+				lcs_client_type := omit,
+				chosen_channel := omit,
+				lcs_priority := omit,
+				lcs_qos := omit,
+				req_gps_ass_d := omit,
+				bsslap_apdu := omit,
+				lcs_capability := omit,
+				packet_meas_rep := omit,
+				meas_cell_id_list := omit,
+				imsi := ts_BSSMAP_LE_IMSI(imsi),
+				imei := omit
+			}
+		}
+	}
+}
+template (present) PDU_BSSAP_LE tr_BSMAP_LE_PerfLocReq(BSSMAP_LE_LocInfo loc_info := BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC,
+						       template (present) BSSMAP_IE_CellIdentifier cell_id,
+						       template hexstring imsi)
+modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			perf_loc_req := {
+				msg_type := BSSMAP_LE_PERFORM_LOC_REQ,
+				location_type := tr_BSSMAP_LE_LocType(loc_info),
+				cell_id := cell_id,
+				cm3 := *,
+				lcs_client_type := *,
+				chosen_channel := *,
+				lcs_priority := *,
+				lcs_qos := *,
+				req_gps_ass_d := *,
+				bsslap_apdu := *,
+				lcs_capability := *,
+				packet_meas_rep := *,
+				meas_cell_id_list := *,
+				imsi := tr_BSSMAP_LE_IMSI(imsi),
+				imei := *
+			}
+		}
+	}
+}
+
+
+/* Section 9.2 */
+template (value) PDU_BSSAP_LE ts_BSMAP_LE_PerfLocResp(BSSMAP_LE_LocInfo loc_info := BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC,
+						      template (omit) octetstring geo_loc,
+						      template (omit) BSSMAP_LE_LcsCause cause)
+
+modifies ts_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			perf_loc_resp := {
+				msg_type := BSSMAP_LE_PERFORM_LOC_RESP,
+				geographic_loc := ts_BSSMAP_LE_GeographicLoc(geo_loc),
+				pos_data := omit,
+				deciph_keys := omit,
+				lcs_cause := ts_BSSMAP_LE_LcsCause(cause),
+				velocity_data := omit,
+				ganss_pos_data := omit
+			}
+		}
+	}
+}
+template (present) PDU_BSSAP_LE tr_BSMAP_LE_PerfLocResp(template BSSMAP_LE_LocInfo loc_info := BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC,
+							template octetstring geo_loc,
+							template BSSMAP_LE_LcsCause cause)
+modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			perf_loc_resp := {
+				msg_type := BSSMAP_LE_PERFORM_LOC_RESP,
+				geographic_loc := tr_BSSMAP_LE_GeographicLoc(geo_loc),
+				pos_data := *,
+				deciph_keys := *,
+				lcs_cause := tr_BSSMAP_LE_LcsCause(cause),
+				velocity_data := *,
+				ganss_pos_data := *
+			}
+		}
+	}
+}
+
+
+/* Section 9.8 */
+template (value) PDU_BSSAP_LE ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_ProtocolId prot_id, octetstring data,
+						    template (omit) BSSMAP_LE_IE_Segmentation segm := omit)
+modifies ts_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			co_info := {
+				msg_type := BSSMAP_LE_CONN_ORIENTED_INFO,
+				bsslap_apdu := {
+					iei := BSSMAP_LE_IEI_APDU,
+					len := 0,
+					spare := '0'B,
+					protocol_id := prot_id,
+					data := data
+				},
+				segmentation := segm
+			}
+		}
+	}
+}
+template (present) PDU_BSSAP_LE tr_BSSMAP_LE_ConnInfo(template (present) BSSMAP_LE_ProtocolId prot_id,
+						      template (present) octetstring data,
+						      template BSSMAP_LE_IE_Segmentation segm := omit)
+modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			co_info := {
+				msg_type := BSSMAP_LE_CONN_ORIENTED_INFO,
+				bsslap_apdu := {
+					iei := BSSMAP_LE_IEI_APDU,
+					len := ?,
+					spare := '0'B,
+					protocol_id := prot_id,
+					data := data
+				},
+				segmentation := segm
+			}
+		}
+	}
+}
+
+
+
+/* Section 9.10 */
+template (value) PDU_BSSAP_LE ts_BSSMAP_LE_Reset(myBSSMAP_Cause cause) modifies ts_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			reset := {
+				msg_type := BSSMAP_LE_RESET,
+				cause := ts_BSSMAP_IE_Cause(enum2int(cause))
+			}
+		}
+	}
+}
+template (present) PDU_BSSAP_LE tr_BSSMAP_LE_Reset modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			reset := {
+				msg_type := BSSMAP_LE_RESET,
+				cause := ?
+			}
+		}
+	}
+}
+
+/* Section 9.11 */
+template (value) PDU_BSSAP_LE ts_BSSMAP_LE_ResetAck modifies ts_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			reset := {
+				msg_type := BSSMAP_LE_RESET_ACK
+			}
+		}
+	}
+}
+template (present) PDU_BSSAP_LE tr_BSSMAP_LE_ResetAck modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			reset_ack := {
+				msg_type := BSSMAP_LE_RESET_ACK
+			}
+		}
+	}
+}
+
+function ts_BSSMAP_LE_APDU(BSSMAP_LE_ProtocolId prot_id, template (omit) octetstring data)
+return template (omit) BSSMAP_LE_IE_APDU {
+	var BSSMAP_LE_IE_APDU ie := {
+		iei := BSSMAP_LE_IEI_APDU,
+		len := 0, // overwritten
+		spare := '0'B,
+		protocol_id := prot_id
+	}
+	if (istemplatekind(data, "omit")) {
+		return omit;
+	}
+	ie.data := valueof(data);
+	return ie;
+}
+
+function tr_BSSMAP_LE_APDU(template BSSMAP_LE_ProtocolId prot_id, template octetstring data)
+return template BSSMAP_LE_IE_APDU {
+	var template BSSMAP_LE_IE_APDU ie := {
+		iei := BSSMAP_LE_IEI_APDU,
+		len := ?,
+		spare := '0'B,
+		protocol_id := prot_id
+	}
+	if (istemplatekind(data, "omit")) {
+		return omit;
+	} else if (istemplatekind(data, "*")) {
+		return *;
+	}
+	ie.data := valueof(data);
+	return ie;
+}
+
+
+/* Section 9.12 */
+template (value) PDU_BSSAP_LE ts_BSSMAP_LE_PerformLocInfo(BSSMAP_IE_CellIdentifier cell_id,
+							  BSSMAP_LE_ProtocolId prot_id,
+							  template (omit) octetstring data)
+modifies ts_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			perf_loc_info := {
+				msg_type := BSSMAP_LE_PERFORM_LOC_INFO,
+				cell_id := cell_id,
+				bsslap_apdu := ts_BSSMAP_LE_APDU(prot_id, data)
+			}
+		}
+	}
+}
+template (present) PDU_BSSAP_LE tr_BSSMAP_LE_PerformLocInfo(template (present) BSSMAP_IE_CellIdentifier cell_id,
+							    template BSSMAP_LE_ProtocolId prot_id,
+							    template octetstring data)
+modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			perf_loc_info := {
+				msg_type := BSSMAP_LE_PERFORM_LOC_INFO,
+				cell_id := cell_id,
+				bsslap_apdu := tr_BSSMAP_LE_APDU(prot_id, data)
+			}
+		}
+	}
+}
+
+/* return Layer3 octetstring inside BSSAP-LE PDU */
+function f_bssap_le_extract_l3(PDU_BSSAP_LE bssap) return template octetstring {
+	if (ischosen(bssap.pdu.bssmap)) {
+		return omit;
+	} else {
+		return bssap.pdu.dtap;
+	}
+}
+
+
+template PDU_BSSAP_LE tr_BSSMAP_LE_Paging(template hexstring imsi_digits := ?,
+					template OCT4 tmsi := *,
+					template BSSMAP_IE_ChannelNeeded chneed := *)
+modifies tr_BSSAP_LE_BSSMAP := {
+	pdu := {
+		bssmap := {
+			paging := {
+				messageType := '52'O,
+				iMSI := tr_BSSMAP_Imsi(imsi_digits),
+				tMSI := tr_BSSMAP_IE_TMSI(tmsi) ifpresent,
+				cellIdentifierList := ?,
+				channelNeeded := chneed,
+				eMLPP_Priority := omit,
+				pagingInformation := omit /* only VGCS/VBS flag */
+			}
+		}
+	}
+}
+
+
+
+
+} with { encode "RAW" };