From ea260349dee80886014748784f8ab3c27ebe0b3c Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 1 Aug 2019 09:49:38 +0200 Subject: [PATCH] Add CBSP (Cell Broadcast Service Protocol) types + templates Change-Id: Ida2e0af7d282fd7d5318110c05efa5a10114242c --- library/CBSP_Templates.ttcn | 744 ++++++++++++++++++++++++++++++++++++ library/CBSP_Types.ttcn | 381 ++++++++++++++++++ 2 files changed, 1125 insertions(+) create mode 100644 library/CBSP_Templates.ttcn create mode 100644 library/CBSP_Types.ttcn diff --git a/library/CBSP_Templates.ttcn b/library/CBSP_Templates.ttcn new file mode 100644 index 000000000..3c60f14b4 --- /dev/null +++ b/library/CBSP_Templates.ttcn @@ -0,0 +1,744 @@ +module CBSP_Templates { + +import from Osmocom_Types all; +import from BSSAP_Types all; +import from CBSP_Types all; + +/* TODO: receive templates must match IEs in any arbitrary order */ + +/* For some reason the TTCN-3 RAW codec cannot automatically figure out the IEI + * that it needs to set for a given union-choice (body). So we have to explicitly + * specify the IEI by the caller :( */ +template (value) CBSP_IE ts_CBSP_IE(CBSP_IEI iei, template (value) CBSP_IE_Body body) := { + iei := iei, + body := body +} + +template CBSP_IE tr_CBSP_IE(template CBSP_IE_Body body) := { + iei := ?, + body := body +} + + +template (value) CBSP_IE ts_CbspMsgId(template (value) uint16_t val) := + ts_CBSP_IE(CBSP_IEI_MSG_ID, {msg_id := val}); +template CBSP_IE tr_CbspMsgId(template uint16_t val := ?) := + tr_CBSP_IE({msg_id := val}); + +template (value) CBSP_IE ts_NewSerNo(template (value) uint16_t val) := + ts_CBSP_IE(CBSP_IEI_NEW_SERIAL_NR, {new_ser_nr := val}); +template CBSP_IE tr_NewSerNo(template uint16_t val := ?) := + tr_CBSP_IE({new_ser_nr := val}); + +template (value) CBSP_IE ts_OldSerNo(template (value) uint16_t val) := + ts_CBSP_IE(CBSP_IEI_OLD_SERIAL_NR, {old_ser_nr := val}); +template CBSP_IE tr_OldSerNo(template uint16_t val := ?) := + tr_CBSP_IE({old_ser_nr := val}); + +template (value) CBSP_IE ts_CbspKARepPeriod(template (value) uint8_t rep_per) := + ts_CBSP_IE(CBSP_IEI_KEEP_ALIVE_REP_PERIOD, {keep_alive_rep_period := rep_per}); +template CBSP_IE tr_CbspKARepPeriod(template uint8_t rep_per := ?) := + tr_CBSP_IE({keep_alive_rep_period := rep_per}); + +function ts_CbspChannelInd(template (omit) uint8_t val) return template (omit) CBSP_IE { + var template (omit) CBSP_IE ie; + if (istemplatekind(val, "omit")) { + ie := omit; + } else { + ie := ts_CBSP_IE(CBSP_IEI_CHANNEL_IND, {channel_ind := val}); + } + return ie; +} +function tr_CbspChannelInd(template uint8_t val := ?) return template CBSP_IE { + var template CBSP_IE ie; + if (istemplatekind(val, "omit")) { + ie := omit; + } else if (istemplatekind(val, "*")) { + ie := tr_CBSP_IE({channel_ind := ?}) ifpresent; + } else { + ie := tr_CBSP_IE({channel_ind := val}); + } + return ie; +} + +template (value) CBSP_IE ts_CbspCause(template (value) CBSP_Cause c) := + ts_CBSP_IE(CBSP_IEI_CAUSE, {cause := c}); +template CBSP_IE tr_CbspCause(template CBSP_Cause c := ?) := + tr_CBSP_IE({cause := c}); + +template (value) CBSP_IE ts_CbspCellList(template (value) BSSMAP_FIELD_CellIdentificationList list) := + ts_CBSP_IE(CBSP_IEI_CELL_LIST, { + cell_list := { + len := 0, + spare1_4 := '0000'B, + cell_id_discr := '0000'B, + cell_id := list + }}); +template CBSP_IE tr_CbspCellList(template BSSMAP_FIELD_CellIdentificationList list := ?) := + tr_CBSP_IE({ + cell_list := { + len := ?, + spare1_4 := ?, + cell_id_discr := ?, + cell_id := list + }}); + +template (value) CBSP_IE ts_CbspCategory(template (value) CBSP_Category cat) := + ts_CBSP_IE(CBSP_IEI_CATEGORY, {category := cat}); +template CBSP_IE tr_CbspCategory(template CBSP_Category cat := ?) := + tr_CBSP_IE({category := cat}); + +template (value) CBSP_IE ts_CbspRepetitionPeriod(template (value) uint16_t per) := + ts_CBSP_IE(CBSP_IEI_REP_PERIOD, {rep_period := per}); +template CBSP_IE tr_CbspRepetitionPeriod(template uint16_t per := ?) := + tr_CBSP_IE({rep_period := per}); + +template (value) CBSP_IE ts_CbspNumBcastReq(template (value) uint16_t num) := + ts_CBSP_IE(CBSP_IEI_NUM_BCAST_REQ, {num_bcast_req := num}); +template CBSP_IE tr_CbspNumBcastReq(template uint16_t num := ?) := + tr_CBSP_IE({num_bcast_req := num}); + +template (value) CBSP_IE ts_CbspNumPages(template (value) uint8_t num) := + ts_CBSP_IE(CBSP_IEI_NUM_OF_PAGES, {num_of_pages := num}); +template CBSP_IE tr_CbspNumPages(template uint16_t num := ?) := + tr_CBSP_IE({num_of_pages := num}); + +template (value) CBSP_IE ts_EmergencyInd(template (value) uint8_t val) := + ts_CBSP_IE(CBSP_IEI_EMERG_IND, {emerg_ind := val}); +template CBSP_IE tr_EmergencyInd(template uint8_t val := ?) := + tr_CBSP_IE({emerg_ind := val}); + +template (value) CBSP_IE ts_WarningType(template (value) uint16_t val) := + ts_CBSP_IE(CBSP_IEI_WARN_TYPE, {warn_type := val}); +template CBSP_IE tr_WarningType(template uint16_t val) := + tr_CBSP_IE({warn_type := val}); + +template (value) CBSP_IE ts_WarnSecInfo(template (value) octetstring payl := ''O) := + ts_CBSP_IE(CBSP_IEI_WARN_SEC_INFO, {warn_sec_info := payl}); +template CBSP_IE tr_WarnSecInfo(template octetstring payl := ?) := + tr_CBSP_IE({warn_sec_info := payl}); + +template (value) CBSP_IE ts_WarningPeriod(template (value) uint8_t val) := + ts_CBSP_IE(CBSP_IEI_WARNING_PERIOD, {warning_period := val}); +template CBSP_IE tr_WarningPeriod(template uint8_t val := ?) := + tr_CBSP_IE({warning_period := val}); + +template (value) CBSP_IE ts_CbspFailList(template (value) CBSP_FailureListItems items) := + ts_CBSP_IE(CBSP_IEI_FAILURE_LIST, {failure_list := { + len := 0, + list := items + }}); +template CBSP_IE tr_CbspFailList(template CBSP_FailureListItems items := ?) := + tr_CBSP_IE({failure_list := { + len := 0, + list := items + }}); + +template (value) CBSP_IE ts_CbspNumComplList(template (value) CBSP_IE_NumBcastComplList list) := + ts_CBSP_IE(CBSP_IEI_NUM_BCAST_COMPL_LIST, {num_bcast_compl_list := list}); +template CBSP_IE tr_CbspNumComplList(template CBSP_IE_NumBcastComplList list := ?) := + tr_CBSP_IE({num_bcast_compl_list := list}); + +template (value) CBSP_IE ts_CbspBcastMsgType(template (value) CBSP_BcastMsgType bi) := + ts_CBSP_IE(CBSP_IEI_BCAST_MSG_TYPE, {bcast_msg_type := { + spare1_4 := '0000'B, + msg_type := bi + }}); +template CBSP_IE tr_CbspBcastMsgType(template CBSP_BcastMsgType bi := ?) := + tr_CBSP_IE({bcast_msg_type := { + spare1_4 := ?, + msg_type := bi + }}); + +template (value) CBSP_IE ts_CbspRecoveryInd(template (value) CBSP_RecoveryInd ri) := + ts_CBSP_IE(CBSP_IEI_RECOVERY_IND, {recovery_ind := { + spare1_4 := '0000'B, + recovery := ri + }}); +template CBSP_IE tr_CbspRecoveryInd(template CBSP_RecoveryInd ri) := + tr_CBSP_IE({recovery_ind := { + spare1_4 := ?, + recovery := ri + }}); + +template (value) CBSP_IE ts_CbspMsgContent(template (value) octetstring payload, uint8_t user_len) := + ts_CBSP_IE(CBSP_IEI_MSG_CONTENT, {msg_content := { + user_len := user_len, + val := payload + }}); +template CBSP_IE tr_CbspMsgContent(template octetstring payload := ?, template uint8_t user_len := ?) := + tr_CBSP_IE({msg_content := { + user_len := user_len, + val := payload + }}); + +template (value) CBSP_IE ts_CbspDCS(template (value) uint8_t dcs) := + ts_CBSP_IE(CBSP_IEI_DCS, {dcs := dcs}); +template CBSP_IE tr_CbspDCS(template uint8_t dcs := ?) := + tr_CBSP_IE({dcs := dcs}); + + +template (value) CBSP_PDU ts_CBSP(CBSP_MessageType msg_type, template (value) CBSP_IEs ies) := { + msg_type := msg_type, + len := 0, /* overwritten */ + ies := ies +} +template CBSP_PDU tr_CBSP(template CBSP_MessageType msg_type := ?, template CBSP_IEs ies := *) := { + msg_type := msg_type, + len := ?, + ies := ies +} + + + +/* 8.1.3.1 WRITE REPLACE */ +function ts_CBSP_WRITE_CBS(template (value) uint16_t msg_id, + template (value) uint16_t new_ser_nr, + template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t channel_ind, + template (value) CBSP_Category category, + template (value) uint16_t rep_period, + template (value) uint16_t num_bcast_req, + template (value) uint8_t dcs, + template (value) CBSP_IEs content) return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_CbspCellList(cell_list), + ts_CbspChannelInd(channel_ind), + ts_CbspCategory(category), + ts_CbspRepetitionPeriod(rep_period), + ts_CbspNumBcastReq(num_bcast_req), + ts_CbspDCS(dcs), + ts_CbspNumPages(lengthof(content)) + }; + return ts_CBSP(CBSP_MSGT_WRITE_REPLACE, valueof(ies) & valueof(content)); +} +template CBSP_PDU tr_CBSP_WRITE_CBS(template uint16_t msg_id := ?, template uint16_t new_ser_nr := ?, + template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template uint8_t channel_ind := ?, + template CBSP_Category category := ?, + template uint16_t rep_period := ?, + template uint16_t num_bcast_req := ?, + template uint8_t dcs := ?, + template CBSP_IEs content := ? + ) := + tr_CBSP(CBSP_MSGT_WRITE_REPLACE, ({ + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_CbspCellList(cell_list), + tr_CbspChannelInd(channel_ind), + tr_CbspCategory(category), + tr_CbspRepetitionPeriod(rep_period), + tr_CbspNumBcastReq(num_bcast_req), + tr_CbspDCS(dcs), + tr_CbspNumPages(lengthof(content)), all from content })); + + +function ts_CBSP_REPLACE_CBS(uint16_t msg_id, uint16_t new_ser_nr, uint16_t old_ser_nr, + template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t channel_ind, + template (value) CBSP_Category category, + template (value) uint16_t rep_period, + template (value) uint16_t num_bcast_req, + template (value) uint8_t dcs, + template (value) CBSP_IEs content) return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_OldSerNo(old_ser_nr), + ts_CbspCellList(cell_list), + ts_CbspChannelInd(channel_ind), + ts_CbspCategory(category), + ts_CbspRepetitionPeriod(rep_period), + ts_CbspNumBcastReq(num_bcast_req), + ts_CbspDCS(dcs), + ts_CbspNumPages(lengthof(content)) + }; + return ts_CBSP(CBSP_MSGT_WRITE_REPLACE, valueof(ies) & valueof(content)); +} +template CBSP_PDU tr_CBSP_REPLACE_CBS(template uint16_t msg_id := ?, template uint16_t new_ser_nr := ?, + template uint16_t old_ser_nr := ?, + template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template uint8_t channel_ind := ?, + template CBSP_Category category := ?, + template uint16_t rep_period := ?, + template uint16_t num_bcast_req := ?, + template uint8_t dcs := ?, + template CBSP_IEs content := ? + ) := + tr_CBSP(CBSP_MSGT_WRITE_REPLACE, ({ + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_OldSerNo(old_ser_nr), + tr_CbspCellList(cell_list), + tr_CbspChannelInd(channel_ind), + tr_CbspCategory(category), + tr_CbspRepetitionPeriod(rep_period), + tr_CbspNumBcastReq(num_bcast_req), + tr_CbspDCS(dcs), + tr_CbspNumPages(lengthof(content)), all from content })); + +template (value) CBSP_PDU ts_CBSP_WRITE_EMERG(uint16_t msg_id, uint16_t new_ser_nr, + template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t emerg_ind, + template (value) uint16_t warn_type, + template (value) uint16_t num_bcast_req, + template (value) uint8_t warn_per + ) := + ts_CBSP(CBSP_MSGT_WRITE_REPLACE, { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_CbspCellList(cell_list), + ts_EmergencyInd(emerg_ind), + ts_WarningType(warn_type), + ts_WarnSecInfo, + ts_WarningPeriod(warn_per) }); +template CBSP_PDU tr_CBSP_WRITE_EMERG(template uint16_t msg_id := ?, template uint16_t new_ser_nr := ?, + template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template uint8_t emerg_ind := ?, + template uint16_t warn_type := ?, + template uint16_t num_bcast_req := ?, + template uint8_t warn_per := ? + ) := + tr_CBSP(CBSP_MSGT_WRITE_REPLACE, { + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_CbspCellList(cell_list), + tr_EmergencyInd(emerg_ind), + tr_WarningType(warn_type), + tr_WarnSecInfo, + tr_WarningPeriod(warn_per) }); + + +template (value) CBSP_PDU ts_CBSP_REPLACE_EMERG(uint16_t msg_id, uint16_t new_ser_nr, uint16_t old_ser_nr, + template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t emerg_ind, + template (value) uint16_t warn_type, + template (value) uint16_t num_bcast_req, + template (value) uint8_t warn_per + ) := + ts_CBSP(CBSP_MSGT_WRITE_REPLACE, { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_OldSerNo(old_ser_nr), + ts_CbspCellList(cell_list), + ts_EmergencyInd(emerg_ind), + ts_WarningType(warn_type), + ts_WarnSecInfo, + ts_WarningPeriod(warn_per) }); +template CBSP_PDU tr_CBSP_REPLACE_EMERG(template uint16_t msg_id := ?, template uint16_t new_ser_nr := ?, + template uint16_t old_ser_nr := ?, + template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template uint8_t emerg_ind := ?, + template uint16_t warn_type := ?, + template uint16_t num_bcast_req := ?, + template uint8_t warn_per := ? + ) := + tr_CBSP(CBSP_MSGT_WRITE_REPLACE, { + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_OldSerNo(old_ser_nr), + tr_CbspCellList(cell_list), + tr_EmergencyInd(emerg_ind), + tr_WarningType(warn_type), + tr_WarnSecInfo, + tr_WarningPeriod(warn_per) }); + +/* 8.1.3.2 WRITE-REPLACE COMPLETE */ +function ts_CBSP_WRITE_CBS_COMPL(uint16_t msg_id, uint16_t new_ser_nr, + template (omit) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t channel_ind) +return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr) + }; + if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := ts_CbspCellList(cell_list); + } + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies); +} +function tr_CBSP_WRITE_CBS_COMPL(template uint16_t msg_id, template uint16_t new_ser_nr, + template BSSMAP_FIELD_CellIdentificationList cell_list, + template uint8_t channel_ind) +return template CBSP_PDU { + var template CBSP_IEs ies := { + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr) + }; + if (istemplatekind(cell_list, "*")) { + ies[lengthof(ies)] := tr_CbspCellList ifpresent; + } else if (istemplatekind(cell_list, "?")) { + ies[lengthof(ies)] := tr_CbspCellList(?); + } else if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := tr_CbspCellList(cell_list); + } + ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind); + return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies); +} + + +function ts_CBSP_REPLACE_CBS_COMPL(uint16_t msg_id, uint16_t new_ser_nr, uint16_t old_ser_nr, + template (value) CBSP_IE_NumBcastComplList compl_list, + template (omit) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t channel_ind) +return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_OldSerNo(old_ser_nr), + ts_CbspNumComplList(compl_list) + }; + if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := ts_CbspCellList(cell_list); + } + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies); +} +function tr_CBSP_REPLACE_CBS_COMPL(template uint16_t msg_id, template uint16_t new_ser_nr, + template uint16_t old_ser_nr, + template CBSP_IE_NumBcastComplList compl_list, + template BSSMAP_FIELD_CellIdentificationList cell_list, + template uint8_t channel_ind) +return template CBSP_PDU { + var template CBSP_IEs ies := { + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_OldSerNo(old_ser_nr), + tr_CbspNumComplList(compl_list) + }; + if (istemplatekind(cell_list, "*")) { + ies[lengthof(ies)] := tr_CbspCellList ifpresent; + } else if (istemplatekind(cell_list, "?")) { + ies[lengthof(ies)] := tr_CbspCellList(?); + } else if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := tr_CbspCellList(cell_list); + } + ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind); + return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_COMPL, ies); +} + + +/* 8.1.3.3 WRITE-REPLACE FAILURE */ +function ts_CBSP_WRITE_CBS_FAIL(uint16_t msg_id, uint16_t new_ser_nr, + template (value) CBSP_FailureListItems fail_list, + template (omit) CBSP_IE_NumBcastComplList compl_list, + template (omit) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t channel_ind) +return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_CbspFailList(fail_list) + }; + if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := ts_CbspNumComplList(compl_list); + } + if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := ts_CbspCellList(cell_list); + } + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_FAIL, ies); +} +function tr_CBSP_WRITE_CBS_FAIL(template uint16_t msg_id, template uint16_t new_ser_nr, + template CBSP_FailureListItems fail_list, + template CBSP_IE_NumBcastComplList compl_list, + template BSSMAP_FIELD_CellIdentificationList cell_list, + template uint8_t channel_ind) +return template CBSP_PDU { + var template CBSP_IEs ies := { + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_CbspFailList(fail_list) + }; + if (istemplatekind(compl_list, "*")) { + ies[lengthof(ies)] := tr_CbspNumComplList ifpresent; + } else if (istemplatekind(compl_list, "?")) { + ies[lengthof(ies)] := tr_CbspNumComplList(?); + } else if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := tr_CbspNumComplList(compl_list); + } + if (istemplatekind(cell_list, "*")) { + ies[lengthof(ies)] := tr_CbspCellList ifpresent; + } else if (istemplatekind(cell_list, "?")) { + ies[lengthof(ies)] := tr_CbspCellList(?); + } else if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := tr_CbspCellList(cell_list); + } + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_FAIL, ies); +} + + +function ts_CBSP_REPLACE_CBS_FAIL(uint16_t msg_id, uint16_t new_ser_nr, uint16_t old_ser_nr, + template (value) CBSP_FailureListItems fail_list, + template (omit) CBSP_IE_NumBcastComplList compl_list, + template (omit) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) uint8_t channel_ind) +return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_NewSerNo(new_ser_nr), + ts_OldSerNo(old_ser_nr), + ts_CbspFailList(fail_list) + }; + if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := ts_CbspNumComplList(compl_list); + } + if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := ts_CbspCellList(cell_list); + } + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + return ts_CBSP(CBSP_MSGT_WRITE_REPLACE_FAIL, ies); +} +function tr_CBSP_REPLACE_CBS_FAIL(template uint16_t msg_id, template uint16_t new_ser_nr, + template uint16_t old_ser_nr, + template CBSP_FailureListItems fail_list, + template CBSP_IE_NumBcastComplList compl_list, + template BSSMAP_FIELD_CellIdentificationList cell_list, + template uint8_t channel_ind) +return template CBSP_PDU { + var template CBSP_IEs ies := { + tr_CbspMsgId(msg_id), + tr_NewSerNo(new_ser_nr), + tr_OldSerNo(old_ser_nr), + tr_CbspFailList(fail_list) + }; + if (istemplatekind(compl_list, "*")) { + ies[lengthof(ies)] := tr_CbspCellList ifpresent; + } else if (istemplatekind(compl_list, "?")) { + ies[lengthof(ies)] := tr_CbspNumComplList(?); + } else if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := tr_CbspNumComplList(compl_list); + } + if (istemplatekind(cell_list, "*")) { + ies[lengthof(ies)] := tr_CbspCellList ifpresent; + } else if (istemplatekind(cell_list, "?")) { + ies[lengthof(ies)] := tr_CbspCellList(?); + } else if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := tr_CbspCellList(cell_list); + } + ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind); + return tr_CBSP(CBSP_MSGT_WRITE_REPLACE_FAIL, ies); +} + +/* 8.1.3.4 KILL */ +template (value) CBSP_PDU ts_CBSP_KILL(template (value) uint16_t msg_id, + template (value) uint16_t old_ser_nr, + template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (omit) uint8_t channel_ind) := + ts_CBSP(CBSP_MSGT_KILL, { + ts_CbspMsgId(msg_id), + ts_OldSerNo(old_ser_nr), + ts_CbspCellList(cell_list), + ts_CbspChannelInd(channel_ind)}); +template CBSP_PDU tr_CBSP_KILL(template uint16_t msg_id := ?, template uint16_t old_ser_nr := ?, + template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template uint8_t channel_ind := ?) := + tr_CBSP(CBSP_MSGT_KILL, { + tr_CbspMsgId(msg_id), + tr_OldSerNo(old_ser_nr), + tr_CbspCellList(cell_list), + tr_CbspChannelInd(channel_ind) }); + +/* 8.1.3.5 KILL COMPLETE */ +function ts_CBSP_KILL_COMPL(template (value) uint16_t msg_id, template (value) uint16_t old_ser_nr, + template (omit) CBSP_IE_NumBcastComplList compl_list, + template (omit) BSSMAP_FIELD_CellIdentificationList cell_list, + template (omit) uint8_t channel_ind) +return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_OldSerNo(old_ser_nr) + }; + if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := ts_CbspNumComplList(compl_list); + } + if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := ts_CbspCellList(cell_list); + } + if (not istemplatekind(channel_ind, "omit")) { + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + } + return ts_CBSP(CBSP_MSGT_KILL_COMPL, ies); +} +function tr_CBSP_KILL_COMPL(template uint16_t msg_id := ?, template uint16_t old_ser_nr := ?, + template CBSP_IE_NumBcastComplList compl_list := ?, + template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template uint8_t channel_ind) +return template CBSP_PDU { + var template CBSP_IEs ies := { + tr_CbspMsgId(msg_id), + tr_OldSerNo(old_ser_nr) + }; + if (istemplatekind(compl_list, "*")) { + ies[lengthof(ies)] := *; + } else if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := tr_CbspNumComplList(compl_list); + } + if (istemplatekind(cell_list, "*")) { + ies[lengthof(ies)] := *; + } else if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := tr_CbspCellList(cell_list); + } + if (istemplatekind(channel_ind, "*")) { + ies[lengthof(ies)] := *; + } else if (not istemplatekind(channel_ind, "omit")) { + ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind); + } + return tr_CBSP(CBSP_MSGT_KILL_COMPL, ies); +} + +/* 8.1.3.6 KILL FAILURE */ +function ts_CBSP_KILL_FAIL(template (value) uint16_t msg_id, template (value) uint16_t old_ser_nr, + template (value) CBSP_FailureListItems fail_list, + template (omit) CBSP_IE_NumBcastComplList compl_list, + template (omit) BSSMAP_FIELD_CellIdentificationList cell_list, + template (omit) uint8_t channel_ind) +return template (value) CBSP_PDU { + var template (value) CBSP_IEs ies := { + ts_CbspMsgId(msg_id), + ts_OldSerNo(old_ser_nr), + ts_CbspFailList(fail_list) + }; + if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := ts_CbspNumComplList(compl_list); + } + if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := ts_CbspCellList(cell_list); + } + if (not istemplatekind(channel_ind, "omit")) { + ies[lengthof(ies)] := ts_CbspChannelInd(channel_ind); + } + return ts_CBSP(CBSP_MSGT_KILL_FAIL, ies); +} +function tr_CBSP_KILL_FAIL(template uint16_t msg_id := ?, template uint16_t old_ser_nr := ?, + template CBSP_FailureListItems fail_list := ?, + template CBSP_IE_NumBcastComplList compl_list := *, + template BSSMAP_FIELD_CellIdentificationList cell_list := *, + template uint8_t channel_ind := *) +return template CBSP_PDU { + var template CBSP_IEs ies := { + tr_CbspMsgId(msg_id), + tr_OldSerNo(old_ser_nr), + tr_CbspFailList(fail_list) + }; + if (istemplatekind(compl_list, "*")) { + ies[lengthof(ies)] := tr_CbspNumComplList ifpresent; + } else if (not istemplatekind(compl_list, "omit")) { + ies[lengthof(ies)] := tr_CbspNumComplList(compl_list); + } + if (istemplatekind(compl_list, "*")) { + ies[lengthof(ies)] := tr_CbspCellList ifpresent; + } else if (not istemplatekind(cell_list, "omit")) { + ies[lengthof(ies)] := tr_CbspCellList(cell_list); + } + if (istemplatekind(channel_ind, "*")) { + ies[lengthof(ies)] := tr_CbspChannelInd(?) ifpresent; + } else if (not istemplatekind(channel_ind, "omit")) { + ies[lengthof(ies)] := tr_CbspChannelInd(channel_ind); + } + return tr_CBSP(CBSP_MSGT_KILL_FAIL, ies); +} + + +/* 8.1.3.16 RESET */ +template (value) CBSP_PDU ts_CBSP_RESET(template (value) BSSMAP_FIELD_CellIdentificationList cell_list) := + ts_CBSP(CBSP_MSGT_RESET, { + ts_CbspCellList(cell_list) + }); +template CBSP_PDU tr_CBSP_RESET(template BSSMAP_FIELD_CellIdentificationList cell_list := ?) := + tr_CBSP(CBSP_MSGT_RESET, { + tr_CbspCellList(cell_list) + }); + +/* 8.1.3.17 RESET COMPLETE */ +template (value) CBSP_PDU ts_CBSP_RESET_COMPL(template (value) BSSMAP_FIELD_CellIdentificationList cell_list) := + ts_CBSP(CBSP_MSGT_RESET_COMPL, { + ts_CbspCellList(cell_list) + }); +template CBSP_PDU tr_CBSP_RESET_COMPL(template BSSMAP_FIELD_CellIdentificationList cell_list := ?) := + tr_CBSP(CBSP_MSGT_RESET_COMPL, { + tr_CbspCellList(cell_list) + }); + +/* 8.1.3.18 RESET FAILURE */ +template (value) CBSP_PDU ts_CBSP_RESET_FAIL(template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) CBSP_FailureListItems fail_items) := + ts_CBSP(CBSP_MSGT_RESET_FAIL, { + ts_CbspFailList(fail_items), + ts_CbspCellList(cell_list) + }); + +template CBSP_PDU tr_CBSP_RESET_FAIL(template BSSMAP_FIELD_CellIdentificationList cell_list, + template CBSP_FailureListItems fail_items) := + tr_CBSP(CBSP_MSGT_RESET_FAIL, { + tr_CbspFailList(fail_items), + tr_CbspCellList(cell_list) + }); + +/* 8.1.3.18a KEEP-ALIVE */ +template (value) CBSP_PDU ts_CBSP_KEEP_ALIVE(uint8_t rep_period) := + ts_CBSP(CBSP_MSGT_KEEP_ALIVE, {ts_CbspKARepPeriod(rep_period)}); +template CBSP_PDU tr_CBSP_KEEP_ALIVE(template uint8_t rep_period := ?) := + tr_CBSP(CBSP_MSGT_KEEP_ALIVE, {tr_CbspKARepPeriod(rep_period)}); + +/* 8.1.3.18b KEEP-ALIVE COMPLETE */ +template (value) CBSP_PDU ts_CBSP_KEEP_ALIVE_COMPL := + ts_CBSP(CBSP_MSGT_KEEP_ALIVE_COMPL, {}); +template CBSP_PDU tr_CBSP_KEEP_ALIVE_COMPL := + tr_CBSP(CBSP_MSGT_KEEP_ALIVE_COMPL, {}); + +/* 8.1.3.19 RESTART */ +template (value) CBSP_PDU ts_CBSP_RESTART(template (value) BSSMAP_FIELD_CellIdentificationList cell_list, + template (value) CBSP_BcastMsgType msg_type, + template (value) CBSP_RecoveryInd rec_ind) := + ts_CBSP(CBSP_MSGT_RESTART, { + ts_CbspCellList(cell_list), + ts_CbspBcastMsgType(msg_type), + ts_CbspRecoveryInd(rec_ind) + }); +template CBSP_PDU tr_CBSP_RESTART(template BSSMAP_FIELD_CellIdentificationList cell_list := ?, + template CBSP_BcastMsgType msg_type := ?, + template CBSP_RecoveryInd rec_ind := ?) := + tr_CBSP(CBSP_MSGT_RESTART, { + tr_CbspCellList(cell_list), + tr_CbspBcastMsgType(msg_type), + tr_CbspRecoveryInd(rec_ind) + }); + +/* 8.1.3.20 FAILURE */ +template (value) CBSP_PDU ts_CBSP_FAILURE(template (value) CBSP_FailureListItems fail_list, + template (value) CBSP_BcastMsgType msg_type) := + ts_CBSP(CBSP_MSGT_FAILURE, { + ts_CbspFailList(fail_list), + ts_CbspBcastMsgType(msg_type) + }); +template CBSP_PDU tr_CBSP_FAILURE(template CBSP_FailureListItems fail_list := ?, + template CBSP_BcastMsgType msg_type := ?) := + tr_CBSP(CBSP_MSGT_FAILURE, { + tr_CbspFailList(fail_list), + tr_CbspBcastMsgType(msg_type) + }); + +/* 8.1.3.21 ERROR INDICATION */ +template (value) CBSP_PDU ts_CBSP_ERROR_IND(CBSP_Cause cause) := + ts_CBSP(CBSP_MSGT_ERROR_IND, {ts_CbspCause(cause)}); +template CBSP_PDU tr_CBSP_ERROR_IND(template CBSP_Cause cause) := + tr_CBSP(CBSP_MSGT_ERROR_IND, {tr_CbspCause(cause), *}); + + +function f_cbsp_find_ie(CBSP_PDU msg, CBSP_IEI iei, out CBSP_IE ret) return boolean { + for (var integer i := 0; i < sizeof(msg.ies); i := i+1) { + if (msg.ies[i].iei == iei) { + ret := msg.ies[i]; + return true; + } + } + return false; +} + + +} diff --git a/library/CBSP_Types.ttcn b/library/CBSP_Types.ttcn new file mode 100644 index 000000000..43a7d7db4 --- /dev/null +++ b/library/CBSP_Types.ttcn @@ -0,0 +1,381 @@ +module CBSP_Types { + +/* CBSP_Types, defining abstract TTCN-3 data types for the CBSP protocol. + * + * CBSP is a ETSI/3GPP standard protocol used between CBC (Cell Broadcast Centre) + * and BSC (Base Station Controller) in 2G/GSM/GERAN networks. It is specified + * in 3GPP TS 48.049. + * + * (C) 2019 by Harald Welte + * All rights reserved. + * + * Released under the terms of GNU General Public License, Version 2 or + * (at your option) any later version. + */ + +import from General_Types all; +import from Osmocom_Types all; +import from BSSAP_Types all; + + +/* 8.2.2 Message Type */ +type enumerated CBSP_MessageType { + CBSP_MSGT_WRITE_REPLACE ('01'O), + CBSP_MSGT_WRITE_REPLACE_COMPL ('02'O), + CBSP_MSGT_WRITE_REPLACE_FAIL ('03'O), + CBSP_MSGT_KILL ('04'O), + CBSP_MSGT_KILL_COMPL ('05'O), + CBSP_MSGT_KILL_FAIL ('06'O), + CBSP_MSGT_LOAD_QUERY ('07'O), + CBSP_MSGT_LOAD_QUERY_COMPL ('08'O), + CBSP_MSGT_LOAD_QUERY_FAIL ('09'O), + CBSP_MSGT_MSG_STATUS_QUERY ('0a'O), + CBSP_MSGT_MSG_STATUS_QUERY_COMPL ('0b'O), + CBSP_MSGT_MSG_STATUS_QUERY_FAIL ('0c'O), + CBSP_MSGT_SET_DRX ('0d'O), + CBSP_MSGT_SET_DRX_COMPL ('0e'O), + CBSP_MSGT_SET_DRX_FAIL ('0f'O), + CBSP_MSGT_RESET ('10'O), + CBSP_MSGT_RESET_COMPL ('11'O), + CBSP_MSGT_RESET_FAIL ('12'O), + CBSP_MSGT_RESTART ('13'O), + CBSP_MSGT_FAILURE ('14'O), + CBSP_MSGT_ERROR_IND ('15'O), + CBSP_MSGT_KEEP_ALIVE ('16'O), + CBSP_MSGT_KEEP_ALIVE_COMPL ('17'O) +} with { variant "FIELDLENGTH(8)" }; + +/* 8.2.1 Information Element Identifier */ +type enumerated CBSP_IEI { + CBSP_IEI_MSG_CONTENT ('01'O), + CBSP_IEI_OLD_SERIAL_NR ('02'O), + CBSP_IEI_NEW_SERIAL_NR ('03'O), + CBSP_IEI_CELL_LIST ('04'O), + CBSP_IEI_CATEGORY ('05'O), + CBSP_IEI_REP_PERIOD ('06'O), + CBSP_IEI_NUM_BCAST_REQ ('07'O), + CBSP_IEI_NUM_BCAST_COMPL_LIST ('08'O), + CBSP_IEI_FAILURE_LIST ('09'O), + CBSP_IEI_RR_LOADING_LIST ('0a'O), + CBSP_IEI_CAUSE ('0b'O), + CBSP_IEI_DCS ('0c'O), + CBSP_IEI_RECOVERY_IND ('0d'O), + CBSP_IEI_MSG_ID ('0e'O), + CBSP_IEI_EMERG_IND ('0f'O), + CBSP_IEI_WARN_TYPE ('10'O), + CBSP_IEI_WARN_SEC_INFO ('11'O), + CBSP_IEI_CHANNEL_IND ('12'O), + CBSP_IEI_NUM_OF_PAGES ('13'O), + CBSP_IEI_SCHEDULE_PERIOD ('14'O), + CBSP_IEI_NUM_OF_RES_SLOTS ('15'O), + CBSP_IEI_BCAST_MSG_TYPE ('16'O), + CBSP_IEI_WARNING_PERIOD ('17'O), + CBSP_IEI_KEEP_ALIVE_REP_PERIOD ('18'O) +} with { variant "FIELDLENGTH(8)" }; + +/* 8.2.7 Category */ +type enumerated CBSP_Category { + CBSP_CATEG_HIGH_PRIO ('00'O), + CBSP_CATEG_BACKGROUND ('01'O), + CBSP_CATEG_NORMAL ('02'O) +} with { variant "FIELDLENGTH(8)" }; + +/* Cell ID Discriminator (8.2.11, ...) */ +type enumerated CBSP_CellIdDisc { + CBSP_CIDD_WHOLE_CGI (0), + CBSP_CIDD_LAC_CI (1), + CBSP_CIDD_CI (2), + CBSP_CIDD_LAI (4), + CBSP_CIDD_LAC (5), + CBSP_CIDD_ALL_IN_BSC (6) +} with { variant "FIELDLENGTH(4)" }; + +/* 8.2.13 Cause */ +type enumerated CBSP_Cause { + CBSP_CAUSE_PARAM_NOT_RECOGNISED ('00'O), + CBSP_CAUSE_PARAM_VAL_INVALID ('01'O), + CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED ('02'O), + CBSP_CAUSE_CELL_ID_NOT_VALID ('03'O), + CBSP_CAUSE_UNRECOGNISED_MSG ('04'O), + CBSP_CAUSE_MISSING_MAND_IE ('05'O), + CBSP_CAUSE_BSC_CAPACITY_EXCEEDED ('06'O), + CBSP_CAUSE_CELL_MEMORY_EXCEEDED ('07'O), + CBSP_CAUSE_BSC_MEMORY_EXCEEDED ('08'O), + CBSP_CAUSE_CB_NOT_SUPPORTED ('09'O), + CBSP_CAUSE_CB_NOT_OPERATIONAL ('0a'O), + CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM ('0b'O), + CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED ('0c'O), + CBSP_CAUSE_MSG_REF_ALREADY_USED ('0d'O), + CBSP_CAUSE_UNSPECIFIED_ERROR ('0e'O), + CBSP_CAUSE_LAI_OR_LAC_NPT_VALID ('0f'O) +} with { variant "FIELDLENGTH(8)" }; + +type record CBSP_IE_MessageContent { + uint8_t user_len, + octetstring val +} with { variant (val) "FIELDLENGTH(82)" }; + +/* 8.2.6 Cell List */ +type record CBSP_IE_CellList { + uint16_t len, + BIT4 spare1_4, + BIT4 cell_id_discr, + BSSMAP_FIELD_CellIdentificationList cell_id +} with { + variant (len) "LENGTHTO(cell_id_discr,spare1_4,cell_id)" + variant (cell_id) "CROSSTAG( + cIl_CGI, cell_id_discr = '0000'B; + cIl_LAC_CI, cell_id_discr = '0001'B; + cIl_CI, cell_id_discr = '0010'B; + cIl_LAI, cell_id_discr = '0100'B; + cIl_LAC, cell_id_discr = '0101'B; + cIl_allInBSS, cell_id_discr = '0110'B; + )" +}; + +/* 8.2.10 Number of Broadcasts Completed List */ +type record CBSP_IE_NumBcastComplList { + uint16_t len, + BIT4 spare1_4, + BIT4 cell_id_discr, + CBSP_FIELD_NumBcastCompl list +} with { + variant (len) "LENGTHTO(cell_id_discr,spare1_4,list)" + variant (list) "CROSSTAG( + cI_CGI, cell_id_discr = '0000'B; + cI_LAC_CI, cell_id_discr = '0001'B; + cI_CI, cell_id_discr = '0010'B; + cI_LAI, cell_id_discr = '0100'B; + cI_LAC, cell_id_discr = '0101'B; + cI_allInBSS, cell_id_discr = '0110'B; + )" +}; +type union CBSP_FIELD_NumBcastCompl { + CBSP_FIELD_NumBcastCompl_CGI cI_CGI, + CBSP_FIELD_NumBcastCompl_LAC_CI cI_LAC_CI, + OCT0 cI_allInBSS, + CBSP_FIELD_NumBcastCompl_CI cI_CI, + CBSP_FIELD_NumBcastCompl_LAC cI_LAC, + CBSP_FIELD_NumBcastCompl_LAI cI_LAI +}; +type record CBSP_FIELD_NumBcastCompl_CGI { + BSSMAP_FIELD_CellIdentification_CGI ci, + uint16_t num_bcats_compl, + CBSP_NumBcastInfo num_bcast_info, + BIT4 spare1_4 +}; +type record CBSP_FIELD_NumBcastCompl_LAC_CI { + BSSMAP_FIELD_CellIdentification_LAC_CI ci, + uint16_t num_bcats_compl, + CBSP_NumBcastInfo num_bcast_info, + BIT4 spare1_4 +}; +type record CBSP_FIELD_NumBcastCompl_LAI { + BSSMAP_FIELD_CellIdentification_LAI ci, + uint16_t num_bcats_compl, + CBSP_NumBcastInfo num_bcast_info, + BIT4 spare1_4 +}; +type record CBSP_FIELD_NumBcastCompl_CI { + OCT2 ci, + uint16_t num_bcats_compl, + CBSP_NumBcastInfo num_bcast_info, + BIT4 spare1_4 +}; +type record CBSP_FIELD_NumBcastCompl_LAC { + OCT2 lac, + uint16_t num_bcats_compl, + CBSP_NumBcastInfo num_bcast_info, + BIT4 spare1_4 +}; +type enumerated CBSP_NumBcastInfo { + CBSP_NUM_BCAST_INFO_VALID (0), + CBSP_NUM_BCAST_INFO_OVERFLOW (1), + CBSP_NUM_BCAST_INFO_UNKNOWN (2) +} with { variant "FIELDLENGTH(4)" }; + + +/* 8.2.11 Failure List */ +type record CBSP_FailureListItem { + BIT4 spare1_4, + BIT4 cell_id_discr, + CBSP_FIELD_CellIdentification cell_id, + CBSP_Cause cause +} with { + variant (cell_id) "CROSSTAG( + cI_CGI, cell_id_discr = '0000'B; + cI_LAC_CI, cell_id_discr = '0001'B; + cI_CI, cell_id_discr = '0010'B; + cI_LAI, cell_id_discr = '0100'B; + cI_LAC, cell_id_discr = '0101'B; + cI_allInBSS, cell_id_discr = '0110'B; + )" +}; +type union CBSP_FIELD_CellIdentification +{ + BSSMAP_FIELD_CellIdentification_CGI cI_CGI, + BSSMAP_FIELD_CellIdentification_LAC_CI cI_LAC_CI, + OCT2 cI_CI, + BSSMAP_FIELD_CellIdentification_LAI cI_LAI, + OCT2 cI_LAC, + OCT2 cI_allInBSS +}; + +type record of CBSP_FailureListItem CBSP_FailureListItems; +type record CBSP_IE_FailureList { + uint16_t len, + CBSP_FailureListItems list +} with { + variant (len) "LENGTHTO(list)" +}; + +/* 8.2.12 RR Loading List */ +type record CBSP_IE_RrLoadingList { + uint16_t len, + BIT4 spare1_4, + BIT4 cell_id_discr, + CBSP_FIELD_RrLoadingList list +} with { + variant (len) "LENGTHTO(cell_id_discr,spare1_4,list)" + variant (list) "CROSSTAG( + cI_CGI, cell_id_discr = '0000'B; + cI_LAC_CI, cell_id_discr = '0001'B; + cI_CI, cell_id_discr = '0010'B; + cI_LAI, cell_id_discr = '0100'B; + cI_LAC, cell_id_discr = '0101'B; + cI_allInBSS, cell_id_discr = '0110'B; + )" +}; +type union CBSP_FIELD_RrLoadingList { + CBSP_FIELD_RrLoadingList_CGI cI_CGI, + CBSP_FIELD_RrLoadingList_LAC_CI cI_LAC_CI, + OCT0 cI_allInBSS, + CBSP_FIELD_RrLoadingList_CI cI_CI, + CBSP_FIELD_RrLoadingList_LAC cI_LAC, + CBSP_FIELD_RrLoadingList_LAI cI_LAI +}; +type record CBSP_FIELD_RrLoadingList_CGI { + BSSMAP_FIELD_CellIdentification_CGI ci, + uint8_t load1, + uint8_t load2 +}; +type record CBSP_FIELD_RrLoadingList_LAC_CI { + BSSMAP_FIELD_CellIdentification_LAC_CI ci, + uint8_t load1, + uint8_t load2 +}; +type record CBSP_FIELD_RrLoadingList_LAI { + BSSMAP_FIELD_CellIdentification_LAI ci, + uint8_t load1, + uint8_t load2 +}; +type record CBSP_FIELD_RrLoadingList_CI { + OCT2 ci, + uint8_t load1, + uint8_t load2 +}; +type record CBSP_FIELD_RrLoadingList_LAC { + OCT2 lac, + uint8_t load1, + uint8_t load2 +}; + +/* 8.2.15 Recovery Indication */ +type record CBSP_IE_RecoveryInd { + BIT4 spare1_4, + CBSP_RecoveryInd recovery +}; +type enumerated CBSP_RecoveryInd { + CBSP_RI_DATA_AVAILABLE (0), + CBSP_RI_DATA_LOST (1) +} with { variant "FIELDLENGTH(4)" }; + +/* 8.2.24 Broadcast Message Type */ +type record CBSP_IE_BcastMsgType { + BIT4 spare1_4, + CBSP_BcastMsgType msg_type +}; +type enumerated CBSP_BcastMsgType { + CBSP_BC_MSGT_CBS (0), + CBSP_BC_MSGT_EMERG (1) +} with { variant "FIELDLENGTH(4)" }; + + +type union CBSP_IE_Body { + CBSP_IE_MessageContent msg_content, + uint16_t old_ser_nr, + uint16_t new_ser_nr, + CBSP_IE_CellList cell_list, + CBSP_Category category, + uint16_t rep_period, + uint16_t num_bcast_req, + CBSP_IE_NumBcastComplList num_bcast_compl_list, + CBSP_IE_FailureList failure_list, + CBSP_IE_RrLoadingList rr_loading_list, + CBSP_Cause cause, + uint8_t dcs, + CBSP_IE_RecoveryInd recovery_ind, + uint16_t msg_id, + uint8_t emerg_ind, + uint16_t warn_type, + octetstring warn_sec_info, + uint8_t channel_ind, + uint8_t num_of_pages, + uint8_t schedule_period, + uint8_t num_of_res_slots, + CBSP_IE_BcastMsgType bcast_msg_type, + uint8_t warning_period, + uint8_t keep_alive_rep_period +} with { + variant (warn_sec_info) "FIELDLENGTH(50)" +}; + +type record CBSP_IE { + CBSP_IEI iei, + CBSP_IE_Body body +} with { + variant (body) "CROSSTAG( msg_content, iei = CBSP_IEI_MSG_CONTENT; + old_ser_nr, iei = CBSP_IEI_OLD_SERIAL_NR; + new_ser_nr, iei = CBSP_IEI_NEW_SERIAL_NR; + cell_list, iei = CBSP_IEI_CELL_LIST; + category, iei = CBSP_IEI_CATEGORY; + rep_period, iei = CBSP_IEI_REP_PERIOD; + num_bcast_req, iei = CBSP_IEI_NUM_BCAST_REQ; + num_bcast_compl_list, iei = CBSP_IEI_NUM_BCAST_COMPL_LIST; + failure_list, iei = CBSP_IEI_FAILURE_LIST; + rr_loading_list, iei = CBSP_IEI_RR_LOADING_LIST; + cause, iei = CBSP_IEI_CAUSE; + dcs, iei = CBSP_IEI_DCS; + recovery_ind, iei = CBSP_IEI_RECOVERY_IND; + msg_id, iei = CBSP_IEI_MSG_ID; + emerg_ind, iei = CBSP_IEI_EMERG_IND; + warn_type, iei = CBSP_IEI_WARN_TYPE; + warn_sec_info, iei = CBSP_IEI_WARN_SEC_INFO; + channel_ind, iei = CBSP_IEI_CHANNEL_IND; + num_of_pages, iei = CBSP_IEI_NUM_OF_PAGES; + schedule_period, iei = CBSP_IEI_SCHEDULE_PERIOD; + num_of_res_slots, iei = CBSP_IEI_NUM_OF_RES_SLOTS; + bcast_msg_type, iei = CBSP_IEI_BCAST_MSG_TYPE; + warning_period, iei = CBSP_IEI_WARNING_PERIOD; + keep_alive_rep_period, iei = CBSP_IEI_KEEP_ALIVE_REP_PERIOD + )" +}; + +type set of CBSP_IE CBSP_IEs; + +type record CBSP_PDU { + CBSP_MessageType msg_type, + uint24_t len, + CBSP_IEs ies +} with { + variant (len) "LENGTHTO(ies)" +}; + +external function enc_CBSP_PDU(in CBSP_PDU msg) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + +external function dec_CBSP_PDU(in octetstring msg) return CBSP_PDU + with { extension "prototype(convert) decode(RAW)" }; + + +} with { encode "RAW"; variant "FIELDORDER(msb)" }