diff options
| -rw-r--r-- | include/osmocom/core/msgb.h | 1 | ||||
| -rw-r--r-- | include/osmocom/core/utils.h | 3 | ||||
| -rw-r--r-- | include/osmocom/gprs/gprs_ns.h | 2 | ||||
| -rw-r--r-- | include/osmocom/gsm/abis_nm.h | 1 | ||||
| -rw-r--r-- | include/osmocom/gsm/apn.h | 3 | ||||
| -rw-r--r-- | include/osmocom/gsm/gsm0808_utils.h | 3 | ||||
| -rw-r--r-- | include/osmocom/gsm/gsm23003.h | 6 | ||||
| -rw-r--r-- | include/osmocom/gsm/gsm48.h | 2 | ||||
| -rw-r--r-- | include/osmocom/gsm/gsm_utils.h | 1 | ||||
| -rw-r--r-- | include/osmocom/gsm/protocol/gsm_04_08.h | 2 | ||||
| -rw-r--r-- | include/osmocom/gsm/rsl.h | 1 | ||||
| -rw-r--r-- | include/osmocom/sim/sim.h | 1 | ||||
| -rw-r--r-- | src/gb/gprs_ns.c | 16 | ||||
| -rw-r--r-- | src/gb/libosmogb.map | 1 | ||||
| -rw-r--r-- | src/gsm/abis_nm.c | 13 | ||||
| -rw-r--r-- | src/gsm/apn.c | 27 | ||||
| -rw-r--r-- | src/gsm/gsm0808_utils.c | 40 | ||||
| -rw-r--r-- | src/gsm/gsm23003.c | 101 | ||||
| -rw-r--r-- | src/gsm/gsm48.c | 92 | ||||
| -rw-r--r-- | src/gsm/gsm_utils.c | 13 | ||||
| -rw-r--r-- | src/gsm/libosmogsm.map | 18 | ||||
| -rw-r--r-- | src/gsm/rsl.c | 40 | ||||
| -rw-r--r-- | src/msgb.c | 38 | ||||
| -rw-r--r-- | src/sim/core.c | 24 | ||||
| -rw-r--r-- | src/utils.c | 31 | 
25 files changed, 362 insertions, 118 deletions
| diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h index 5029225e..0c51ce26 100644 --- a/include/osmocom/core/msgb.h +++ b/include/osmocom/core/msgb.h @@ -67,6 +67,7 @@ extern struct msgb *msgb_dequeue(struct llist_head *queue);  extern void msgb_reset(struct msgb *m);  uint16_t msgb_length(const struct msgb *msg);  extern const char *msgb_hexdump(const struct msgb *msg); +char *msgb_hexdump_buf(char *buf, size_t buf_len, const struct msgb *msg);  extern int msgb_resize_area(struct msgb *msg, uint8_t *area,  	int old_size, int new_size);  extern struct msgb *msgb_copy(const struct msgb *msg, const char *name); diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index e3728cd0..6a2b7d5b 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -53,6 +53,7 @@ int osmo_bcd2str(char *dst, size_t dst_size, const uint8_t *bcd, int start_nibbl  int osmo_hexparse(const char *str, uint8_t *b, int max_len); +char *osmo_ubit_dump_buf(char *buf, size_t buf_len, const uint8_t *bits, unsigned int len);  char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);  char *osmo_hexdump(const unsigned char *buf, int len);  char *osmo_hexdump_nospc(const unsigned char *buf, int len); @@ -139,7 +140,7 @@ bool osmo_separated_identifiers_valid(const char *str, const char *sep_chars);  const char *osmo_escape_str(const char *str, int len);  char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t bufsize);  const char *osmo_quote_str(const char *str, int in_len); -const char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize); +char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize);  uint32_t osmo_isqrt32(uint32_t x); diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h index c62ef98a..ed155ffe 100644 --- a/include/osmocom/gprs/gprs_ns.h +++ b/include/osmocom/gprs/gprs_ns.h @@ -211,6 +211,8 @@ int gprs_ns_vty_init(struct gprs_ns_inst *nsi);  /* Resturn peer info as string (NOTE: the buffer is allocated statically) */  const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc); +/* Return peer info in user-supplied buffer */ +char *gprs_ns_ll_str_buf(char *buf, size_t buf_len, const struct gprs_nsvc *nsvc);  /* Copy the link layer info from other into nsvc */  void gprs_ns_ll_copy(struct gprs_nsvc *nsvc, struct gprs_nsvc *other); diff --git a/include/osmocom/gsm/abis_nm.h b/include/osmocom/gsm/abis_nm.h index 823b5a45..788727cd 100644 --- a/include/osmocom/gsm/abis_nm.h +++ b/include/osmocom/gsm/abis_nm.h @@ -42,6 +42,7 @@ extern const struct tlv_definition abis_nm_osmo_att_tlvdef;  extern const struct tlv_definition abis_nm_att_tlvdef_ipa;  const char *abis_nm_dump_foh(const struct abis_om_fom_hdr *foh); +char *abis_nm_dump_foh_buf(char *buf, size_t buf_len, const struct abis_om_fom_hdr *foh);  /*! write a human-readable OML header to the debug log   *  \param[in] ss Logging sub-system diff --git a/include/osmocom/gsm/apn.h b/include/osmocom/gsm/apn.h index 288b229e..7899bb28 100644 --- a/include/osmocom/gsm/apn.h +++ b/include/osmocom/gsm/apn.h @@ -11,11 +11,14 @@  #define APN_MAXLEN	100  char *osmo_apn_qualify(unsigned int mcc, unsigned int mnc, const char *ni); +char *osmo_apn_qualify_buf(char *buf, size_t buf_len, unsigned int mcc, unsigned int mnc, const char *ni);  /* Compose a string of the form '<ni>.mnc001.mcc002.gprs\0', returned in a   * static buffer. */  char *osmo_apn_qualify_from_imsi(const char *imsi,  				 const char *ni, int have_3dig_mnc); +char *osmo_apn_qualify_from_imsi_buf(char *buf, size_t buf_len, const char *imsi, +				     const char *ni, int have_3dig_mnc);  int osmo_apn_from_str(uint8_t *apn_enc, size_t max_apn_enc_len, const char *str);  char *osmo_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t apn_enc_len); diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h index dedb0298..e2469670 100644 --- a/include/osmocom/gsm/gsm0808_utils.h +++ b/include/osmocom/gsm/gsm0808_utils.h @@ -69,7 +69,9 @@ struct osmo_lcls {  };  char *osmo_lcls_dump(const struct osmo_lcls *lcls); +char *osmo_lcls_dump_buf(char *buf, size_t buf_len, const struct osmo_lcls *lcls);  char *osmo_gcr_dump(const struct osmo_lcls *lcls); +char *osmo_gcr_dump_buf(char *buf, size_t buf_len, const struct osmo_lcls *lcls);  extern const struct value_string gsm0808_cell_id_discr_names[];  static inline const char *gsm0808_cell_id_discr_name(enum CELL_IDENT id_discr) @@ -251,5 +253,6 @@ static inline uint8_t gsm0808_chosen_channel(enum gsm_chan_t type, enum gsm48_ch  }  const char *gsm0808_channel_type_name(const struct gsm0808_channel_type *ct); +char *gsm0808_channel_type_name_buf(char *buf, size_t buf_len, const struct gsm0808_channel_type *ct);  /*! @} */ diff --git a/include/osmocom/gsm/gsm23003.h b/include/osmocom/gsm/gsm23003.h index cf622ce0..88c4f3c2 100644 --- a/include/osmocom/gsm/gsm23003.h +++ b/include/osmocom/gsm/gsm23003.h @@ -105,13 +105,19 @@ bool osmo_msisdn_str_valid(const char *msisdn);  bool osmo_imei_str_valid(const char *imei, bool with_15th_digit);  const char *osmo_mcc_name(uint16_t mcc); +char *osmo_mcc_name_buf(char *buf, size_t buf_len, uint16_t mcc);  const char *osmo_mnc_name(uint16_t mnc, bool mnc_3_digits); +char *osmo_mnc_name_buf(char *buf, size_t buf_len, uint16_t mnc, bool mnc_3_digits);  const char *osmo_plmn_name(const struct osmo_plmn_id *plmn);  const char *osmo_plmn_name2(const struct osmo_plmn_id *plmn); +char *osmo_plmn_name_buf(char *buf, size_t buf_len, const struct osmo_plmn_id *plmn);  const char *osmo_lai_name(const struct osmo_location_area_id *lai); +char *osmo_lai_name_buf(char *buf, size_t buf_len, const struct osmo_location_area_id *lai);  const char *osmo_cgi_name(const struct osmo_cell_global_id *cgi);  const char *osmo_cgi_name2(const struct osmo_cell_global_id *cgi); +char *osmo_cgi_name_buf(char *buf, size_t buf_len, const struct osmo_cell_global_id *cgi);  const char *osmo_gummei_name(const struct osmo_gummei *gummei); +char *osmo_gummei_name_buf(char *buf, size_t buf_len, const struct osmo_gummei *gummei);  void osmo_plmn_to_bcd(uint8_t *bcd_dst, const struct osmo_plmn_id *plmn);  void osmo_plmn_from_bcd(const uint8_t *bcd_src, struct osmo_plmn_id *plmn); diff --git a/include/osmocom/gsm/gsm48.h b/include/osmocom/gsm/gsm48.h index 7e0e5c48..81b2bf0d 100644 --- a/include/osmocom/gsm/gsm48.h +++ b/include/osmocom/gsm/gsm48.h @@ -35,6 +35,7 @@ const char *gsm48_cc_msg_name(uint8_t msgtype);  const char *gsm48_rr_msg_name(uint8_t msgtype);  const char *rr_cause_name(uint8_t cause);  const char *osmo_rai_name(const struct gprs_ra_id *rai); +char *osmo_rai_name_buf(char *buf, size_t buf_len, const struct gprs_ra_id *rai);  int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,  		     uint16_t *mnc, uint16_t *lac) @@ -55,6 +56,7 @@ int gsm48_mi_to_string(char *string, const int str_len,  			const uint8_t *mi, const int mi_len);  const char *gsm48_mi_type_name(uint8_t mi);  const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len); +char *osmo_mi_name_buf(char *buf, size_t buf_len, const uint8_t *mi, uint8_t mi_len);  /* Parse Routeing Area Identifier */  void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf); diff --git a/include/osmocom/gsm/gsm_utils.h b/include/osmocom/gsm/gsm_utils.h index f8f72a7f..f48cc68f 100644 --- a/include/osmocom/gsm/gsm_utils.h +++ b/include/osmocom/gsm/gsm_utils.h @@ -180,6 +180,7 @@ uint32_t gsm_gsmtime2fn(struct gsm_time *time);  /* Returns static buffer with string representation of a GSM Time */  char *osmo_dump_gsmtime(const struct gsm_time *tm); +char *osmo_dump_gsmtime_buf(char *buf, size_t buf_len, const struct gsm_time *tm);  /* GSM TS 03.03 Chapter 2.6 */  enum gprs_tlli_type { diff --git a/include/osmocom/gsm/protocol/gsm_04_08.h b/include/osmocom/gsm/protocol/gsm_04_08.h index c052e4c8..c97df168 100644 --- a/include/osmocom/gsm/protocol/gsm_04_08.h +++ b/include/osmocom/gsm/protocol/gsm_04_08.h @@ -70,6 +70,7 @@ bool osmo_gsm48_classmark1_is_r99(const struct gsm48_classmark1 *cm1);  bool osmo_gsm48_classmark2_is_r99(const struct gsm48_classmark2 *cm2, uint8_t cm2_len);  int osmo_gsm48_classmark_supports_a5(const struct osmo_gsm48_classmark *cm, uint8_t a5);  const char *osmo_gsm48_classmark_a5_name(const struct osmo_gsm48_classmark *cm); +char *osmo_gsm48_classmark_a5_name_buf(char *buf, size_t buf_len, const struct osmo_gsm48_classmark *cm);  void osmo_gsm48_classmark_update(struct osmo_gsm48_classmark *dst, const struct osmo_gsm48_classmark *src);  /* Chapter 10.5.2.1b.3 */ @@ -1643,6 +1644,7 @@ extern const struct value_string gsm48_rr_msgtype_names[];  extern const struct value_string gsm48_mm_msgtype_names[];  extern const struct value_string gsm48_cc_msgtype_names[];  const char *gsm48_pdisc_msgtype_name(uint8_t pdisc, uint8_t msg_type); +char *gsm48_pdisc_msgtype_name_buf(char *buf, size_t buf_len, uint8_t pdisc, uint8_t msg_type);  /* FIXME: Table 10.4 / 10.4a (GPRS) */ diff --git a/include/osmocom/gsm/rsl.h b/include/osmocom/gsm/rsl.h index be0fa797..4a1da3a6 100644 --- a/include/osmocom/gsm/rsl.h +++ b/include/osmocom/gsm/rsl.h @@ -30,6 +30,7 @@ uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot);  /* decode channel number as per Section 9.3.1 */  int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot);  /* Turns channel number into a string */ +char *rsl_chan_nr_str_buf(char *buf, size_t buf_len, uint8_t chan_nr);  const char *rsl_chan_nr_str(uint8_t chan_nr); diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h index 680cad15..0490dcd4 100644 --- a/include/osmocom/sim/sim.h +++ b/include/osmocom/sim/sim.h @@ -296,6 +296,7 @@ enum osim_card_sw_class osim_sw_class(const struct osim_card_profile *cp,  					uint16_t sw_in);  struct osim_card_hdl; +char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_card_hdl *ch, uint16_t sw_in);  char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in);  extern const struct tlv_definition ts102221_fcp_tlv_def; diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index c7ff78ed..fc120cec 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -1525,17 +1525,15 @@ int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,  	return rc;  } -const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc) +char *gprs_ns_ll_str_buf(char *buf, size_t buf_len, const struct gprs_nsvc *nsvc)  { -	static char buf[80]; -  	switch(nsvc->ll) {  	case GPRS_NS_LL_UDP: -		snprintf(buf, sizeof(buf), "%s:%u", +		snprintf(buf, buf_len, "%s:%u",  			 inet_ntoa(nsvc->ip.bts_addr.sin_addr), osmo_ntohs(nsvc->ip.bts_addr.sin_port));  		break;  	case GPRS_NS_LL_FR_GRE: -		snprintf(buf, sizeof(buf), "%s:%u", +		snprintf(buf, buf_len, "%s:%u",  			 inet_ntoa(nsvc->frgre.bts_addr.sin_addr), osmo_ntohs(nsvc->frgre.bts_addr.sin_port));  		break;  	default: @@ -1543,11 +1541,17 @@ const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc)  		break;  	} -	buf[sizeof(buf) - 1] = '\0'; +	buf[buf_len - 1] = '\0';  	return buf;  } +const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc) +{ +	static char buf[80]; +	return gprs_ns_ll_str_buf(buf, sizeof(buf), nsvc); +} +  void gprs_ns_ll_copy(struct gprs_nsvc *nsvc, struct gprs_nsvc *other)  {  	nsvc->ll = other->ll; diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map index 2ad3ff71..21929da1 100644 --- a/src/gb/libosmogb.map +++ b/src/gb/libosmogb.map @@ -64,6 +64,7 @@ gprs_ns_tx_status;  gprs_ns_tx_unblock;  gprs_ns_vty_init;  gprs_ns_ll_str; +gprs_ns_ll_str_buf;  gprs_ns_ll_copy;  gprs_ns_ll_clear;  gprs_ns_msgb_alloc; diff --git a/src/gsm/abis_nm.c b/src/gsm/abis_nm.c index 49d05ba5..e25fdd03 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -928,14 +928,19 @@ enum gsm_phys_chan_config abis_nm_pchan4chcomb(uint8_t chcomb)  	return GSM_PCHAN_NONE;  } -const char *abis_nm_dump_foh(const struct abis_om_fom_hdr *foh) +char *abis_nm_dump_foh_buf(char *buf, size_t buf_len, const struct abis_om_fom_hdr *foh)  { -	static char foh_buf[128]; -	snprintf(foh_buf, sizeof(foh_buf), "OC=%s(%02x) INST=(%02x,%02x,%02x)", +	snprintf(buf, buf_len, "OC=%s(%02x) INST=(%02x,%02x,%02x)",  		get_value_string(abis_nm_obj_class_names, foh->obj_class),  		foh->obj_class, foh->obj_inst.bts_nr, foh->obj_inst.trx_nr,  		foh->obj_inst.ts_nr); -	return foh_buf; +	return buf; +} + +const char *abis_nm_dump_foh(const struct abis_om_fom_hdr *foh) +{ +	static char foh_buf[128]; +	return abis_nm_dump_foh_buf(foh_buf, sizeof(foh_buf), foh);  }  /* this is just for compatibility reasons, it is now a macro */ diff --git a/src/gsm/apn.c b/src/gsm/apn.c index 26746631..4ab370c5 100644 --- a/src/gsm/apn.c +++ b/src/gsm/apn.c @@ -32,17 +32,22 @@  static char apn_strbuf[APN_MAXLEN+1]; -char *osmo_apn_qualify(unsigned int mcc, unsigned int mnc, const char *ni) +char *osmo_apn_qualify_buf(char *buf, size_t buf_len, unsigned int mcc, unsigned int mnc, const char *ni)  { -	snprintf(apn_strbuf, sizeof(apn_strbuf)-1, APN_GPRS_FMT, -		ni, mnc, mcc); -	apn_strbuf[sizeof(apn_strbuf)-1] = '\0'; +	snprintf(buf, buf_len-1, APN_GPRS_FMT, ni, mnc, mcc); +	buf[buf_len-1] = '\0'; -	return apn_strbuf; +	return buf;  } -char *osmo_apn_qualify_from_imsi(const char *imsi, -				 const char *ni, int have_3dig_mnc) +char *osmo_apn_qualify(unsigned int mcc, unsigned int mnc, const char *ni) +{ +	return osmo_apn_qualify_buf(apn_strbuf, sizeof(apn_strbuf), mcc, mnc, ni); +} + + +char *osmo_apn_qualify_from_imsi_buf(char *buf, size_t buf_len, const char *imsi, +				     const char *ni, int have_3dig_mnc)  {  	char cbuf[3+1], nbuf[3+1]; @@ -56,7 +61,13 @@ char *osmo_apn_qualify_from_imsi(const char *imsi,  		strncpy(nbuf, imsi+3, 2);  		nbuf[2] = '\0';  	} -	return osmo_apn_qualify(atoi(cbuf), atoi(nbuf), ni); +	return osmo_apn_qualify_buf(buf, buf_len, atoi(cbuf), atoi(nbuf), ni); +} + +char *osmo_apn_qualify_from_imsi(const char *imsi, +				 const char *ni, int have_3dig_mnc) +{ +	return osmo_apn_qualify_from_imsi_buf(apn_strbuf, sizeof(apn_strbuf), imsi, ni, have_3dig_mnc);  }  /** diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index e0cdaaf6..52e46743 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -595,11 +595,13 @@ int gsm0808_dec_lcls(struct osmo_lcls *lcls, const struct tlv_parsed *tp)  static char dbuf[256];  /*! Dump LCLS parameters (GCR excluded) into string for printing. + *  \param[out] buf caller-allocated output string buffer + *  \param[in] buf_len size of buf in bytes   *  \param[in] lcls pointer to the struct to print.   *  \returns string representation of LCLS or NULL on error. */ -char *osmo_lcls_dump(const struct osmo_lcls *lcls) +char *osmo_lcls_dump_buf(char *buf, size_t buf_len, const struct osmo_lcls *lcls)  { -	struct osmo_strbuf s = { .buf = dbuf, .len = 256 }; +	struct osmo_strbuf s = { .buf = buf, .len = buf_len };  	if (!lcls)  		return NULL; @@ -612,12 +614,22 @@ char *osmo_lcls_dump(const struct osmo_lcls *lcls)  	return dbuf;  } +/*! Dump LCLS parameters (GCR excluded) into static string buffer for printing. + *  \param[in] lcls pointer to the struct to print. + *  \returns string representation of LCLS in static buffer or NULL on error. */ +char *osmo_lcls_dump(const struct osmo_lcls *lcls) +{ +	return osmo_lcls_dump_buf(dbuf, sizeof(dbuf), lcls); +} +  /*! Dump GCR struct into string for printing. + *  \param[out] buf caller-allocated output string buffer + *  \param[in] buf_len size of buf in bytes   *  \param[in] lcls pointer to the struct to print.   *  \returns string representation of GCR or NULL on error. */ -char *osmo_gcr_dump(const struct osmo_lcls *lcls) +char *osmo_gcr_dump_buf(char *buf, size_t buf_len, const struct osmo_lcls *lcls)  { -	struct osmo_strbuf s = { .buf = dbuf, .len = 256 }; +	struct osmo_strbuf s = { .buf = buf, .len = buf_len };  	if (!lcls)  		return NULL; @@ -631,6 +643,15 @@ char *osmo_gcr_dump(const struct osmo_lcls *lcls)  	return dbuf;  } +/*! Dump GCR struct into static string buffer for printing. + *  \param[in] lcls pointer to the struct to print. + *  \returns string representation of GCR in static buffer or NULL on error. */ +char *osmo_gcr_dump(const struct osmo_lcls *lcls) +{ +	return osmo_gcr_dump_buf(dbuf, sizeof(dbuf), lcls); +} + +  /*! Encode TS 08.08 Encryption Information IE   *  \param[out] msg Message Buffer to which IE is to be appended   *  \param[in] ei Encryption Information to be encoded @@ -1838,13 +1859,18 @@ const char *gsm0808_cell_id_list_name(const struct gsm0808_cell_id_list2 *cil)  #undef APPEND_STR  #undef APPEND_CELL_ID_U -const char *gsm0808_channel_type_name(const struct gsm0808_channel_type *ct) +char *gsm0808_channel_type_name_buf(char *buf, size_t buf_len, const struct gsm0808_channel_type *ct)  { -	static char buf[128]; -	snprintf(buf, sizeof(buf), "ch_indctr=0x%x ch_rate_type=0x%x perm_spch=%s", +	snprintf(buf, buf_len, "ch_indctr=0x%x ch_rate_type=0x%x perm_spch=%s",  		 ct->ch_indctr, ct->ch_rate_type,  		 osmo_hexdump(ct->perm_spch, ct->perm_spch_len));  	return buf;  } +const char *gsm0808_channel_type_name(const struct gsm0808_channel_type *ct) +{ +	static char buf[128]; +	return gsm0808_channel_type_name_buf(buf, sizeof(buf), ct); +} +  /*! @} */ diff --git a/src/gsm/gsm23003.c b/src/gsm/gsm23003.c index 720c09b6..bbfe236a 100644 --- a/src/gsm/gsm23003.c +++ b/src/gsm/gsm23003.c @@ -90,13 +90,37 @@ bool osmo_imei_str_valid(const char *imei, bool with_15th_digit)  }  /*! Return MCC string as standardized 3-digit with leading zeros. + * \param[out] buf caller-allocated output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] mcc  MCC value. + * \returns string in user-supplied output buffer + */ +char *osmo_mcc_name_buf(char *buf, size_t buf_len, uint16_t mcc) +{ +	snprintf(buf, buf_len, "%03u", mcc); +	return buf; +} + +/*! Return MCC string as standardized 3-digit with leading zeros.   * \param[in] mcc  MCC value.   * \returns string in static buffer.   */  const char *osmo_mcc_name(uint16_t mcc)  {  	static char buf[8]; -	snprintf(buf, sizeof(buf), "%03u", mcc); +	return osmo_mcc_name_buf(buf, sizeof(buf), mcc); +} + +/*! Return MNC string as standardized 2- or 3-digit with leading zeros. + * \param[out] buf caller-allocated output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] mnc  MNC value. + * \param[in] mnc_3_digits  True if an MNC should fill three digits, only has an effect if MNC < 100. + * \returns string in static buffer. + */ +char *osmo_mnc_name_buf(char *buf, size_t buf_len, uint16_t mnc, bool mnc_3_digits) +{ +	snprintf(buf, buf_len, "%0*u", mnc_3_digits ? 3 : 2, mnc);  	return buf;  } @@ -108,14 +132,21 @@ const char *osmo_mcc_name(uint16_t mcc)  const char *osmo_mnc_name(uint16_t mnc, bool mnc_3_digits)  {  	static char buf[8]; -	snprintf(buf, sizeof(buf), "%0*u", mnc_3_digits ? 3 : 2, mnc); -	return buf; +	return osmo_mnc_name_buf(buf, sizeof(buf), mnc, mnc_3_digits);  } -static inline void plmn_name(char *buf, size_t buflen, const struct osmo_plmn_id *plmn) +/*! Return MCC-MNC string as standardized 3-digit-dash-2/3-digit with leading zeros. + * \param[out] buf caller-allocated output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] plmn  MCC-MNC value. + * \returns string in static buffer. + */ +char *osmo_plmn_name_buf(char *buf, size_t buf_len, const struct osmo_plmn_id *plmn)  { -	snprintf(buf, buflen, "%s-%s", osmo_mcc_name(plmn->mcc), -		 osmo_mnc_name(plmn->mnc, plmn->mnc_3_digits)); +	char mcc[8], mnc[8]; +	snprintf(buf, buf_len, "%s-%s", osmo_mcc_name_buf(mcc, sizeof(mcc), plmn->mcc), +		 osmo_mnc_name_buf(mnc, sizeof(mnc), plmn->mnc, plmn->mnc_3_digits)); +	return buf;  }  /*! Return MCC-MNC string as standardized 3-digit-dash-2/3-digit with leading zeros. @@ -125,10 +156,10 @@ static inline void plmn_name(char *buf, size_t buflen, const struct osmo_plmn_id  const char *osmo_plmn_name(const struct osmo_plmn_id *plmn)  {  	static char buf[16]; -	plmn_name(buf, sizeof(buf), plmn); -	return buf; +	return osmo_plmn_name_buf(buf, sizeof(buf), plmn);  } +  /*! Same as osmo_plmn_name(), but returning in a different static buffer.   * \param[in] plmn  MCC-MNC value.   * \returns string in static buffer. @@ -136,7 +167,19 @@ const char *osmo_plmn_name(const struct osmo_plmn_id *plmn)  const char *osmo_plmn_name2(const struct osmo_plmn_id *plmn)  {  	static char buf[16]; -	plmn_name(buf, sizeof(buf), plmn); +	return osmo_plmn_name_buf(buf, sizeof(buf), plmn); +} + +/*! Return MCC-MNC-LAC as string, in caller-provided output buffer. + * \param[out] buf caller-allocated output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] lai  LAI to encode, the rac member is ignored. + * \returns buf + */ +char *osmo_lai_name_buf(char *buf, size_t buf_len, const struct osmo_location_area_id *lai) +{ +	char plmn[16]; +	snprintf(buf, buf_len, "%s-%u", osmo_plmn_name_buf(plmn, sizeof(plmn), &lai->plmn), lai->lac);  	return buf;  } @@ -147,13 +190,18 @@ const char *osmo_plmn_name2(const struct osmo_plmn_id *plmn)  const char *osmo_lai_name(const struct osmo_location_area_id *lai)  {  	static char buf[32]; -	snprintf(buf, sizeof(buf), "%s-%u", osmo_plmn_name(&lai->plmn), lai->lac); -	return buf; +	return osmo_lai_name_buf(buf, sizeof(buf), lai);  } -static const char *_cgi_name(const struct osmo_cell_global_id *cgi, char *buf, size_t buflen) +/*! Return MCC-MNC-LAC-CI as string, in caller-provided output buffer. + * \param[out] buf caller-allocated output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] cgi  CGI to encode. + * \returns buf + */ +char *osmo_cgi_name_buf(char *buf, size_t buf_len, const struct osmo_cell_global_id *cgi)  { -	snprintf(buf, buflen, "%s-%u", osmo_lai_name(&cgi->lai), cgi->cell_identity); +	snprintf(buf, buf_len, "%s-%u", osmo_lai_name(&cgi->lai), cgi->cell_identity);  	return buf;  } @@ -164,7 +212,7 @@ static const char *_cgi_name(const struct osmo_cell_global_id *cgi, char *buf, s  const char *osmo_cgi_name(const struct osmo_cell_global_id *cgi)  {  	static char buf[32]; -	return _cgi_name(cgi, buf, sizeof(buf)); +	return osmo_cgi_name_buf(buf, sizeof(buf), cgi);  }  /*! Same as osmo_cgi_name(), but uses a different static buffer. @@ -175,7 +223,7 @@ const char *osmo_cgi_name(const struct osmo_cell_global_id *cgi)  const char *osmo_cgi_name2(const struct osmo_cell_global_id *cgi)  {  	static char buf[32]; -	return _cgi_name(cgi, buf, sizeof(buf)); +	return osmo_cgi_name_buf(buf, sizeof(buf), cgi);  }  static void to_bcd(uint8_t *bcd, uint16_t val) @@ -187,14 +235,31 @@ static void to_bcd(uint8_t *bcd, uint16_t val)  	bcd[0] = val % 10;  } -const char *osmo_gummei_name(const struct osmo_gummei *gummei) +/*! Return string representation of GUMMEI in caller-provided output buffer. + * \param[out] buf pointer to caller-provided output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] gummei GUMMEI to be stringified + * \returns buf + */ +char *osmo_gummei_name_buf(char *buf, size_t buf_len, const struct osmo_gummei *gummei)  { -	static char buf[32]; -	snprintf(buf, sizeof(buf), "%s-%04x-%02x", osmo_plmn_name(&gummei->plmn), +	char plmn[16]; +	snprintf(buf, buf_len, "%s-%04x-%02x", osmo_plmn_name_buf(plmn, sizeof(plmn), &gummei->plmn),  		 gummei->mme.group_id, gummei->mme.code);  	return buf;  } +/*! Return string representation of GUMMEI in static output buffer. + * \param[in] gummei GUMMEI to be stringified + * \returns pointer to static output buffer + */ +const char *osmo_gummei_name(const struct osmo_gummei *gummei) +{ +	static char buf[32]; +	return osmo_gummei_name_buf(buf, sizeof(buf), gummei); +} + +  /* Convert MCC + MNC to BCD representation   * \param[out] bcd_dst caller-allocated memory for output   * \param[in] mcc Mobile Country Code diff --git a/src/gsm/gsm48.c b/src/gsm/gsm48.c index 5dc30ad0..a45d67bc 100644 --- a/src/gsm/gsm48.c +++ b/src/gsm/gsm48.c @@ -182,6 +182,20 @@ const char *rr_cause_name(uint8_t cause)  	return get_value_string(rr_cause_names, cause);  } +/*! Return MCC-MNC-LAC-RAC as string, in a caller-provided output buffer. + * \param[out] buf caller-provided output buffer + * \param[in] buf_len size of buf in bytes + * \param[in] rai  RAI to encode. + * \returns buf + */ +char *osmo_rai_name_buf(char *buf, size_t buf_len, const struct gprs_ra_id *rai) +{ +	snprintf(buf, buf_len, "%s-%s-%u-%u", +		 osmo_mcc_name(rai->mcc), osmo_mnc_name(rai->mnc, rai->mnc_3_digits), rai->lac, +		 rai->rac); +	return buf; +} +  /*! Return MCC-MNC-LAC-RAC as string, in a static buffer.   * \param[in] rai  RAI to encode.   * \returns Static string buffer. @@ -189,10 +203,7 @@ const char *rr_cause_name(uint8_t cause)  const char *osmo_rai_name(const struct gprs_ra_id *rai)  {  	static char buf[32]; -	snprintf(buf, sizeof(buf), "%s-%s-%u-%u", -		 osmo_mcc_name(rai->mcc), osmo_mnc_name(rai->mnc, rai->mnc_3_digits), rai->lac, -		 rai->rac); -	return buf; +	return osmo_rai_name_buf(buf, sizeof(buf), rai);  }  /* FIXME: convert to value_string */ @@ -433,14 +444,15 @@ const char *gsm48_mi_type_name(uint8_t mi)  	return get_value_string(mi_type_names, mi);  } -/*! Return a human readable representation of a Mobile Identity in static buffer. +/*! Return a human readable representation of a Mobile Identity in caller-provided buffer. + * \param[out] buf caller-provided output buffer + * \param[in] buf_len size of buf in bytes   * \param[in] mi  Mobile Identity buffer containing 3GPP TS 04.08 style MI type and data.   * \param[in] mi_len  Length of mi. - * \return A string like "IMSI-1234567", "TMSI-0x1234ABCD" or "unknown", "TMSI-invalid"... + * \return buf   */ -const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len) +char *osmo_mi_name_buf(char *buf, size_t buf_len, const uint8_t *mi, uint8_t mi_len)  { -	static char mi_name[10 + GSM48_MI_SIZE + 1];  	uint8_t mi_type;  	uint32_t tmsi;  	char mi_string[GSM48_MI_SIZE]; @@ -452,8 +464,8 @@ const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len)  		/* Table 10.5.4.3, reverse generate_mid_from_tmsi */  		if (mi_len == GSM48_TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {  			tmsi = osmo_load32be(&mi[1]); -			snprintf(mi_name, sizeof(mi_name), "TMSI-0x%08" PRIX32, tmsi); -			return mi_name; +			snprintf(buf, buf_len, "TMSI-0x%08" PRIX32, tmsi); +			return buf;  		}  		return "TMSI-invalid"; @@ -461,14 +473,25 @@ const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len)  	case GSM_MI_TYPE_IMEI:  	case GSM_MI_TYPE_IMEISV:  		osmo_bcd2str(mi_string, sizeof(mi_string), mi, 1, (mi_len * 2) - (mi[0] & GSM_MI_ODD ? 0 : 1), true); -		snprintf(mi_name, sizeof(mi_name), "%s-%s", gsm48_mi_type_name(mi_type), mi_string); -		return mi_name; +		snprintf(buf, buf_len, "%s-%s", gsm48_mi_type_name(mi_type), mi_string); +		return buf;  	default:  		return "unknown";  	}  } +/*! Return a human readable representation of a Mobile Identity in static buffer. + * \param[in] mi  Mobile Identity buffer containing 3GPP TS 04.08 style MI type and data. + * \param[in] mi_len  Length of mi. + * \return A string like "IMSI-1234567", "TMSI-0x1234ABCD" or "unknown", "TMSI-invalid"... + */ +const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len) +{ +	static char mi_name[10 + GSM48_MI_SIZE + 1]; +	return osmo_mi_name_buf(mi_name, sizeof(mi_name), mi, mi_len); +} +  /*! Checks is particular message is cipherable in A/Gb mode according to   *         3GPP TS 24.008 ยง 4.7.1.2   *  \param[in] hdr Message header @@ -1050,16 +1073,17 @@ const struct value_string gsm48_nc_ss_msgtype_names[] = {  	{ 0, NULL }  }; -/*! Compose a string naming the message type for given protocol. +/*! Compose a string naming the message type for given protocol, in a caller-provided buffer.   * If the message type string is known, return the message type name, otherwise   * return "<protocol discriminator name>:<message type in hex>". + * \param[out] buf caller-allcated output string buffer + * \param[in] buf_len size of buf in bytes   * \param[in] pdisc protocol discriminator like GSM48_PDISC_MM   * \param[in] msg_type message type like GSM48_MT_MM_LOC_UPD_REQUEST - * \returns statically allocated string or string constant. + * \returns buf   */ -const char *gsm48_pdisc_msgtype_name(uint8_t pdisc, uint8_t msg_type) +char *gsm48_pdisc_msgtype_name_buf(char *buf, size_t buf_len, uint8_t pdisc, uint8_t msg_type)  { -	static char namebuf[64];  	const struct value_string *msgt_names;  	switch (pdisc) { @@ -1081,11 +1105,23 @@ const char *gsm48_pdisc_msgtype_name(uint8_t pdisc, uint8_t msg_type)  	}  	if (msgt_names) -		return get_value_string(msgt_names, msg_type); +		snprintf(buf, buf_len, "%s", get_value_string(msgt_names, msg_type)); +	else +		snprintf(buf, buf_len, "%s:0x%02x", gsm48_pdisc_name(pdisc), msg_type); +	return buf; +} -	snprintf(namebuf, sizeof(namebuf), "%s:0x%02x", -		 gsm48_pdisc_name(pdisc), msg_type); -	return namebuf; +/*! Compose a string naming the message type for given protocol, in a static buffer. + * If the message type string is known, return the message type name, otherwise + * return "<protocol discriminator name>:<message type in hex>". + * \param[in] pdisc protocol  | 
