libosmocore/include/osmocom/gsm/gsm0808.h

203 lines
7.6 KiB
C
Raw Normal View History

/*! \defgroup gsm0808 GSM 08.08 / 3GPP TS 48.008 A Interface
* @{
* \file gsm0808.h */
/*
* (C) 2009,2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009,2010 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#pragma once
#include "tlv.h"
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0808_utils.h>
implement support for 3-digit MNC with leading zeros Enable representing three-digit MNC with leading zeros. The MNCs 23 and 023 are actually different; so far we treated both as 23. Re-encode an incoming BCD or string of 023 as it were, i.e. not dropping the leading zero as 23. Break ABI compatibility by changing the size and ordering of structs gprs_ra_id, osmo_plmn_id, osmo_cell_global_id, ... by adding an mnc_3_digits flag. Change ordering in gprs_ra_id because the canonical oder is {Mobile Country Code, Mobile Network Code}, so have the mcc member first. ABI compatibility cannot be maintained for struct gprs_ra_id, since it is a direct member of structs bssgp_bvc_ctx and bssgp_paging_info, and even just adding a flag to the end would cause ABI changes of those structs. Similarly, osmo_plmn_id is a direct member of osmo_location_area_id, and so forth. Add new API to set and read this additional flag to preserve leading zeros: - osmo_plmn_to_bcd(), osmo_plmn_from_bcd() after gsm48_mcc_mnc_to_bcd() and gsm48_mcc_mnc_from_bcd(). - gsm48_decode_lai2(), gsm48_generate_lai2() after gsm48_decode_lai(), gsm48_generate_lai(). - gsm0808_create_layer3_2() after gsm0808_create_layer3() and gsm0808_create_layer3_aoip(). - various osmo_*_name() functions in gsm23003.h (osmo_rai_name() still in gsm48.h close to struct gprs_ra_id definition). The amount and duplication of these may seem a bit overboard, but IMO they do make sense in this way. Though most code will soon see patches unifying the data structures used, in some cases (vty, ctrl) they are required singled out. Without these functions, the formatting ("%0*u", mnc_3_digits ? 3 : 2, mnc) would be duplicated all over our diverse repositories. In various log output, include the leading MNC zeros. Mark one TODO in card_fs_sim.c, I am not sure how to communicate a leading zero to/from a SIM card FS. The focus here is on the core network / BSS. To indicate ABI incompatibility, bump libosmogsm and libosmogb LIBVERSIONs; adjust debian files accordingly. Implementation choices: - The default behavior upon zero-initialization will be the mnc_3_digits flag set to false, which yields exactly the previous behavior. - I decided against packing the mnc with the mnc_3_digits field into a sub-struct because it would immediately break all builds of dependent projects: it would require immediate merging of numerous patches in other repositories, and it would make compiling older code against a newer libosmocore unneccessarily hard. Change-Id: Id2240f7f518494c9df6c8bda52c0d5092f90f221
2018-02-20 12:47:08 +00:00
#include <osmocom/gsm/gsm23003.h>
#include <osmocom/core/utils.h>
implement support for 3-digit MNC with leading zeros Enable representing three-digit MNC with leading zeros. The MNCs 23 and 023 are actually different; so far we treated both as 23. Re-encode an incoming BCD or string of 023 as it were, i.e. not dropping the leading zero as 23. Break ABI compatibility by changing the size and ordering of structs gprs_ra_id, osmo_plmn_id, osmo_cell_global_id, ... by adding an mnc_3_digits flag. Change ordering in gprs_ra_id because the canonical oder is {Mobile Country Code, Mobile Network Code}, so have the mcc member first. ABI compatibility cannot be maintained for struct gprs_ra_id, since it is a direct member of structs bssgp_bvc_ctx and bssgp_paging_info, and even just adding a flag to the end would cause ABI changes of those structs. Similarly, osmo_plmn_id is a direct member of osmo_location_area_id, and so forth. Add new API to set and read this additional flag to preserve leading zeros: - osmo_plmn_to_bcd(), osmo_plmn_from_bcd() after gsm48_mcc_mnc_to_bcd() and gsm48_mcc_mnc_from_bcd(). - gsm48_decode_lai2(), gsm48_generate_lai2() after gsm48_decode_lai(), gsm48_generate_lai(). - gsm0808_create_layer3_2() after gsm0808_create_layer3() and gsm0808_create_layer3_aoip(). - various osmo_*_name() functions in gsm23003.h (osmo_rai_name() still in gsm48.h close to struct gprs_ra_id definition). The amount and duplication of these may seem a bit overboard, but IMO they do make sense in this way. Though most code will soon see patches unifying the data structures used, in some cases (vty, ctrl) they are required singled out. Without these functions, the formatting ("%0*u", mnc_3_digits ? 3 : 2, mnc) would be duplicated all over our diverse repositories. In various log output, include the leading MNC zeros. Mark one TODO in card_fs_sim.c, I am not sure how to communicate a leading zero to/from a SIM card FS. The focus here is on the core network / BSS. To indicate ABI incompatibility, bump libosmogsm and libosmogb LIBVERSIONs; adjust debian files accordingly. Implementation choices: - The default behavior upon zero-initialization will be the mnc_3_digits flag set to false, which yields exactly the previous behavior. - I decided against packing the mnc with the mnc_3_digits field into a sub-struct because it would immediately break all builds of dependent projects: it would require immediate merging of numerous patches in other repositories, and it would make compiling older code against a newer libosmocore unneccessarily hard. Change-Id: Id2240f7f518494c9df6c8bda52c0d5092f90f221
2018-02-20 12:47:08 +00:00
#define BSSMAP_MSG_SIZE 512
#define BSSMAP_MSG_HEADROOM 128
struct sockaddr_storage;
struct msgb;
struct gsm0808_cell_id_list2;
struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc,
uint16_t cc, int lac, uint16_t _ci)
OSMO_DEPRECATED("Use gsm0808_create_layer3_2() instead, to not lose leading zeros in the MNC");
struct msgb *gsm0808_create_layer3_aoip(const struct msgb *msg_l3, uint16_t nc,
uint16_t cc, int lac, uint16_t _ci,
const struct gsm0808_speech_codec_list *scl)
OSMO_DEPRECATED("Use gsm0808_create_layer3_2() instead, to not lose leading zeros in the MNC");
implement support for 3-digit MNC with leading zeros Enable representing three-digit MNC with leading zeros. The MNCs 23 and 023 are actually different; so far we treated both as 23. Re-encode an incoming BCD or string of 023 as it were, i.e. not dropping the leading zero as 23. Break ABI compatibility by changing the size and ordering of structs gprs_ra_id, osmo_plmn_id, osmo_cell_global_id, ... by adding an mnc_3_digits flag. Change ordering in gprs_ra_id because the canonical oder is {Mobile Country Code, Mobile Network Code}, so have the mcc member first. ABI compatibility cannot be maintained for struct gprs_ra_id, since it is a direct member of structs bssgp_bvc_ctx and bssgp_paging_info, and even just adding a flag to the end would cause ABI changes of those structs. Similarly, osmo_plmn_id is a direct member of osmo_location_area_id, and so forth. Add new API to set and read this additional flag to preserve leading zeros: - osmo_plmn_to_bcd(), osmo_plmn_from_bcd() after gsm48_mcc_mnc_to_bcd() and gsm48_mcc_mnc_from_bcd(). - gsm48_decode_lai2(), gsm48_generate_lai2() after gsm48_decode_lai(), gsm48_generate_lai(). - gsm0808_create_layer3_2() after gsm0808_create_layer3() and gsm0808_create_layer3_aoip(). - various osmo_*_name() functions in gsm23003.h (osmo_rai_name() still in gsm48.h close to struct gprs_ra_id definition). The amount and duplication of these may seem a bit overboard, but IMO they do make sense in this way. Though most code will soon see patches unifying the data structures used, in some cases (vty, ctrl) they are required singled out. Without these functions, the formatting ("%0*u", mnc_3_digits ? 3 : 2, mnc) would be duplicated all over our diverse repositories. In various log output, include the leading MNC zeros. Mark one TODO in card_fs_sim.c, I am not sure how to communicate a leading zero to/from a SIM card FS. The focus here is on the core network / BSS. To indicate ABI incompatibility, bump libosmogsm and libosmogb LIBVERSIONs; adjust debian files accordingly. Implementation choices: - The default behavior upon zero-initialization will be the mnc_3_digits flag set to false, which yields exactly the previous behavior. - I decided against packing the mnc with the mnc_3_digits field into a sub-struct because it would immediately break all builds of dependent projects: it would require immediate merging of numerous patches in other repositories, and it would make compiling older code against a newer libosmocore unneccessarily hard. Change-Id: Id2240f7f518494c9df6c8bda52c0d5092f90f221
2018-02-20 12:47:08 +00:00
struct msgb *gsm0808_create_layer3_2(const struct msgb *msg_l3, const struct osmo_cell_global_id *cell,
const struct gsm0808_speech_codec_list *scl);
struct msgb *gsm0808_create_reset(void);
2013-06-19 13:14:37 +00:00
struct msgb *gsm0808_create_reset_ack(void);
struct msgb *gsm0808_create_clear_command(uint8_t cause);
struct msgb *gsm0808_create_clear_complete(void);
struct msgb *gsm0808_create_cipher(const struct gsm0808_encrypt_info *ei,
const uint8_t *cipher_response_mode);
struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id);
struct msgb *gsm0808_create_cipher_reject(enum gsm0808_cause cause);
struct msgb *gsm0808_create_cipher_reject_ext(enum gsm0808_cause_class class, uint8_t ext);
struct msgb *gsm0808_create_classmark_request();
struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len);
struct msgb *gsm0808_create_sapi_reject(uint8_t link_id);
struct msgb *gsm0808_create_ass(const struct gsm0808_channel_type *ct,
const uint16_t *cic,
const struct sockaddr_storage *ss,
const struct gsm0808_speech_codec_list *scl,
const uint32_t *ci);
struct msgb *gsm0808_create_ass_compl(uint8_t rr_cause, uint8_t chosen_channel,
uint8_t encr_alg_id, uint8_t speech_mode,
const struct sockaddr_storage *ss,
const struct gsm0808_speech_codec *sc,
const struct gsm0808_speech_codec_list
*scl);
struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
uint8_t chosen_channel,
uint8_t encr_alg_id,
uint8_t speech_mode);
struct msgb *gsm0808_create_ass_fail(uint8_t cause, const uint8_t *rr_cause,
const struct gsm0808_speech_codec_list
*scl);
struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause);
struct msgb *gsm0808_create_clear_rqst(uint8_t cause);
struct msgb *gsm0808_create_paging2(const char *imsi, const uint32_t *tmsi,
const struct gsm0808_cell_id_list2 *cil,
const uint8_t *chan_needed);
struct msgb *gsm0808_create_paging(const char *imsi, const uint32_t *tmsi,
const struct gsm0808_cell_id_list *cil,
const uint8_t *chan_needed)
OSMO_DEPRECATED("use gsm0808_create_paging2 instead");
struct msgb *gsm0808_create_lcls_conn_ctrl(enum gsm0808_lcls_config *config,
enum gsm0808_lcls_control *control);
struct msgb *gsm0808_create_lcls_conn_ctrl_ack(enum gsm0808_lcls_status status);
struct msgb *gsm0808_create_lcls_notification(enum gsm0808_lcls_status status, bool break_req);
/*! 3GPP TS 48.008 §3.2.2.5.8 Old BSS to New BSS information */
struct gsm0808_old_bss_to_new_bss_info {
bool extra_information_present;
struct {
bool prec;
bool lcs;
bool ue_prob;
} extra_information;
bool current_channel_type_2_present;
struct {
uint8_t mode;
uint8_t field;
} current_channel_type_2;
/* more items are defined in the spec and may be added later */
bool more_items; /*< always set this to false */
};
/*! 3GPP TS 48.008 §3.2.1.9 HANDOVER REQUIRED */
struct gsm0808_handover_required {
uint16_t cause;
struct gsm0808_cell_id_list2 cil;
bool current_channel_type_1_present;
uint8_t current_channel_type_1;
bool speech_version_used_present;
uint8_t speech_version_used;
bool old_bss_to_new_bss_info_present;
struct gsm0808_old_bss_to_new_bss_info old_bss_to_new_bss_info;
/* more items are defined in the spec and may be added later */
bool more_items; /*< always set this to false */
};
struct msgb *gsm0808_create_handover_required(const struct gsm0808_handover_required *params);
struct msgb *gsm0808_create_handover_request_ack(const uint8_t *l3_info, uint8_t l3_info_len,
uint8_t chosen_channel, uint8_t chosen_encr_alg,
uint8_t chosen_speech_version);
struct msgb *gsm0808_create_handover_detect();
struct gsm0808_handover_complete {
bool rr_cause_present;
uint8_t rr_cause;
bool speech_codec_chosen_present;
struct gsm0808_speech_codec speech_codec_chosen;
struct gsm0808_speech_codec_list codec_list_bss_supported; /*< omit when .len == 0 */
bool chosen_encr_alg_present;
uint8_t chosen_encr_alg;
bool chosen_channel_present;
uint8_t chosen_channel;
bool lcls_bss_status_present;
enum gsm0808_lcls_status lcls_bss_status;
/* more items are defined in the spec and may be added later */
bool more_items; /*< always set this to false */
};
struct msgb *gsm0808_create_handover_complete(const struct gsm0808_handover_complete *params);
struct gsm0808_handover_failure {
uint16_t cause;
bool rr_cause_present;
uint8_t rr_cause;
struct gsm0808_speech_codec_list codec_list_bss_supported; /*< omit when .len == 0 */
/* more items are defined in the spec and may be added later */
bool more_items; /*< always set this to false */
};
struct msgb *gsm0808_create_handover_failure(const struct gsm0808_handover_failure *params);
struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id);
void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id);
const struct tlv_definition *gsm0808_att_tlvdef(void);
/*! Parse BSSAP TLV structure using \ref tlv_parse */
#define osmo_bssap_tlv_parse(dec, buf, len) tlv_parse(dec, gsm0808_att_tlvdef(), buf, len, 0, 0)
const char *gsm0808_bssmap_name(uint8_t msg_type);
const char *gsm0808_bssap_name(uint8_t msg_type);
const char *gsm0808_cause_name(enum gsm0808_cause cause);
const char *gsm0808_cause_class_name(enum gsm0808_cause_class class);
extern const struct value_string gsm0808_lcls_config_names[];
extern const struct value_string gsm0808_lcls_control_names[];
extern const struct value_string gsm0808_lcls_status_names[];
static inline const char *gsm0808_lcls_config_name(uint8_t val) {
return get_value_string(gsm0808_lcls_config_names, val);
}
static inline const char *gsm0808_lcls_control_name(uint8_t val) {
return get_value_string(gsm0808_lcls_control_names, val);
}
static inline const char *gsm0808_lcls_status_name(uint8_t val) {
return get_value_string(gsm0808_lcls_status_names, val);
}
/*! @} */