aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/core/msgb.h26
-rw-r--r--include/osmocom/core/socket.h1
-rw-r--r--include/osmocom/core/utils.h6
-rw-r--r--include/osmocom/gprs/gprs_ns.h1
-rw-r--r--include/osmocom/gsm/abis_nm.h1
-rw-r--r--include/osmocom/gsm/apn.h2
-rw-r--r--include/osmocom/gsm/gsm0808_utils.h5
-rw-r--r--include/osmocom/gsm/gsm23003.h6
-rw-r--r--include/osmocom/gsm/gsm48.h2
-rw-r--r--include/osmocom/gsm/gsm_utils.h1
-rw-r--r--include/osmocom/gsm/protocol/gsm_04_08.h2
-rw-r--r--include/osmocom/gsm/rsl.h1
-rw-r--r--include/osmocom/sim/sim.h1
-rw-r--r--src/gb/gprs_ns.c8
-rw-r--r--src/gb/libosmogb.map1
-rw-r--r--src/gsm/abis_nm.c9
-rw-r--r--src/gsm/apn.c16
-rw-r--r--src/gsm/gsm0808_utils.c40
-rw-r--r--src/gsm/gsm23003.c78
-rw-r--r--src/gsm/gsm48.c59
-rw-r--r--src/gsm/gsm_utils.c7
-rw-r--r--src/gsm/libosmogsm.map20
-rw-r--r--src/gsm/rsl.c13
-rw-r--r--src/msgb.c57
-rw-r--r--src/sim/core.c8
-rw-r--r--src/socket.c14
-rw-r--r--src/utils.c100
27 files changed, 474 insertions, 11 deletions
diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h
index 0c51ce2..e05d37f 100644
--- a/include/osmocom/core/msgb.h
+++ b/include/osmocom/core/msgb.h
@@ -60,6 +60,7 @@ struct msgb {
unsigned char _data[0]; /*!< optional immediate data array */
};
+extern struct msgb *msgb_alloc_c(const void *ctx, uint16_t size, const char *name);
extern struct msgb *msgb_alloc(uint16_t size, const char *name);
extern void msgb_free(struct msgb *m);
extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
@@ -68,9 +69,11 @@ 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);
+char *msgb_hexdump_c(const void *ctx, 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);
+extern struct msgb *msgb_copy_c(const void *ctx, const struct msgb *msg, const char *name);
static int msgb_test_invariant(const struct msgb *msg) __attribute__((pure));
/*! Free all msgbs from a queue built with msgb_enqueue().
@@ -501,6 +504,29 @@ static inline int msgb_l3trim(struct msgb *msg, int l3len)
return msgb_trim(msg, (msg->l3h - msg->data) + l3len);
}
+/*! Allocate message buffer with specified headroom from specified talloc context.
+ * \param[in] ctx talloc context from which to allocate
+ * \param[in] size size in bytes, including headroom
+ * \param[in] headroom headroom in bytes
+ * \param[in] name human-readable name
+ * \returns allocated message buffer with specified headroom
+ *
+ * This function is a convenience wrapper around \ref msgb_alloc
+ * followed by \ref msgb_reserve in order to create a new \ref msgb with
+ * user-specified amount of headroom.
+ */
+static inline struct msgb *msgb_alloc_headroom_c(const void *ctx, int size, int headroom,
+ const char *name)
+{
+ osmo_static_assert(size > headroom, headroom_bigger);
+
+ struct msgb *msg = msgb_alloc_c(ctx, size, name);
+ if (msg)
+ msgb_reserve(msg, headroom);
+ return msg;
+}
+
+
/*! Allocate message buffer with specified headroom
* \param[in] size size in bytes, including headroom
* \param[in] headroom headroom in bytes
diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index 4f6ed72..37b1eae 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -68,6 +68,7 @@ int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
char *osmo_sock_get_name(const void *ctx, int fd);
const char *osmo_sock_get_name2(int fd);
+char *osmo_sock_get_name2_c(const void *ctx, int fd);
int osmo_sock_get_name_buf(char *str, size_t str_len, int fd);
int osmo_sock_get_ip_and_port(int fd, char *ip, size_t ip_len, char *port, size_t port_len, bool local);
int osmo_sock_get_local_ip(int fd, char *host, size_t len);
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 6a2b7d5..51e43ee 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -56,7 +56,9 @@ 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_c(const void *ctx, const unsigned char *buf, int len);
char *osmo_hexdump_nospc(const unsigned char *buf, int len);
+char *osmo_hexdump_nospc_c(const void *ctx, const unsigned char *buf, int len);
const char *osmo_hexdump_buf(char *out_buf, size_t out_buf_size, const unsigned char *buf, int len, const char *delim,
bool delim_after_last);
@@ -73,9 +75,11 @@ void osmo_str2upper(char *out, const char *in)
size_t osmo_str_tolower_buf(char *dest, size_t dest_len, const char *src);
const char *osmo_str_tolower(const char *src);
+char *osmo_str_tolower_c(const void *ctx, const char *src);
size_t osmo_str_toupper_buf(char *dest, size_t dest_len, const char *src);
const char *osmo_str_toupper(const char *src);
+char *osmo_str_toupper_c(const void *ctx, const char *src);
#define OSMO_SNPRINTF_RET(ret, rem, offset, len) \
do { \
@@ -139,8 +143,10 @@ 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);
+char *osmo_escape_str_c(const void *ctx, const char *str, int in_len);
const char *osmo_quote_str(const char *str, int in_len);
char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize);
+char *osmo_quote_str_c(const void *ctx, const char *str, int in_len);
uint32_t osmo_isqrt32(uint32_t x);
diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h
index ed155ff..02faa50 100644
--- a/include/osmocom/gprs/gprs_ns.h
+++ b/include/osmocom/gprs/gprs_ns.h
@@ -213,6 +213,7 @@ int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
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);
+char *gprs_ns_ll_str_c(const void *ctx, 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 788727c..ab5a5d5 100644
--- a/include/osmocom/gsm/abis_nm.h
+++ b/include/osmocom/gsm/abis_nm.h
@@ -43,6 +43,7 @@ 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);
+char *abis_nm_dump_foh_c(void *ctx, 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 7899bb2..ab5f493 100644
--- a/include/osmocom/gsm/apn.h
+++ b/include/osmocom/gsm/apn.h
@@ -12,6 +12,7 @@
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);
+char *osmo_apn_qualify_c(const void *ctx, 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. */
@@ -19,6 +20,7 @@ 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);
+char *osmo_apn_qualify_from_imsi_c(const void *ctx, 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 e246967..47c4e95 100644
--- a/include/osmocom/gsm/gsm0808_utils.h
+++ b/include/osmocom/gsm/gsm0808_utils.h
@@ -70,6 +70,7 @@ 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_lcls_dump_c(void *ctx, 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);
@@ -79,8 +80,11 @@ static inline const char *gsm0808_cell_id_discr_name(enum CELL_IDENT id_discr)
const char *gsm0808_cell_id_name(const struct gsm0808_cell_id *cid);
const char *gsm0808_cell_id_name2(const struct gsm0808_cell_id *cid);
+char *gsm0808_cell_id_name_buf(char *buf, size_t buflen, const struct gsm0808_cell_id *cid);
+char *gsm0808_cell_id_name_c(const void *ctx, const struct gsm0808_cell_id *cid);
const char *gsm0808_cell_id_list_name(const struct gsm0808_cell_id_list2 *cil);
int gsm0808_cell_id_list_name_buf(char *buf, size_t buflen, const struct gsm0808_cell_id_list2 *cil);
+char *gsm0808_cell_id_list_name_c(const void *ctx, const struct gsm0808_cell_id_list2 *cil);
int gsm0808_cell_id_u_name(char *buf, size_t buflen,
enum CELL_IDENT id_discr, const union gsm0808_cell_id_u *u);
bool gsm0808_cell_ids_match(const struct gsm0808_cell_id *id1, const struct gsm0808_cell_id *id2, bool exact_match);
@@ -254,5 +258,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);
+char *gsm0808_channel_type_name_c(const void *ctx, const struct gsm0808_channel_type *ct);
/*! @} */
diff --git a/include/osmocom/gsm/gsm23003.h b/include/osmocom/gsm/gsm23003.h
index 88c4f3c..69f00f6 100644
--- a/include/osmocom/gsm/gsm23003.h
+++ b/include/osmocom/gsm/gsm23003.h
@@ -106,18 +106,24 @@ 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_mcc_name_c(const void *ctx, 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);
+char *osmo_mnc_name_c(const void *ctx, 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);
+char *osmo_plmn_name_c(const void *ctx, 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);
+char *osmo_lai_name_c(const void *ctx, 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);
+char *osmo_cgi_name_c(const void *ctx, 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);
+char *osmo_gummei_name_c(const void *ctx, 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 81b2bf0..786fbc9 100644
--- a/include/osmocom/gsm/gsm48.h
+++ b/include/osmocom/gsm/gsm48.h
@@ -36,6 +36,7 @@ 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);
+char *osmo_rai_name_c(const void *ctx, 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)
@@ -57,6 +58,7 @@ int gsm48_mi_to_string(char *string, const int str_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);
+char *osmo_mi_name_c(const void *ctx, 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 f48cc68..37df665 100644
--- a/include/osmocom/gsm/gsm_utils.h
+++ b/include/osmocom/gsm/gsm_utils.h
@@ -181,6 +181,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);
+char *osmo_dump_gsmtime_c(const void *ctx, 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 c97df16..16910c3 100644
--- a/include/osmocom/gsm/protocol/gsm_04_08.h
+++ b/include/osmocom/gsm/protocol/gsm_04_08.h
@@ -71,6 +71,7 @@ bool osmo_gsm48_classmark2_is_r99(const struct gsm48_classmark2 *cm2, uint8_t cm
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);
+char *osmo_gsm48_classmark_a5_name_c(const void *ctx, 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 */
@@ -1645,6 +1646,7 @@ 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);
+char *gsm48_pdisc_msgtype_name_c(const void *ctx, 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 4a1da3a..285dbc2 100644
--- a/include/osmocom/gsm/rsl.h
+++ b/include/osmocom/gsm/rsl.h
@@ -32,6 +32,7 @@ int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *tim
/* 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);
+char *rsl_chan_nr_str_c(const void *ctx, uint8_t chan_nr);
const char *rsl_err_name(uint8_t err);
diff --git a/include/osmocom/sim/sim.h b/include/osmocom/sim/sim.h
index 0490dcd..2bc4715 100644
--- a/include/osmocom/sim/sim.h
+++ b/include/osmocom/sim/sim.h
@@ -298,6 +298,7 @@ enum osim_card_sw_class osim_sw_class(const struct osim_card_profile *cp,
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);
+char *osim_print_sw_c(const void *ctx, const struct osim_card_hdl *ch, uint16_t sw_in);
extern const struct tlv_definition ts102221_fcp_tlv_def;
extern const struct value_string ts102221_fcp_vals[14];
diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c
index fc120ce..d72003e 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 21929da..5e675a6 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 e25fdd0..a4c0e41 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 4ab370c..88b45a4 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 52e4674..99cf188 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 bbfe236..2252f70 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 a45d67b..c2c19cf 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 f2bf57b..1450ed0 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 a69fb60..56481fd 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 7bc6002..1777479 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" },
diff --git a/src/msgb.c b/src/msgb.c
index 47b413b..5a154e5 100644
--- a/src/msgb.c
+++ b/src/msgb.c
@@ -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 998e836..63b3000 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 3a46ad0..c817e72 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 4796365..b8b4ef5 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).