static int gsmtap_send_sim(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; 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; }
/*! \brief Add a local sink to an existing GSMTAP source instance */ int gsmtap_source_add_sink(struct gsmtap_inst *gti) { int fd; fd = gsmtap_source_add_sink_fd(gsmtap_inst_fd(gti)); if (fd < 0) return fd; if (gti->ofd_wq_mode) { struct osmo_fd *sink_ofd; sink_ofd = >i->sink_ofd; sink_ofd->fd = fd; sink_ofd->when = BSC_FD_READ; sink_ofd->cb = gsmtap_sink_fd_cb; osmo_fd_register(sink_ofd); } return fd; }
/*! \brief Send a \ref msgb through a GSMTAP source * \param[in] gti GSMTAP instance * \param[in] msg message buffer */ int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg) { if (!gti) return -ENODEV; if (gti->ofd_wq_mode) return osmo_wqueue_enqueue(>i->wq, msg); else { /* try immediate send and return error if any */ int rc; rc = write(gsmtap_inst_fd(gti), msg->data, msg->len); if (rc <= 0) { return rc; } else if (rc >= msg->len) { msgb_free(msg); return 0; } else { /* short write */ return -EIO; } } }