/* * With some modems we get offered multiple codecs * and we have selected one of them. It might not * be the right one and we need to detect this with * the first audio packets. One difficulty is that * we patch the rtp payload type in place, so we * need to discuss this. */ struct mgcp_process_rtp_state *check_transcode_state( struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end, struct rtp_hdr *rtp_hdr) { struct mgcp_rtp_end *src_end; /* Only deal with messages from net to bts */ if (&endp->bts_end != dst_end) goto done; src_end = source_for_dest(endp, dst_end); /* Already patched */ if (rtp_hdr->payload_type == dst_end->codec.payload_type) goto done; /* The payload we expect */ if (rtp_hdr->payload_type == src_end->codec.payload_type) goto done; /* The matching alternate payload type? Then switch */ if (rtp_hdr->payload_type == src_end->alt_codec.payload_type) { struct mgcp_config *cfg = endp->cfg; struct mgcp_rtp_codec tmp_codec = src_end->alt_codec; src_end->alt_codec = src_end->codec; src_end->codec = tmp_codec; cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end); cfg->setup_rtp_processing_cb(endp, &endp->bts_end, &endp->net_end); } done: return dst_end->rtp_process_data; }
/* * We don't look at the content of the request yet and lie * about most of the responses. */ static void respond_to(struct sockaddr_in *src, struct osmo_fd *fd, uint8_t *data, size_t len) { static int fetched_info = 0; static char mac_str[20] = {0, }; static char model_name[64] = {0, }; static char ser_str[20] = {0, }; struct sockaddr_in loc_addr; int rc; char loc_ip[INET_ADDRSTRLEN]; struct msgb *msg = msgb_alloc_headroom(512, 128, "ipa get response"); if (!msg) { LOGP(DFIND, LOGL_ERROR, "Failed to allocate msgb\n"); return; } if (!fetched_info) { int fd_eth; int serno; /* fetch the MAC */ fd_eth = open(ETH0_ADDR_SYSFS, O_RDONLY); if (fd_eth >= 0) { read(fd_eth, mac_str, sizeof(mac_str)-1); mac_str[sizeof(mac_str)-1] = '\0'; close(fd_eth); } /* fetch the serial number */ lc15bts_par_get_int(tall_mgr_ctx, LC15BTS_PAR_SERNR, &serno); snprintf(ser_str, sizeof(ser_str), "%d", serno); strncpy(model_name, get_hwversion_desc(), sizeof(model_name)-1); fetched_info = 1; } if (source_for_dest(&src->sin_addr, &loc_addr.sin_addr) != 0) { LOGP(DFIND, LOGL_ERROR, "Failed to determine local source\n"); return; } msgb_put_u8(msg, IPAC_MSGT_ID_RESP); /* append MAC addr */ quirk_l16tv_put(msg, strlen(mac_str) + 1, IPAC_IDTAG_MACADDR, (uint8_t *) mac_str); /* append ip address */ inet_ntop(AF_INET, &loc_addr.sin_addr, loc_ip, sizeof(loc_ip)); quirk_l16tv_put(msg, strlen(loc_ip) + 1, IPAC_IDTAG_IPADDR, (uint8_t *) loc_ip); /* append the serial number */ quirk_l16tv_put(msg, strlen(ser_str) + 1, IPAC_IDTAG_SERNR, (uint8_t *) ser_str); /* abuse some flags */ quirk_l16tv_put(msg, strlen(model_name) + 1, IPAC_IDTAG_UNIT, (uint8_t *) model_name); /* ip.access nanoBTS would reply to port==3006 */ ipaccess_prepend_header_quirk(msg, IPAC_PROTO_IPACCESS); rc = sendto(fd->fd, msg->data, msg->len, 0, (struct sockaddr *)src, sizeof(*src)); if (rc != msg->len) LOGP(DFIND, LOGL_ERROR, "Failed to send with rc(%d) errno(%d)\n", rc, errno); }