diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gb/gprs_ns.c | 8 | ||||
| -rw-r--r-- | src/gb/libosmogb.map | 1 | ||||
| -rw-r--r-- | src/gsm/abis_nm.c | 9 | ||||
| -rw-r--r-- | src/gsm/apn.c | 16 | ||||
| -rw-r--r-- | src/gsm/gsm0808_utils.c | 40 | ||||
| -rw-r--r-- | src/gsm/gsm23003.c | 78 | ||||
| -rw-r--r-- | src/gsm/gsm48.c | 59 | ||||
| -rw-r--r-- | src/gsm/gsm_utils.c | 7 | ||||
| -rw-r--r-- | src/gsm/libosmogsm.map | 20 | ||||
| -rw-r--r-- | src/gsm/rsl.c | 13 | ||||
| -rw-r--r-- | src/msgb.c | 57 | ||||
| -rw-r--r-- | src/sim/core.c | 8 | ||||
| -rw-r--r-- | src/socket.c | 14 | ||||
| -rw-r--r-- | src/utils.c | 100 | 
14 files changed, 419 insertions, 11 deletions
| diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c index fc120cec..d72003ed 100644 --- a/src/gb/gprs_ns.c +++ b/src/gb/gprs_ns.c @@ -1552,6 +1552,14 @@ const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc)  	return gprs_ns_ll_str_buf(buf, sizeof(buf), nsvc);  } +char *gprs_ns_ll_str_c(const void *ctx, const struct gprs_nsvc *nsvc) +{ +	char *buf = talloc_size(ctx, INET6_ADDRSTRLEN+10); +	if (!buf) +		return buf; +	return gprs_ns_ll_str_buf(buf, INET6_ADDRSTRLEN+10, 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 21929da1..5e675a66 100644 --- a/src/gb/libosmogb.map +++ b/src/gb/libosmogb.map @@ -65,6 +65,7 @@ gprs_ns_tx_unblock;  gprs_ns_vty_init;  gprs_ns_ll_str;  gprs_ns_ll_str_buf; +gprs_ns_ll_str_c;  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 e25fdd03..a4c0e41f 100644 --- a/src/gsm/abis_nm.c +++ b/src/gsm/abis_nm.c @@ -943,6 +943,15 @@ const char *abis_nm_dump_foh(const struct abis_om_fom_hdr *foh)  	return abis_nm_dump_foh_buf(foh_buf, sizeof(foh_buf), foh);  } +char *abis_nm_dump_foh_c(void *ctx, const struct abis_om_fom_hdr *foh) +{ +	size_t len = 15 /* format */ + 22 /* obj_class_name */+ 4*3 /* uint8 */ + 1 /*nul*/; +	char *buf = talloc_size(ctx, len); +	if (!buf) +		return NULL; +	return abis_nm_dump_foh_buf(buf, len, foh); +} +  /* this is just for compatibility reasons, it is now a macro */  #undef abis_nm_debugp_foh  OSMO_DEPRECATED("Use abis_nm_debugp_foh macro instead") diff --git a/src/gsm/apn.c b/src/gsm/apn.c index 4ab370c5..88b45a4b 100644 --- a/src/gsm/apn.c +++ b/src/gsm/apn.c @@ -24,6 +24,7 @@  #include <stdint.h>  #include <stdlib.h>  #include <string.h> +#include <talloc.h>  #include <osmocom/gsm/apn.h> @@ -45,6 +46,13 @@ 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_c(const void *ctx, unsigned int mcc, unsigned int mnc, const char *ni) +{ +	char *buf = talloc_size(ctx, APN_MAXLEN); +	if (!buf) +		return NULL; +	return osmo_apn_qualify_buf(buf, APN_MAXLEN, 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) @@ -70,6 +78,14 @@ char *osmo_apn_qualify_from_imsi(const char *imsi,  	return osmo_apn_qualify_from_imsi_buf(apn_strbuf, sizeof(apn_strbuf), imsi, ni, have_3dig_mnc);  } +char *osmo_apn_qualify_from_imsi_c(const void *ctx, const char *imsi, const char *ni, int have_3dig_mnc) +{ +	char *buf = talloc_size(ctx, APN_MAXLEN); +	if (!buf) +		return NULL; +	return osmo_apn_qualify_from_imsi_buf(buf, APN_MAXLEN, imsi, ni, have_3dig_mnc); +} +  /**   * Convert an encoded APN into a dot-separated string.   * diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c index 52e46743..99cf1881 100644 --- a/src/gsm/gsm0808_utils.c +++ b/src/gsm/gsm0808_utils.c @@ -622,6 +622,14 @@ char *osmo_lcls_dump(const struct osmo_lcls *lcls)  	return osmo_lcls_dump_buf(dbuf, sizeof(dbuf), lcls);  } +char *osmo_lcls_dump_c(void *ctx, const struct osmo_lcls *lcls) +{ +	char *buf = talloc_size(ctx, 256); +	if (!buf) +		return NULL; +	return osmo_lcls_dump_buf(buf, 256, 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 @@ -1775,8 +1783,7 @@ const struct value_string gsm0808_cell_id_discr_names[] = {  #define APPEND_STR(fmt, args...) APPEND_THING(snprintf, fmt, ##args)  #define APPEND_CELL_ID_U(DISCR, U) APPEND_THING(gsm0808_cell_id_u_name, DISCR, U) -static const char *gsm0808_cell_id_name_buf(const struct gsm0808_cell_id *cid, -					    char *buf, size_t buflen) +char *gsm0808_cell_id_name_buf(char *buf, size_t buflen, const struct gsm0808_cell_id *cid)  {  	char *pos = buf;  	int total_len = 0; @@ -1793,7 +1800,7 @@ static const char *gsm0808_cell_id_name_buf(const struct gsm0808_cell_id *cid,  const char *gsm0808_cell_id_name(const struct gsm0808_cell_id *cid)  {  	static char buf[64]; -	return gsm0808_cell_id_name_buf(cid, buf, sizeof(buf)); +	return gsm0808_cell_id_name_buf(buf, sizeof(buf), cid);  }  /*! Like gsm0808_cell_id_name() but uses a different static buffer. @@ -1803,7 +1810,15 @@ const char *gsm0808_cell_id_name(const struct gsm0808_cell_id *cid)  const char *gsm0808_cell_id_name2(const struct gsm0808_cell_id *cid)  {  	static char buf[64]; -	return gsm0808_cell_id_name_buf(cid, buf, sizeof(buf)); +	return gsm0808_cell_id_name_buf(buf, sizeof(buf), cid); +} + +char *gsm0808_cell_id_name_c(const void *ctx, const struct gsm0808_cell_id *cid) +{ +	char *buf = talloc_size(ctx, 64); +	if (!buf) +		return NULL; +	return gsm0808_cell_id_name_buf(buf, 64, cid);  }  /*! Return a human readable representation of the Cell Identifier List, like @@ -1856,6 +1871,15 @@ const char *gsm0808_cell_id_list_name(const struct gsm0808_cell_id_list2 *cil)  	return buf;  } +char *gsm0808_cell_id_list_name_c(const void *ctx, const struct gsm0808_cell_id_list2 *cil) +{ +	char *buf = talloc_size(ctx, 1024); +	if (!buf) +		return NULL; +	gsm0808_cell_id_list_name_buf(buf, 1024, cil); +	return buf; +} +  #undef APPEND_STR  #undef APPEND_CELL_ID_U @@ -1873,4 +1897,12 @@ const char *gsm0808_channel_type_name(const struct gsm0808_channel_type *ct)  	return gsm0808_channel_type_name_buf(buf, sizeof(buf), ct);  } +char *gsm0808_channel_type_name_c(const void *ctx, const struct gsm0808_channel_type *ct) +{ +	char *buf = talloc_size(ctx, 128); +	if (!buf) +		return NULL; +	return gsm0808_channel_type_name_buf(buf, 128, ct); +} +  /*! @} */ diff --git a/src/gsm/gsm23003.c b/src/gsm/gsm23003.c index bbfe236a..2252f706 100644 --- a/src/gsm/gsm23003.c +++ b/src/gsm/gsm23003.c @@ -111,6 +111,19 @@ const char *osmo_mcc_name(uint16_t mcc)  	return osmo_mcc_name_buf(buf, sizeof(buf), mcc);  } +/*! Return MCC string as standardized 3-digit with leading zeros, into a talloc-allocated buffer. + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] mcc  MCC value. + * \returns string in dynamically allocated buffer. + */ +const char *osmo_mcc_name_c(const void *ctx, uint16_t mcc) +{ +	char *buf = talloc_size(ctx, 8); +	if (!buf) +		return NULL; +	return osmo_mcc_name_buf(buf, 8, 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 @@ -124,6 +137,20 @@ char *osmo_mnc_name_buf(char *buf, size_t buf_len, uint16_t mnc, bool mnc_3_digi  	return buf;  } +/*! Return MNC string as standardized 2- or 3-digit with leading zeros, into a talloc-allocated buffer. + * \param[in] ctx talloc context from which to allocate output buffer + * \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 dynamically allocated buffer. + */ +char *osmo_mnc_name_c(const void *ctx, uint16_t mnc, bool mnc_3_digits) +{ +	char *buf = talloc_size(ctx, 8); +	if (!buf) +		return buf; +	return osmo_mnc_name_buf(buf, 8, mnc, mnc_3_digits); +} +  /*! Return MNC string as standardized 2- or 3-digit with leading zeros.   * \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. @@ -170,6 +197,20 @@ const char *osmo_plmn_name2(const struct osmo_plmn_id *plmn)  	return osmo_plmn_name_buf(buf, sizeof(buf), plmn);  } +/*! Return MCC-MNC string as standardized 3-digit-dash-2/3-digit with leading zeros, into + *  a dynamically-allocated output buffer. + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] plmn  MCC-MNC value. + * \returns string in dynamically allocated buffer. + */ +char *osmo_plmn_name_c(const void *ctx, const struct osmo_plmn_id *plmn) +{ +	char *buf = talloc_size(ctx, 16); +	if (!buf) +		return NULL; +	return osmo_plmn_name_buf(buf, 16, 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 @@ -193,6 +234,19 @@ const char *osmo_lai_name(const struct osmo_location_area_id *lai)  	return osmo_lai_name_buf(buf, sizeof(buf), lai);  } +/*! Return MCC-MNC-LAC as string, in a talloc-allocated output buffer. + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] lai  LAI to encode, the rac member is ignored. + * \returns string representation of lai in dynamically allocated buffer. + */ +char *osmo_lai_name_c(const void *ctx, const struct osmo_location_area_id *lai) +{ +	char *buf = talloc_size(ctx, 32); +	if (!buf) +		return NULL; +	return osmo_lai_name_buf(buf, 32, lai); +} +  /*! 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 @@ -226,6 +280,17 @@ const char *osmo_cgi_name2(const struct osmo_cell_global_id *cgi)  	return osmo_cgi_name_buf(buf, sizeof(buf), cgi);  } +/*! Return MCC-MNC-LAC-CI as string, in a talloc-allocated output buffer. + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] cgi  CGI to encode. + * \returns string representation of CGI in dynamically-allocated buffer. + */ +char *osmo_cgi_name_c(const void *ctx, const struct osmo_cell_global_id *cgi) +{ +	char *buf = talloc_size(ctx, 32); +	return osmo_cgi_name_buf(buf, 32, cgi); +} +  static void to_bcd(uint8_t *bcd, uint16_t val)  {  	bcd[2] = val % 10; @@ -259,6 +324,19 @@ const char *osmo_gummei_name(const struct osmo_gummei *gummei)  	return osmo_gummei_name_buf(buf, sizeof(buf), gummei);  } +/*! Return string representation of GUMMEI in static 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 pointer to static output buffer + */ +char *osmo_gummei_name_c(const void *ctx, const struct osmo_gummei *gummei) +{ +	char *buf = talloc_size(ctx, 32); +	if (!buf) +		return NULL; +	return osmo_gummei_name_buf(buf, 32, gummei); +}  /* Convert MCC + MNC to BCD representation   * \param[out] bcd_dst caller-allocated memory for output diff --git a/src/gsm/gsm48.c b/src/gsm/gsm48.c index a45d67bc..c2c19cfe 100644 --- a/src/gsm/gsm48.c +++ b/src/gsm/gsm48.c @@ -36,6 +36,7 @@  #include <osmocom/core/byteswap.h>  #include <osmocom/core/bit16gen.h>  #include <osmocom/core/bit32gen.h> +#include <osmocom/core/talloc.h>  #include <osmocom/gsm/tlv.h>  #include <osmocom/gsm/gsm48.h>  #include <osmocom/gsm/gsm0502.h> @@ -206,6 +207,19 @@ const char *osmo_rai_name(const struct gprs_ra_id *rai)  	return osmo_rai_name_buf(buf, sizeof(buf), rai);  } +/*! Return MCC-MNC-LAC-RAC as string, in dynamically-allocated output buffer. + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] rai  RAI to encode. + * \returns string representation in dynamically-allocated output buffer. + */ +char *osmo_rai_name_c(const void *ctx, const struct gprs_ra_id *rai) +{ +	char *buf = talloc_size(ctx, 32); +	if (!buf) +		return NULL; +	return osmo_rai_name_buf(buf, 32, rai); +} +  /* FIXME: convert to value_string */  static const char *cc_state_names[32] = {  	"NULL", @@ -492,6 +506,22 @@ const char *osmo_mi_name(const uint8_t *mi, uint8_t mi_len)  	return osmo_mi_name_buf(mi_name, sizeof(mi_name), mi, mi_len);  } +/*! Return a human readable representation of a Mobile Identity in dynamically-allocated buffer. + * \param[in] ctx talloc context from which to allocate output 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" in a + * 	   dynamically-allocated output buffer. + */ +char *osmo_mi_name_c(const void *ctx, const uint8_t *mi, uint8_t mi_len) +{ +	size_t buf_len = 10 + GSM48_MI_SIZE + 1; +	char *mi_name = talloc_size(ctx, buf_len); +	if (!mi_name) +		return NULL; +	return osmo_mi_name_buf(mi_name, buf_len, 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 @@ -1124,6 +1154,22 @@ const char *gsm48_pdisc_msgtype_name(uint8_t pdisc, uint8_t msg_type)  	return gsm48_pdisc_msgtype_name_buf(namebuf, sizeof(namebuf), pdisc, msg_type);  } +/*! Compose a string naming the message type for given protocol, in a dynamically-allocated buffer. + * If the message type string is known, return the message type name, otherwise + * return "<protocol discriminator name>:<message type in hex>". + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] pdisc protocol discriminator like GSM48_PDISC_MM + * \param[in] msg_type message type like GSM48_MT_MM_LOC_UPD_REQUEST + * \returns string representation in dynamically allocated output buffer. + */ +char *gsm48_pdisc_msgtype_name_c(const void *ctx, uint8_t pdisc, uint8_t msg_type) +{ +	char *namebuf = talloc_size(ctx, 64); +	if (!namebuf) +		return NULL; +	return gsm48_pdisc_msgtype_name_buf(namebuf, 64, pdisc, msg_type); +} +  const struct value_string gsm48_reject_value_names[] = {  	 { GSM48_REJECT_IMSI_UNKNOWN_IN_HLR, "IMSI_UNKNOWN_IN_HLR" },  	 { GSM48_REJECT_ILLEGAL_MS, "ILLEGAL_MS" }, @@ -1261,6 +1307,19 @@ const char *osmo_gsm48_classmark_a5_name(const struct osmo_gsm48_classmark *cm)  	return osmo_gsm48_classmark_a5_name_buf(buf, sizeof(buf), cm);  } +/*! Return a string representation of A5 cipher algorithms indicated by Classmark 1, 2 and 3. + * \param[in] ctx talloc context from which to allocate output buffer + * \param[in] cm  Classmarks. + * \returns string like "cm1{a5/1=supported} cm2{0x23= A5/2 A5/3} no-cm3" in dynamically-allocated + *          output buffer. + */ +char *osmo_gsm48_classmark_a5_name_c(const void *ctx, const struct osmo_gsm48_classmark *cm) +{ +	char *buf = talloc_size(ctx, 128); +	if (!buf) +		return NULL; +	return osmo_gsm48_classmark_a5_name_buf(buf, 128, 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 diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index f2bf57bf..1450ed0b 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -900,6 +900,13 @@ char *osmo_dump_gsmtime(const struct gsm_time *tm)  	return osmo_dump_gsmtime_buf(buf, sizeof(buf), tm);  } +char *osmo_dump_gsmtime_c(const void *ctx, const struct gsm_time *tm) +{ +	char *buf = talloc_size(ctx, 64); +	if (!buf) +		return NULL; +	return osmo_dump_gsmtime_buf(buf, 64, tm); +}  /*! append range1024 encoded data to bit vector   *  \param[out] bv Caller-provided output bit-vector diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index a69fb606..56481fdd 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -10,6 +10,7 @@ abis_nm_chcomb4pchan;  abis_nm_debugp_foh;  abis_nm_dump_foh;  abis_nm_dump_foh_buf; +abis_nm_dump_foh_c;  abis_nm_event_type_name;  abis_nm_nack_cause_name;  abis_nm_nack_name; @@ -212,8 +213,11 @@ gsm0808_enc_cell_id;  gsm0808_dec_cell_id;  gsm0808_cell_id_name;  gsm0808_cell_id_name2; +gsm0808_cell_id_name_buf; +gsm0808_cell_id_name_c;  gsm0808_cell_id_list_name;  gsm0808_cell_id_list_name_buf; +gsm0808_cell_id_list_name_c;  gsm0808_cell_id_discr_names;  gsm0808_cell_id_u_name;  gsm0808_cell_ids_match; @@ -227,6 +231,7 @@ gsm0808_permitted_speech_names;  gsm0808_chosen_enc_alg_names;  gsm0808_channel_type_name;  gsm0808_channel_type_name_buf; +gsm0808_channel_type_name_c;  gsm0808_lcls_config_names;  gsm0808_lcls_control_names;  gsm0808_lcls_status_names; @@ -255,6 +260,7 @@ osmo_gcr_dump;  osmo_gcr_dump_buf;  osmo_lcls_dump;  osmo_lcls_dump_buf; +osmo_lcls_dump_c;  gsm0858_rsl_ul_meas_enc; @@ -350,6 +356,7 @@ gsm48_dtx_mode;  gsm48_mi_type_name;  osmo_mi_name;  osmo_mi_name_buf; +osmo_mi_name_c;  gsm48_mcc_mnc_to_bcd;  gsm48_mcc_mnc_from_bcd;  gsm48_generate_lai2; @@ -360,20 +367,27 @@ osmo_plmn_to_bcd;  osmo_plmn_from_bcd;  osmo_mcc_name;  osmo_mcc_name_buf; +osmo_mcc_name_c;  osmo_mnc_name;  osmo_mnc_name_buf; +osmo_mnc_name_c;  osmo_plmn_name;  osmo_plmn_name_buf; +osmo_plmn_name_c;  osmo_plmn_name2;  osmo_lai_name;  osmo_lai_name_buf; +osmo_lai_name_c;  osmo_rai_name;  osmo_rai_name_buf; +osmo_rai_name_c;  osmo_cgi_name;  osmo_cgi_name_buf; +osmo_cgi_name_c;  osmo_cgi_name2;  osmo_gummei_name;  osmo_gummei_name_buf; +osmo_gummei_name_c;  osmo_mnc_from_str;  osmo_mnc_cmp;  osmo_plmn_cmp; @@ -391,6 +405,7 @@ gsm48_cc_msgtype_names;  gsm48_cc_cause_names;  gsm48_pdisc_msgtype_name;  gsm48_pdisc_msgtype_name_buf; +gsm48_pdisc_msgtype_name_c;  gsm48_reject_value_names;  gsm_7bit_decode; @@ -417,6 +432,7 @@ gsm_get_octet_len;  gsm_gsmtime2fn;  osmo_dump_gsmtime;  osmo_dump_gsmtime_buf; +osmo_dump_gsmtime_c;  gsm_milenage;  gsm_septet_encode; @@ -487,6 +503,7 @@ 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_chan_nr_str_c;  rsl_dec_chan_nr;  rsl_enc_chan_nr;  rsl_err_name; @@ -549,8 +566,10 @@ ipa_send;  osmo_apn_qualify;  osmo_apn_qualify_buf; +osmo_apn_qualify_c;  osmo_apn_qualify_from_imsi;  osmo_apn_qualify_from_imsi_buf; +osmo_apn_qualify_from_imsi_c;  osmo_apn_to_str;  osmo_apn_from_str; @@ -610,6 +629,7 @@ osmo_gsm48_classmark2_is_r99;  osmo_gsm48_classmark_supports_a5;  osmo_gsm48_classmark_a5_name;  osmo_gsm48_classmark_a5_name_buf; +osmo_gsm48_classmark_a5_name_c;  osmo_gsm48_classmark_update;  local: *; diff --git a/src/gsm/rsl.c b/src/gsm/rsl.c index 7bc60027..17774799 100644 --- a/src/gsm/rsl.c +++ b/src/gsm/rsl.c @@ -258,6 +258,19 @@ const char *rsl_chan_nr_str(uint8_t chan_nr)  	return rsl_chan_nr_str_buf(str, sizeof(str), chan_nr);  } +/*! Get human-readable string for RSL channel number, in dynamically-allocated buffer. + *  \param[in] ctx talloc context from which to allocate output buffer + *  \param[in] chan_nr channel number to be stringified + *  \returns dynamically-allocated buffer with string representation + */ +char *rsl_chan_nr_str_c(const void *ctx, uint8_t chan_nr) +{ +	char *str = talloc_size(ctx, 20); +	if (!str) +		return NULL; +	return rsl_chan_nr_str_buf(str, 20, chan_nr); +} +  static const struct value_string rsl_err_vals[] = {  	{ RSL_ERR_RADIO_IF_FAIL,	"Radio Interface Failure" },  	{ RSL_ERR_RADIO_LINK_FAIL,	"Radio Link Failure" }, @@ -64,9 +64,8 @@  #include <osmocom/core/talloc.h>  #include <osmocom/core/logging.h> -void *tall_msgb_ctx = NULL; - -/*! Allocate a new message buffer +/*! Allocate a new message buffer from given talloc cotext + * \param[in] ctx talloc context from which to allocate   * \param[in] size Length in octets, including headroom   * \param[in] name Human-readable name to be associated with msgb   * \returns dynamically-allocated \ref msgb @@ -75,11 +74,11 @@ void *tall_msgb_ctx = NULL;   * memory buffer for the actual message data (size specified by \a size)   * using the talloc memory context previously set by \ref msgb_set_talloc_ctx   */ -struct msgb *msgb_alloc(uint16_t size, const char *name) +struct msgb *msgb_alloc_c(const void *ctx, uint16_t size, const char *name)  {  	struct msgb *msg; -	msg = talloc_named_const(tall_msgb_ctx, sizeof(*msg) + size, name); +	msg = talloc_named_const(ctx, sizeof(*msg) + size, name);  	if (!msg) {  		LOGP(DLGLOBAL, LOGL_FATAL, "Unable to allocate a msgb: "  			"name='%s', size=%u\n", name, size); @@ -98,6 +97,24 @@ struct msgb *msgb_alloc(uint16_t size, const char *name)  	return msg;  } +/* default msgb allocation context for msgb_alloc() */ +void *tall_msgb_ctx = NULL; + +/*! Allocate a new message buffer from tall_msgb_ctx + * \param[in] size Length in octets, including headroom + * \param[in] name Human-readable name to be associated with msgb + * \returns dynamically-allocated \ref msgb + * + * This function allocates a 'struct msgb' as well as the underlying + * memory buffer for the actual message data (size specified by \a size) + * using the talloc memory context previously set by \ref msgb_set_talloc_ctx + */ +struct msgb *msgb_alloc(uint16_t size, const char *name) +{ +	return msgb_alloc_c(tall_msgb_ctx, size, name); +} + +  /*! Release given message buffer   * \param[in] m Message buffer to be freed   */ @@ -309,11 +326,11 @@ void *msgb_talloc_ctx_init(void *root_ctx, unsigned int pool_size)   *  \param[in] msg  The old msgb object   *  \param[in] name Human-readable name to be associated with msgb   */ -struct msgb *msgb_copy(const struct msgb *msg, const char *name) +struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *name)  {  	struct msgb *new_msg; -	new_msg = msgb_alloc(msg->data_len, name); +	new_msg = msgb_alloc_c(ctx, msg->data_len, name);  	if (!new_msg)  		return NULL; @@ -338,6 +355,19 @@ struct msgb *msgb_copy(const struct msgb *msg, const char *name)  	return new_msg;  } +/*! Copy an msgb. + * + *  This function allocates a new msgb, copies the data buffer of msg, + *  and adjusts the pointers (incl l1h-l4h) accordingly. The cb part + *  is not copied. + *  \param[in] msg  The old msgb object + *  \param[in] name Human-readable name to be associated with msgb + */ +struct msgb *msgb_copy(const struct msgb *msg, const char *name) +{ +	return msgb_copy_c(tall_msgb_ctx, msg, name); +} +  /*! Resize an area within an msgb   *   *  This resizes a sub area of the msgb data and adjusts the pointers (incl @@ -485,6 +515,19 @@ const char *msgb_hexdump(const struct msgb *msg)  	return msgb_hexdump_buf(buf, sizeof(buf), msg);  } +/*! Return a dynamically allocated buffer containing a hexdump of the msg + * \param[in] ctx talloc context from where to allocate the output string + * \param[in] msg message buffer + * \returns a pointer to a static char array + */ +char *msgb_hexdump_c(const void *ctx, const struct msgb *msg) +{ +	char *buf = talloc_size(ctx, msgb_length(msg)*3 + 100); +	if (!buf) +		return NULL; +	return msgb_hexdump_buf(buf, sizeof(buf), msg); +} +  /*! Print a string to the end of message buffer.   * \param[in] msgb message buffer.   * \param[in] format format string. diff --git a/src/sim/core.c b/src/sim/core.c index 998e836b..63b3000b 100644 --- a/src/sim/core.c +++ b/src/sim/core.c @@ -305,6 +305,14 @@ char *osim_print_sw(const struct osim_card_hdl *ch, uint16_t sw_in)  	return osim_print_sw_buf(sw_print_buf, sizeof(sw_print_buf), ch, sw_in);  } +char *osim_print_sw_c(const void *ctx, const struct osim_card_hdl *ch, uint16_t sw_in) +{ +	char *buf = talloc_size(ctx, 256); +	if (!buf) +		return NULL; +	return osim_print_sw_buf(buf, 256, ch, sw_in); +} +  const struct osim_card_sw *osim_find_sw(const struct osim_card_profile *cp,  					uint16_t sw_in)  { diff --git a/src/socket.c b/src/socket.c index 3a46ad02..c817e723 100644 --- a/src/socket.c +++ b/src/socket.c @@ -827,6 +827,20 @@ const char *osmo_sock_get_name2(int fd)  	return str;  } +/*! Get address/port information on socket in static string, like "r=1.2.3.4:5<->l=6.7.8.9:10". + * This does not include braces like osmo_sock_get_name(). + *  \param[in] fd  File descriptor of socket. + *  \return Static string buffer containing the result. + */ +char *osmo_sock_get_name2_c(const void *ctx, int fd) +{ +	char *str = talloc_size(ctx, OSMO_SOCK_NAME_MAXLEN); +	if (!str) +		return NULL; +	osmo_sock_get_name_buf(str, sizeof(str), fd); +	return str; +} +  static int sock_get_domain(int fd)  {  	int domain; diff --git a/src/utils.c b/src/utils.c index 47963650..b8b4ef56 100644 --- a/src/utils.c +++ b/src/utils.c @@ -338,6 +338,27 @@ char *osmo_hexdump(const unsigned char *buf, int len)  }  /*! Convert binary sequence to hexadecimal ASCII string + *  \param[in] ctx talloc context from where to allocate the output string + *  \param[in] buf pointer to sequence of bytes + *  \param[in] len length of buf in number of bytes + *  \returns pointer to zero-terminated string + * + * This function will print a sequence of bytes as hexadecimal numbers, + * adding one space character between each byte (e.g. "1a ef d9") + * + * The maximum size of the output buffer is 4096 bytes, i.e. the maximum + * number of input bytes that can be printed in one call is 1365! + */ +char *osmo_hexdump_c(const void *ctx, const unsigned char *buf, int len) +{ +	char *hexd_buff = talloc_size(ctx, len*3 + 1); +	if (!hexd_buff) +		return NULL; +	osmo_hexdump_buf(hexd_buff, sizeof(hexd_buff), buf, len, " ", true); +	return hexd_buff; +} + +/*! Convert binary sequence to hexadecimal ASCII string   *  \param[in] buf pointer to sequence of bytes   *  \param[in] len length of buf in number of bytes   *  \returns pointer to zero-terminated string @@ -354,6 +375,28 @@ char *osmo_hexdump_nospc(const unsigned char *buf, int len)  	return hexd_buff;  } +/*! Convert binary sequence to hexadecimal ASCII string + *  \param[in] ctx talloc context from where to allocate the output string + *  \param[in] buf pointer to sequence of bytes + *  \param[in] len length of buf in number of bytes + *  \returns pointer to zero-terminated string + * + * This function will print a sequence of bytes as hexadecimal numbers, + * without any space character between each byte (e.g. "1aefd9") + * + * The maximum size of the output buffer is 4096 bytes, i.e. the maximum + * number of input bytes that can be printed in one call is 2048! + */ +char *osmo_hexdump_nospc_c(const void *ctx, const unsigned char *buf, int len) +{ +	char *hexd_buff = talloc_size(ctx, len*2 + 1); +	if (!hexd_buff) +		return NULL; +	osmo_hexdump_buf(hexd_buff, sizeof(hexd_buff), buf, len, "", true); +	return hexd_buff; +} + +  /* Compat with previous typo to preserve abi */  char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)  #if defined(__MACH__) && defined(__APPLE__) @@ -639,6 +682,19 @@ const char *osmo_escape_str(const char *str, int in_len)  	return osmo_escape_str_buf(str, in_len, namebuf, sizeof(namebuf));  } +/*! Return the string with all non-printable characters escaped, in dynamically-allocated buffer. + * \param[in] str  A string that may contain any characters. + * \param[in] len  Pass -1 to print until nul char, or >= 0 to force a length. + * \returns dynamically-allocated output buffer, containing an escaped representation + */ +char *osmo_escape_str_c(const void *ctx, const char *str, int in_len) +{ +	char *buf = talloc_size(ctx, in_len+1); +	if (!buf) +		return NULL; +	return osmo_escape_str_buf(str, in_len, buf, in_len+1); +} +  /*! Like osmo_escape_str(), but returns double-quotes around a string, or "NULL" for a NULL string.   * This allows passing any char* value and get its C representation as string.   * \param[in] str  A string that may contain any characters. @@ -671,6 +727,20 @@ const char *osmo_quote_str(const char *str, int in_len)  	return osmo_quote_str_buf(str, in_len, namebuf, sizeof(namebuf));  } +/*! Like osmo_quote_str_buf() but returns the result in a dynamically-allocated buffer. + * The static buffer is shared with get_value_string() and osmo_escape_str(). + * \param[in] str  A string that may contain any characters. + * \param[in] in_len  Pass -1 to print until nul char, or >= 0 to force a length. + * \returns dynamically-allocated buffer containing a quoted and escaped representation. + */ +char *osmo_quote_str_c(const void *ctx, const char *str, int in_len) +{ +	char *buf = talloc_size(ctx, OSMO_MAX(in_len+2, 32)); +	if (!buf) +		return NULL; +	return osmo_quote_str_buf(str, in_len, buf, 32); +} +  /*! perform an integer square root operation on unsigned 32bit integer.   *  This implementation is taken from "Hacker's Delight" Figure 11-1 "Integer square root, Newton's   *  method", which can also be found at http://www.hackersdelight.org/hdcodetxt/isqrt.c.txt */ @@ -754,6 +824,21 @@ const char *osmo_str_tolower(const char *src)  	return buf;  } +/*! Convert a string to lowercase, dynamically allocating the output from given talloc context + * See also osmo_str_tolower_buf(). + * \param[in] ctx  talloc context from where to allocate the output string + * \param[in] src  String to convert to lowercase. + * \returns Resulting lowercase string in a dynamically allocated buffer, always nul terminated. + */ +char *osmo_str_tolower_c(const void *ctx, const char *src) +{ +	char *buf = talloc_size(ctx, strlen(src)+1); +	if (!buf) +		return NULL; +	osmo_str_tolower_buf(buf, sizeof(buf), src); +	return buf; +} +  /*! Convert a string to uppercase, while checking buffer size boundaries.   * The result written to \a dest is guaranteed to be nul terminated if \a dest_len > 0.   * If dest == src, the string is converted in-place, if necessary truncated at dest_len - 1 characters @@ -797,6 +882,21 @@ const char *osmo_str_toupper(const char *src)  	return buf;  } +/*! Convert a string to uppercase, dynamically allocating the output from given talloc context + * See also osmo_str_tolower_buf(). + * \param[in] ctx  talloc context from where to allocate the output string + * \param[in] src  String to convert to uppercase. + * \returns Resulting uppercase string in a dynamically allocated buffer, always nul terminated. + */ +char *osmo_str_toupper_c(const void *ctx, const char *src) +{ +	char *buf = talloc_size(ctx, strlen(src)+1); +	if (!buf) +		return NULL; +	osmo_str_toupper_buf(buf, sizeof(buf), src); +	return buf; +} +  /*! Calculate the Luhn checksum (as used for IMEIs).   * \param[in] in  Input digits in ASCII string representation.   * \param[in] in_len  Count of digits to use for the input (14 for IMEI). | 
