#include #include #include #include #include #include #include /*! global GSMTAP instance */ static struct gsmtap_inst *g_gti; /*! initialize the global GSMTAP instance for SIM traces */ int osmo_st2_gsmtap_init(const char *gsmtap_host) { if (g_gti) return -EEXIST; g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0); if (!g_gti) { perror("unable to open GSMTAP"); return -EIO; } gsmtap_source_add_sink(g_gti); return 0; } /*! log one APDU via the global GSMTAP instance. * \param[in] sub_type GSMTAP sub-type (GSMTAP_SIM_* constant) * \param[in] apdu User-provided buffer with APDU to log * \param[in] len Length of apdu in bytes */ int osmo_st2_gsmtap_send_apdu(uint8_t sub_type, const uint8_t *apdu, unsigned int len) { struct gsmtap_hdr *gh; unsigned int gross_len = len + sizeof(*gh); uint8_t *buf = malloc(gross_len); int rc; if (!buf) return -ENOMEM; memset(buf, 0, sizeof(*gh)); gh = (struct gsmtap_hdr *) buf; gh->version = GSMTAP_VERSION; gh->hdr_len = sizeof(*gh)/4; gh->type = GSMTAP_TYPE_SIM; gh->sub_type = sub_type; memcpy(buf + sizeof(*gh), apdu, len); rc = write(gsmtap_inst_fd(g_gti), buf, gross_len); if (rc < 0) { perror("write gsmtap"); free(buf); return rc; } free(buf); return 0; }