mirror of https://gerrit.osmocom.org/libosmocore
Add _buf() functions to bypass static string buffers
We have a number of static buffers in use in libosmo*. This means the related functions are not usable in a thread-safe way. While we so far don't have many multi-threaded programs in the osmocom universe, the static buffers also prevent us from calling the same e.g. string-ify function twice within a single printf() call. Let's make sure there's an alternative function in all those cases, where the user can pass in a caller-allocated buffer + size, and make the 'classic' function with the static buffer a wrapper around that _buf() variant. Change-Id: Ibf85f79e93244f53b2684ff6f1095c5b41203e05
This commit is contained in:
parent
98ed3393cd
commit
4a62eda225
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*! @} */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
|
|
|
@ -89,6 +89,18 @@ bool osmo_imei_str_valid(const char *imei, bool with_15th_digit)
|
|||
return is_n_digits(imei, 14, 14);
|
||||
}
|
||||
|
||||
/*! 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.
|
||||
|
@ -96,7 +108,19 @@ bool osmo_imei_str_valid(const char *imei, bool with_15th_digit)
|
|||
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
|
||||
|
|
|
@ -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 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.
|
||||
*/
|
||||
const char *gsm48_pdisc_msgtype_name(uint8_t pdisc, uint8_t msg_type)
|
||||
{
|
||||
static char namebuf[64];
|
||||
return gsm48_pdisc_msgtype_name_buf(namebuf, sizeof(namebuf), pdisc, msg_type);
|
||||
}
|
||||
|
||||
const struct value_string gsm48_reject_value_names[] = {
|
||||
|
@ -1187,9 +1223,8 @@ bool osmo_gsm48_classmark_is_r99(const struct osmo_gsm48_classmark *cm)
|
|||
* \param[in] cm Classmarks.
|
||||
* \returns A statically allocated string like "cm1{a5/1=supported} cm2{0x23= A5/2 A5/3} no-cm3"
|
||||
*/
|
||||
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)
|
||||
{
|
||||
static char buf[128];
|
||||
char cm1[42] = "no-cm1";
|
||||
char cm2[42] = " no-cm2";
|
||||
char cm3[42] = " no-cm3";
|
||||
|
@ -1212,10 +1247,21 @@ const char *osmo_gsm48_classmark_a5_name(const struct osmo_gsm48_classmark *cm)
|
|||
cm->classmark3[0] & (1 << 2) ? " A5/6" : "",
|
||||
cm->classmark3[0] & (1 << 3) ? " A5/7" : "");
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%s%s", cm1, cm2, cm3);
|
||||
snprintf(buf, buf_len, "%s%s%s", cm1, cm2, cm3);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*! Return a string representation of A5 cipher algorithms indicated by Classmark 1, 2 and 3.
|
||||
* \param[in] cm Classmarks.
|
||||
* \returns A statically allocated string like "cm1{a5/1=supported} cm2{0x23= A5/2 A5/3} no-cm3"
|
||||
*/
|
||||
const char *osmo_gsm48_classmark_a5_name(const struct osmo_gsm48_classmark *cm)
|
||||
{
|
||||
static char buf[128];
|
||||
return osmo_gsm48_classmark_a5_name_buf(buf, sizeof(buf), cm);
|
||||
}
|
||||
|
||||
|
||||
/*! Overwrite dst with the Classmark information present in src.
|
||||
* Add an new Classmark and overwrite in dst what src has to offer, but where src has no Classmark information, leave
|
||||
* dst unchanged. (For Classmark 2 and 3, dst will exactly match any non-zero Classmark length from src, hence may end
|
||||
|
|
|
@ -886,16 +886,21 @@ uint32_t gsm_gsmtime2fn(struct gsm_time *time)
|
|||
return (51 * ((time->t3 - time->t2 + 26) % 26) + time->t3 + (26 * 51 * time->t1));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
static char buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%06"PRIu32"/%02"PRIu16"/%02"PRIu8"/%02"PRIu8"/%02"PRIu8,
|
||||
snprintf(buf, buf_len, "%06"PRIu32"/%02"PRIu16"/%02"PRIu8"/%02"PRIu8"/%02"PRIu8,
|
||||
tm->fn, tm->t1, tm->t2, tm->t3, (uint8_t)tm->fn%52);
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *osmo_dump_gsmtime(const struct gsm_time *tm)
|
||||
{
|
||||
static char buf[64];
|
||||
return osmo_dump_gsmtime_buf(buf, sizeof(buf), tm);
|
||||
}
|
||||
|
||||
|
||||
/*! append range1024 encoded data to bit vector
|
||||
* \param[out] bv Caller-provided output bit-vector
|
||||
* \param[in] r Input Range1024 sructure */
|
||||
|
|
|
@ -9,6 +9,7 @@ abis_nm_fail_evt_vrep;
|
|||
abis_nm_chcomb4pchan;
|
||||
abis_nm_debugp_foh;
|
||||
abis_nm_dump_foh;
|
||||
abis_nm_dump_foh_buf;
|
||||
abis_nm_event_type_name;
|
||||
abis_nm_nack_cause_name;
|
||||
abis_nm_nack_name;
|
||||
|
@ -225,6 +226,7 @@ gsm0808_speech_codec_type_names;
|
|||
gsm0808_permitted_speech_names;
|
||||
gsm0808_chosen_enc_alg_names;
|
||||
gsm0808_channel_type_name;
|
||||
gsm0808_channel_type_name_buf;
|
||||
gsm0808_lcls_config_names;
|
||||
gsm0808_lcls_control_names;
|
||||
gsm0808_lcls_status_names;
|
||||
|
@ -250,7 +252,9 @@ osmo_enc_gcr;
|
|||
osmo_dec_gcr;
|
||||
osmo_gcr_eq;
|
||||
osmo_gcr_dump;
|
||||
osmo_gcr_dump_buf;
|
||||
osmo_lcls_dump;
|
||||
osmo_lcls_dump_buf;
|
||||
|
||||
gsm0858_rsl_ul_meas_enc;
|
||||
|
||||
|
@ -345,6 +349,7 @@ gsm48_set_dtx;
|
|||
gsm48_dtx_mode;
|
||||
gsm48_mi_type_name;
|
||||
osmo_mi_name;
|
||||
osmo_mi_name_buf;
|
||||
gsm48_mcc_mnc_to_bcd;
|
||||
gsm48_mcc_mnc_from_bcd;
|
||||
gsm48_generate_lai2;
|
||||
|
@ -354,14 +359,21 @@ osmo_bts_feature_name;
|
|||
osmo_plmn_to_bcd;
|
||||
osmo_plmn_from_bcd;
|
||||
osmo_mcc_name;
|
||||
osmo_mcc_name_buf;
|
||||
osmo_mnc_name;
|
||||
osmo_mnc_name_buf;
|
||||
osmo_plmn_name;
|
||||
osmo_plmn_name_buf;
|
||||
osmo_plmn_name2;
|
||||
osmo_lai_name;
|
||||
osmo_lai_name_buf;
|
||||
osmo_rai_name;
|
||||
osmo_rai_name_buf;
|
||||
osmo_cgi_name;
|
||||
osmo_cgi_name_buf;
|
||||
osmo_cgi_name2;
|
||||
osmo_gummei_name;
|
||||
osmo_gummei_name_buf;
|
||||
osmo_mnc_from_str;
|
||||
osmo_mnc_cmp;
|
||||
osmo_plmn_cmp;
|
||||
|
@ -378,6 +390,7 @@ gsm48_mm_msgtype_names;
|
|||
gsm48_cc_msgtype_names;
|
||||
gsm48_cc_cause_names;
|
||||
gsm48_pdisc_msgtype_name;
|
||||
gsm48_pdisc_msgtype_name_buf;
|
||||
gsm48_reject_value_names;
|
||||
|
||||
gsm_7bit_decode;
|
||||
|
@ -403,6 +416,7 @@ gsm_fn_as_gsmtime_str;
|
|||
gsm_get_octet_len;
|
||||
gsm_gsmtime2fn;
|
||||
osmo_dump_gsmtime;
|
||||
osmo_dump_gsmtime_buf;
|
||||
|
||||
gsm_milenage;
|
||||
gsm_septet_encode;
|
||||
|
@ -472,6 +486,7 @@ rsl_ipac_eie_tlvdef;
|
|||
rsl_ccch_conf_to_bs_cc_chans;
|
||||
rsl_ccch_conf_to_bs_ccch_sdcch_comb;
|
||||
rsl_chan_nr_str;
|
||||
rsl_chan_nr_str_buf;
|
||||
rsl_dec_chan_nr;
|
||||
rsl_enc_chan_nr;
|
||||
rsl_err_name;
|
||||
|
@ -533,7 +548,9 @@ ipa_prepend_header_ext;
|
|||
ipa_send;
|
||||
|
||||
osmo_apn_qualify;
|
||||
osmo_apn_qualify_buf;
|
||||
osmo_apn_qualify_from_imsi;
|
||||
osmo_apn_qualify_from_imsi_buf;
|
||||
osmo_apn_to_str;
|
||||
osmo_apn_from_str;
|
||||
|
||||
|
@ -592,6 +609,7 @@ osmo_gsm48_classmark1_is_r99;
|
|||
osmo_gsm48_classmark2_is_r99;
|
||||
osmo_gsm48_classmark_supports_a5;
|
||||
osmo_gsm48_classmark_a5_name;
|
||||
osmo_gsm48_classmark_a5_name_buf;
|
||||
osmo_gsm48_classmark_update;
|
||||
|
||||
local: *;
|
||||
|
|
|
@ -215,33 +215,47 @@ int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *tim
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Get human-readable string for RSL channel number */
|
||||
const char *rsl_chan_nr_str(uint8_t chan_nr)
|
||||
/*! Get human-readable string for RSL channel number, in caller-provided buffer.
|
||||
* \param[out] buf caller-provided output buffer
|
||||
* \param[in] buf_len size of buf in bytes
|
||||
* \param[in] chan_nr channel number to be stringified
|
||||
* \returns buf with string
|
||||
*/
|
||||
char *rsl_chan_nr_str_buf(char *buf, size_t buf_len, uint8_t chan_nr)
|
||||
{
|
||||
static char str[20];
|
||||
int ts = chan_nr & 7;
|
||||
uint8_t cbits = chan_nr >> 3;
|
||||
|
||||
if (cbits == 0x01)
|
||||
sprintf(str, "TCH/F on TS%d", ts);
|
||||
snprintf(buf, buf_len, "TCH/F on TS%d", ts);
|
||||
else if ((cbits & 0x1e) == 0x02)
|
||||
sprintf(str, "TCH/H(%u) on TS%d", cbits & 0x01, ts);
|
||||
snprintf(buf, buf_len, "TCH/H(%u) on TS%d", cbits & 0x01, ts);
|
||||
else if ((cbits & 0x1c) == 0x04)
|
||||
sprintf(str, "SDCCH/4(%u) on TS%d", cbits & 0x03, ts);
|
||||
snprintf(buf, buf_len, "SDCCH/4(%u) on TS%d", cbits & 0x03, ts);
|
||||
else if ((cbits & 0x18) == 0x08)
|
||||
sprintf(str, "SDCCH/8(%u) on TS%d", cbits & 0x07, ts);
|
||||
snprintf(buf, buf_len, "SDCCH/8(%u) on TS%d", cbits & 0x07, ts);
|
||||
else if (cbits == 0x10)
|
||||
sprintf(str, "BCCH on TS%d", ts);
|
||||
snprintf(buf, buf_len, "BCCH on TS%d", ts);
|
||||
else if (cbits == 0x11)
|
||||
sprintf(str, "RACH on TS%d", ts);
|
||||
snprintf(buf, buf_len, "RACH on TS%d", ts);
|
||||
else if (cbits == 0x12)
|
||||
sprintf(str, "PCH/AGCH on TS%d", ts);
|
||||
snprintf(buf, buf_len, "PCH/AGCH on TS%d", ts);
|
||||
else if (cbits == 0x18)
|
||||
sprintf(str, "PDCH on TS%d", ts);
|
||||
snprintf(buf, buf_len, "PDCH on TS%d", ts);
|
||||
else
|
||||
sprintf(str, "UNKNOWN on TS%d", ts);
|
||||
snprintf(buf, buf_len, "UNKNOWN on TS%d", ts);
|
||||
|
||||
return str;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*! Get human-readable string for RSL channel number, in static buffer.
|
||||
* \param[in] chan_nr channel number to be stringified
|
||||
* \returns buf with string
|
||||
*/
|
||||
const char *rsl_chan_nr_str(uint8_t chan_nr)
|
||||
{
|
||||
static char str[20];
|
||||
return rsl_chan_nr_str_buf(str, sizeof(str), chan_nr);
|
||||
}
|
||||
|
||||
static const struct value_string rsl_err_vals[] = {
|
||||
|
|
38
src/msgb.c
38
src/msgb.c
|
@ -392,13 +392,14 @@ int msgb_resize_area(struct msgb *msg, uint8_t *area,
|
|||
}
|
||||
|
||||
|
||||
/*! Return a (static) buffer containing a hexdump of the msg
|
||||
* \param[in] msg message buffer
|
||||
* \returns a pointer to a static char array
|
||||
/*! fill user-provided buffer with hexdump of the msg.
|
||||
* \param[out] buf caller-allocated buffer for output string
|
||||
* \param[in] buf_len length of buf
|
||||
* \param[in] msg message buffer to be dumped
|
||||
* \returns buf
|
||||
*/
|
||||
const char *msgb_hexdump(const struct msgb *msg)
|
||||
char *msgb_hexdump_buf(char *buf, size_t buf_len, const struct msgb *msg)
|
||||
{
|
||||
static char buf[4100];
|
||||
int buf_offs = 0;
|
||||
int nchars;
|
||||
const unsigned char *start = msg->data;
|
||||
|
@ -421,32 +422,32 @@ const char *msgb_hexdump(const struct msgb *msg)
|
|||
if (lxhs[i] > msg->tail)
|
||||
continue;
|
||||
if (lxhs[i] < msg->data || lxhs[i] > msg->tail) {
|
||||
nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs,
|
||||
nchars = snprintf(buf + buf_offs, buf_len - buf_offs,
|
||||
"(L%d=data%+" PRIdPTR ") ",
|
||||
i+1, lxhs[i] - msg->data);
|
||||
buf_offs += nchars;
|
||||
continue;
|
||||
}
|
||||
if (lxhs[i] < start) {
|
||||
nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs,
|
||||
nchars = snprintf(buf + buf_offs, buf_len - buf_offs,
|
||||
"(L%d%+" PRIdPTR ") ", i+1,
|
||||
start - lxhs[i]);
|
||||
buf_offs += nchars;
|
||||
continue;
|
||||
}
|
||||
nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs,
|
||||
nchars = snprintf(buf + buf_offs, buf_len - buf_offs,
|
||||
"%s[L%d]> ",
|
||||
osmo_hexdump(start, lxhs[i] - start),
|
||||
i+1);
|
||||
if (nchars < 0 || nchars + buf_offs >= sizeof(buf))
|
||||
if (nchars < 0 || nchars + buf_offs >= buf_len)
|
||||
return "ERROR";
|
||||
|
||||
buf_offs += nchars;
|
||||
start = lxhs[i];
|
||||
}
|
||||
nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs,
|
||||
nchars = snprintf(buf + buf_offs, buf_len - buf_offs,
|
||||
"%s", osmo_hexdump(start, msg->tail - start));
|
||||
if (nchars < 0 || nchars + buf_offs >= sizeof(buf))
|
||||
if (nchars < 0 || nchars + buf_offs >= buf_len)
|
||||
return "ERROR";
|
||||
|
||||
buf_offs += nchars;
|
||||
|
@ -456,17 +457,17 @@ const char *msgb_hexdump(const struct msgb *msg)
|
|||
continue;
|
||||
|
||||
if (lxhs[i] < msg->head || lxhs[i] > msg->head + msg->data_len) {
|
||||
nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs,
|
||||
nchars = snprintf(buf + buf_offs, buf_len - buf_offs,
|
||||
"(L%d out of range) ", i+1);
|
||||
} else if (lxhs[i] <= msg->data + msg->data_len &&
|
||||
lxhs[i] > msg->tail) {
|
||||
nchars = snprintf(buf + buf_offs, sizeof(buf) - buf_offs,
|
||||
nchars = snprintf(buf + buf_offs, buf_len - buf_offs,
|
||||
"(L%d=tail%+" PRIdPTR ") ",
|
||||
i+1, lxhs[i] - msg->tail);
|
||||
} else
|
||||
continue;
|
||||
|
||||
if (nchars < 0 || nchars + buf_offs >= sizeof(buf))
|
||||
if (nchars < 0 || nchars + buf_offs >= buf_len)
|
||||
return "ERROR";
|
||||
buf_offs += nchars;
|
||||
}
|
||||
|
@ -474,6 +475,15 @@ const char *msgb_hexdump(const struct msgb *msg)
|
|||
return buf;
|
||||
}
|
||||
|
||||
/*! Return a (static) buffer containing a hexdump of the msg.
|
||||
* \param[in] msg message buffer
|
||||
* \returns a pointer to a static char array
|
||||
*/
|
||||
const char *msgb_hexdump(const struct msgb *msg)
|
||||
{
|
||||
static char buf[4100];
|
||||
return msgb_hexdump_buf(buf, sizeof(buf), msg);
|
||||
}
|
||||
|
||||
/*! Print a string to the end of message buffer.
|
||||
* \param[in] msgb message buffer.
|
||||
|
|
|
@ -267,10 +267,8 @@ struct msgb *osim_new_apdumsg(uint8_t cla, uint8_t ins, uint8_t p1,
|
|||
return msg;
|
||||
}
|
||||
|
||||
/* FIXME: do we want to mark this as __thread? */
|
||||
static char sw_print_buf[256];
|
||||
|
||||
char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in)
|
||||
char *osim_print_sw_buf(char *buf, size_t buf_len, const struct osim_card_hdl *ch, uint16_t sw_in)
|
||||
{
|
||||
const struct osim_card_sw *csw;
|
||||
|
||||
|
@ -283,25 +281,29 @@ char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in)
|
|||
|
||||
switch (csw->type) {
|
||||
case SW_TYPE_STR:
|
||||
snprintf(sw_print_buf, sizeof(sw_print_buf),
|
||||
"%04x (%s)", sw_in, csw->u.str);
|
||||
snprintf(buf, buf_len, "%04x (%s)", sw_in, csw->u.str);
|
||||
break;
|
||||
default:
|
||||
goto ret_def;
|
||||
}
|
||||
|
||||
sw_print_buf[sizeof(sw_print_buf)-1] = '\0';
|
||||
buf[buf_len-1] = '\0';
|
||||
|
||||
return sw_print_buf;
|
||||
return buf;
|
||||
|
||||
ret_def:
|
||||
snprintf(sw_print_buf, sizeof(sw_print_buf),
|
||||
"%04x (Unknown)", sw_in);
|
||||
sw_print_buf[sizeof(sw_print_buf)-1] = '\0';
|
||||
snprintf(buf, buf_len, "%04x (Unknown)", sw_in);
|
||||
buf[buf_len-1] = '\0';
|
||||
|
||||
return sw_print_buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in)
|
||||
{
|
||||
/* FIXME: do we want to mark this as __thread? */
|
||||
static char sw_print_buf[256];
|
||||
return osim_print_sw_buf(sw_print_buf, sizeof(sw_print_buf), ch, sw_in);
|
||||
}
|
||||
|
||||
const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,
|
||||
uint16_t sw_in)
|
||||
|
|
31
src/utils.c
31
src/utils.c
|
@ -273,17 +273,20 @@ const char *osmo_hexdump_buf(char *out_buf, size_t out_buf_size, const unsigned
|
|||
return out_buf;
|
||||
}
|
||||
|
||||
/*! Convert a sequence of unpacked bits to ASCII string
|
||||
/*! Convert a sequence of unpacked bits to ASCII string, in user-supplied buffer.
|
||||
* \param[out] buf caller-provided output string buffer
|
||||
* \param[out] buf_len size of buf in bytes
|
||||
* \param[in] bits A sequence of unpacked bits
|
||||
* \param[in] len Length of bits
|
||||
* \returns string representation in static buffer.
|
||||
*/
|
||||
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
|
||||
char *osmo_ubit_dump_buf(char *buf, size_t buf_len, const uint8_t *bits, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (len > sizeof(hexd_buff)-1)
|
||||
len = sizeof(hexd_buff)-1;
|
||||
memset(hexd_buff, 0, sizeof(hexd_buff));
|
||||
if (len > buf_len-1)
|
||||
len = buf_len-1;
|
||||
memset(buf, 0, buf_len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
char outch;
|
||||
|
@ -301,10 +304,20 @@ char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
|
|||
outch = 'E';
|
||||
break;
|
||||
}
|
||||
hexd_buff[i] = outch;
|
||||
buf[i] = outch;
|
||||
}
|
||||
hexd_buff[sizeof(hexd_buff)-1] = 0;
|
||||
return hexd_buff;
|
||||
buf[buf_len-1] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*! Convert a sequence of unpacked bits to ASCII string, in static buffer.
|
||||
* \param[in] bits A sequence of unpacked bits
|
||||
* \param[in] len Length of bits
|
||||
* \returns string representation in static buffer.
|
||||
*/
|
||||
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len)
|
||||
{
|
||||
return osmo_ubit_dump_buf(hexd_buff, sizeof(hexd_buff), bits, len);
|
||||
}
|
||||
|
||||
/*! Convert binary sequence to hexadecimal ASCII string
|
||||
|
@ -632,7 +645,7 @@ const char *osmo_escape_str(const char *str, int in_len)
|
|||
* \param[in] in_len Pass -1 to print until nul char, or >= 0 to force a length.
|
||||
* \returns buf containing a quoted and escaped representation, possibly truncated.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
int l;
|
||||
if (!str)
|
||||
|
|
Loading…
Reference in New Issue