TEST(chunk, decode_message) { struct mbuf *mb_chunked = mbuf_alloc(1024); struct mbuf *mb_data = mbuf_alloc(1024); int err = 0; ASSERT_TRUE(mb_chunked != NULL); ASSERT_TRUE(mb_data != NULL); mbuf_write_str(mb_chunked, encoded_data); mb_chunked->pos = 0; /* decode all chunks */ for (int i=0; i<16; i++) { uint8_t *p; size_t n; err = chunk_decode(&p, &n, mb_chunked); if (err) break; if (n == 0) break; err = mbuf_write_mem(mb_data, p, n); if (err) break; } ASSERT_EQ(str_len(decoded_data), mb_data->end); ASSERT_TRUE(0 == memcmp(decoded_data, mb_data->buf, mb_data->end)); mem_deref(mb_chunked); mem_deref(mb_data); }
/** * Load configuration from file * * @param confp Configuration object to be allocated * @param filename Name of configuration file * * @return 0 if success, otherwise errorcode */ int conf_alloc(struct conf **confp, const char *filename) { struct conf *conf; int err = 0; if (!confp) return EINVAL; conf = mem_zalloc(sizeof(*conf), conf_destructor); if (!conf) return ENOMEM; conf->mb = mbuf_alloc(1024); if (!conf->mb) { err = ENOMEM; goto out; } err |= mbuf_write_u8(conf->mb, '\n'); if (filename) err |= load_file(conf->mb, filename); out: if (err) mem_deref(conf); else *confp = conf; return err; }
static int send_bye_packet(struct rtcp_sess *sess) { const uint32_t ssrc = rtp_sess_ssrc(sess->rs); struct mbuf *mb; int err; mb = mbuf_alloc(512); if (!mb) return ENOMEM; mb->pos = RTCP_HEADROOM; err = rtcp_encode(mb, RTCP_BYE, 1, &ssrc, "Adjo"); err |= mk_sdes(sess, mb); if (err) goto out; mb->pos = RTCP_HEADROOM; err = rtcp_send(sess->rs, mb); out: mem_deref(mb); return err; }
/** * Send a STUN response message * * @param proto Transport Protocol * @param sock Socket; UDP (struct udp_sock) or TCP (struct tcp_conn) * @param dst Destination network address * @param presz Number of bytes in preamble, if sending over TURN * @param req Matching STUN request * @param key Authentication key (optional) * @param keylen Number of bytes in authentication key * @param fp Use STUN Fingerprint attribute * @param attrc Number of attributes to encode (variable arguments) * @param ... Variable list of attribute-tuples * Each attribute has 2 arguments, attribute type and value * * @return 0 if success, otherwise errorcode */ int stun_reply(int proto, void *sock, const struct sa *dst, size_t presz, const struct stun_msg *req, const uint8_t *key, size_t keylen, bool fp, uint32_t attrc, ...) { struct mbuf *mb = NULL; int err = ENOMEM; va_list ap; if (!sock || !req) return EINVAL; mb = mbuf_alloc(256); if (!mb) goto out; va_start(ap, attrc); mb->pos = presz; err = stun_msg_vencode(mb, stun_msg_method(req), STUN_CLASS_SUCCESS_RESP, stun_msg_tid(req), NULL, key, keylen, fp, 0x00, attrc, ap); va_end(ap); if (err) goto out; mb->pos = presz; err = stun_send(proto, sock, dst, mb); out: mem_deref(mb); return err; }
int call_notify_sipfrag(struct call *call, uint16_t scode, const char *reason, ...) { struct mbuf *mb; va_list ap; int err; if (!call) return EINVAL; mb = mbuf_alloc(512); if (!mb) return ENOMEM; va_start(ap, reason); (void)mbuf_printf(mb, "SIP/2.0 %u %v\n", scode, reason, &ap); va_end(ap); mb->pos = 0; if (scode >= 200) { err = sipevent_notify(call->not, mb, SIPEVENT_TERMINATED, SIPEVENT_NORESOURCE, 0); call->not = mem_deref(call->not); } else { err = sipevent_notify(call->not, mb, SIPEVENT_ACTIVE, SIPEVENT_NORESOURCE, 0); } mem_deref(mb); return err; }
//read from auth server int cb_read_auth(struct epoll_event *ev, struct sockinfo *si) { int ret, szhdr = sizeof(dnsheader); mbuf_type *mbuf = mbuf_alloc(); if (NULL == mbuf) return -1; memset(mbuf, 0, sizeof(mbuf_type)); mbuf->fd = ev->data.fd; mbuf->buf = si->buf; mbuf->buflen = BIG_MEM_STEP; mbuf->addr = &(mbuf->aaddr); if (si->socktype == TCP) ret = tcp_read_dns_msg(mbuf, MBUF_DATA_LEN - 2, 0); else ret = udp_read_msg(mbuf, 0); //epoll return and no blocked here if (ret < szhdr) { mbuf_free(mbuf); return -1; } si->buflen = mbuf->buflen = ret; si->mbuf = mbuf; return ret; }
static int on_send_packet(const zrtp_stream_t *stream, char *rtp_packet, unsigned int rtp_packet_length) { struct menc_media *st = zrtp_stream_get_userdata(stream); struct mbuf *mb; int err; if (drop_packets(st)) return zrtp_status_ok; if (!sa_isset(&st->raddr, SA_ALL)) return zrtp_status_ok; mb = mbuf_alloc(PRESZ + rtp_packet_length); if (!mb) return zrtp_status_alloc_fail; mb->pos = PRESZ; (void)mbuf_write_mem(mb, (void *)rtp_packet, rtp_packet_length); mb->pos = PRESZ; err = udp_send_helper(st->rtpsock, &st->raddr, mb, st->uh_rtp); if (err) { warning("zrtp: udp_send %u bytes (%m)\n", rtp_packet_length, err); } mem_deref(mb); return zrtp_status_ok; }
static int test_rtcp_decode_badmsg(void) { struct rtcp_msg *msg = NULL; uint32_t ssrc = 0xcafebabe; struct mbuf *mb; int err = 0; mb = mbuf_alloc(128); if (!mb) { err = ENOMEM; goto out; } err = rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_SLI, ssrc, ssrc, NULL, NULL); if (err) goto out; /* simulate a corrupt RTCP packet */ mb->pos = 2; (void)mbuf_write_u16(mb, htons(0)); mb->pos = 0; if (EBADMSG != rtcp_decode(&msg, mb)) { err = EBADMSG; goto out; } out: mem_deref(msg); mem_deref(mb); return err; }
static int bio_write(BIO *b, const char *buf, int len) { struct dtls_flow *tc = b->ptr; struct mbuf *mb; enum {SPACE = 4}; /* sizeof TURN channel header */ int err; mb = mbuf_alloc(SPACE + len); if (!mb) return -1; (void)mbuf_fill(mb, 0x00, SPACE); (void)mbuf_write_mem(mb, (void *)buf, len); mb->pos = SPACE; err = udp_send_helper(tc->us, &tc->peer, mb, tc->uh); if (err) { warning("dtls: udp_send_helper: %m\n", err); } mem_deref(mb); return err ? -1 : len; }
static int parse_msg(const uint8_t *p, size_t n) { struct mbuf *mb = mbuf_alloc(512); int err; if (!mb) return ENOMEM; err = mbuf_write_mem(mb, p, n); if (err) return err; mb->pos = 0; while (mbuf_get_left(mb) >= 4) { struct bfcp_msg *msg; err = bfcp_msg_decode(&msg, mb); if (err) break; mem_deref(msg); } mem_deref(mb); return err; }
static void estab_handler(void *arg) { struct rst *rst = arg; struct mbuf *mb; int err; re_printf("rst: connection established\n"); mb = mbuf_alloc(512); if (!mb) { err = ENOMEM; goto out; } err = mbuf_printf(mb, "GET %s HTTP/1.0\r\n" "Icy-MetaData: 1\r\n" "\r\n", rst->path); if (err) goto out; mb->pos = 0; err = tcp_send(rst->tc, mb); if (err) goto out; out: if (err) { re_printf("rst: error sending HTTP request: %m\n", err); } mem_deref(mb); }
static int output_handler(const char *str) { struct mbuf *mb; int err = 0; if (!str) return EINVAL; mb = mbuf_alloc(256); if (!mb) return ENOMEM; mbuf_write_str(mb, str); if (sa_isset(&cons->udp_peer, SA_ALL)) { mb->pos = 0; err |= udp_send(cons->us, &cons->udp_peer, mb); } if (cons->tc) { mb->pos = 0; err |= tcp_send(cons->tc, mb); } mem_deref(mb); return err; }
/** * Send SIP OPTIONS message to a peer * * @param ua User-Agent object * @param uri Peer SIP Address * @param resph Response handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int ua_options_send(struct ua *ua, const char *uri, options_resp_h *resph, void *arg) { struct mbuf *dialbuf; int err = 0; (void)arg; if (!ua || !str_isset(uri)) return EINVAL; dialbuf = mbuf_alloc(64); if (!dialbuf) return ENOMEM; err |= uri_complete(ua, dialbuf, uri); dialbuf->buf[dialbuf->end] = '\0'; err = sip_req_send(ua, "OPTIONS", (char *)dialbuf->buf, resph, NULL, "Accept: application/sdp\r\n" "Content-Length: 0\r\n" "\r\n"); if (err) { warning("ua: send options: (%m)\n", err); } mem_deref(dialbuf); return err; }
static void udp_recv(const struct sa *src, struct mbuf *mb, void *arg) { struct ui_st *st = arg; struct mbuf *mbr = mbuf_alloc(64); struct re_printf pf; st->udp_peer = *src; pf.vph = print_handler; pf.arg = mbr; while (mbuf_get_left(mb)) { char ch = mbuf_read_u8(mb); if (ch == '\r') ch = '\n'; ui_input_key(ch, &pf); } if (mbr->end > 0) { mbr->pos = 0; (void)udp_send(st->us, src, mbr); } mem_deref(mbr); }
/** * Play an audio file in WAV format * * @param playp Pointer to allocated player object * @param filename Name of WAV file to play * @param repeat Number of times to repeat * * @return 0 if success, otherwise errorcode */ int play_file(struct play **playp, const char *filename, int repeat) { struct mbuf *mb; char path[256]; uint32_t srate; uint8_t ch; int err; if (playp && *playp) return EALREADY; #ifndef PREFIX #define PREFIX "/usr" #endif if (re_snprintf(path, sizeof(path), PREFIX "/share/baresip/%s", filename) < 0) return ENOMEM; mb = mbuf_alloc(1024); if (!mb) return ENOMEM; err = aufile_load(mb, path, &srate, &ch); if (err) { DEBUG_WARNING("%s: %m\n", path, err); goto out; } err = play_tone(playp, mb, srate, ch, repeat); out: mem_deref(mb); return err; }
int test_rtcp_decode(void) { struct rtcp_msg *msg = NULL; struct mbuf *mb; int err = 0; mb = mbuf_alloc(512); if (!mb) return ENOMEM; err |= mbuf_write_u8(mb, 0x55); /* overhead -- test padding */ err |= mbuf_write_mem(mb, rtcp_sdes, sizeof(rtcp_sdes)); err |= mbuf_write_u8(mb, 0xaa); /* junk */ mb->pos = 1; while (mbuf_get_left(mb) >= 4 && !err) { err = rtcp_decode(&msg, mb); msg = mem_deref(msg); } mem_deref(msg); mem_deref(mb); if (err) return err; err = test_rtcp_decode_badmsg(); if (err) return err; return err; }
static struct mbuf *mbuf_load_file(const char *filename) { struct mbuf *mb = mbuf_alloc(2048); int err = 0, fd = open(filename, O_RDONLY); if (fd < 0) { warning("could not open '%s' (%m)\n", filename, errno); return 0; } for (;;) { uint8_t buf[1024]; const ssize_t n = read(fd, (void *)buf, sizeof(buf)); if (n < 0) { err = errno; break; } else if (n == 0) break; err |= mbuf_write_mem(mb, buf, n); } (void)close(fd); if (err) return NULL; mb->pos = 0; return mb; }
static int read_file(struct ausrc_st *st) { struct mbuf *mb; int err; for (;;) { mb = mbuf_alloc(4096); if (!mb) return ENOMEM; mb->end = mb->size; err = aufile_read(st->aufile, mb->buf, &mb->end); if (err) break; if (mb->end == 0) { info("aufile: end of file\n"); break; } aubuf_append(st->aubuf, mb); mb = mem_deref(mb); } info("aufile: loaded %zu bytes\n", aubuf_cur_size(st->aubuf)); mem_deref(mb); return err; }
int h265_decode_update(struct viddec_state **vdsp, const struct vidcodec *vc, const char *fmtp) { struct viddec_state *vds; AVCodec *codec; int err = 0; (void)vc; (void)fmtp; if (!vdsp) return EINVAL; vds = *vdsp; if (vds) return 0; /* HEVC = H.265 */ codec = avcodec_find_decoder(AV_CODEC_ID_HEVC); if (!codec) { warning("h265: could not find H265 decoder\n"); return ENOSYS; } vds = mem_zalloc(sizeof(*vds), destructor); if (!vds) return ENOMEM; vds->mb = mbuf_alloc(1024); if (!vds->mb) { err = ENOMEM; goto out; } vds->pict = av_frame_alloc(); if (!vds->pict) { err = ENOMEM; goto out; } vds->ctx = avcodec_alloc_context3(codec); if (!vds->ctx) { err = ENOMEM; goto out; } if (avcodec_open2(vds->ctx, codec, NULL) < 0) { err = ENOMEM; goto out; } out: if (err) mem_deref(vds); else *vdsp = vds; return err; }
int test_rtcp_encode(void) { struct mbuf *mb; const size_t sz = sizeof(rtcp_msg) - 1; const uint32_t srcv[2] = {0x12345678, 0x00abcdef}; int err = 0; mb = mbuf_alloc(512); if (!mb) return ENOMEM; err |= rtcp_encode(mb, RTCP_SR, 1, 0x12345678, 0x00112233, 0x44556677, 0x22332233, 0x00001111, 0x00002222, encode_handler, 0); err |= rtcp_encode(mb, RTCP_RR, 1, 0x12345678, encode_handler, 0); err |= rtcp_encode(mb, RTCP_SDES, 1, sdes_encode_handler, 0); err |= rtcp_encode(mb, RTCP_BYE, 2, srcv, "ciao"); err |= rtcp_encode(mb, RTCP_APP, 0, 0x12345678, "name", "data", (size_t)4); err |= rtcp_encode(mb, RTCP_FIR, 0, 0x12345678); err |= rtcp_encode(mb, RTCP_NACK, 0, 0x12345678, 0x89ab, 0xcdef); err |= rtcp_encode(mb, RTCP_RTPFB, RTCP_RTPFB_GNACK, 0x12345678, 0xfedcba98, gnack_encode, 0); err |= rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_PLI, 0x12345678, 0xfedcba98, NULL, 0); err |= rtcp_encode(mb, RTCP_PSFB, RTCP_PSFB_SLI, 0x12345678, 0xfedcba98, sli_encode, 0); if (err) goto out; if (mb->end != sz) { err = EPROTO; } if (0 != memcmp(mb->buf, rtcp_msg, mb->end)) { err = EBADMSG; } if (err) { DEBUG_WARNING("encode error: %m\n", err); hexdump(stderr, mb->buf, mb->end); } mb->pos = 0; while (mbuf_get_left(mb) >= 4 && !err) { struct rtcp_msg *msg = NULL; err = rtcp_decode(&msg, mb); msg = mem_deref(msg); } if (err) goto out; /* verify that rtcp_decode() read the whole buffer */ TEST_EQUALS(mb->end, mb->pos); out: mem_deref(mb); return err; }
static void * gossip_loop(void *arg) { struct server_pool *sp = arg; uint64_t gossip_interval = gn_pool.g_interval * 1000; seeds_buf = mbuf_alloc(SEED_BUF_SIZE); log_debug(LOG_VVERB, "gossip_interval : %d msecs", gn_pool.g_interval); for(;;) { usleep(gossip_interval); log_debug(LOG_VERB, "Gossip is running ..."); if (gn_pool.seeds_provider != NULL && gn_pool.seeds_provider(sp->ctx, seeds_buf) == DN_OK) { log_debug(LOG_VERB, "Got seed nodes '%.*s'", mbuf_length(seeds_buf), seeds_buf->pos); gossip_update_seeds(sp, seeds_buf); } current_node->ts = (uint64_t) time(NULL); gossip_process_msgs(); if (current_node->state == NORMAL) { gn_pool.ctx->dyn_state = NORMAL; } if (!sp->ctx->enable_gossip) { //gossip_debug(); continue; //no gossiping } if (node_count == 1) { //single node deployment gn_pool.ctx->dyn_state = NORMAL; continue; } //STANDBY state for warm bootstrap if (gn_pool.ctx->dyn_state == STANDBY) continue; if (gn_pool.ctx->dyn_state == JOINING) { log_debug(LOG_NOTICE, "I am still joining the ring!"); //aggressively contact all known nodes before changing to state NORMAL gossip_announce_joining(sp); usleep(MAX(gn_pool.ctx->timeout, gossip_interval) * 2); } else if (gn_pool.ctx->dyn_state == NORMAL) { gossip_forward_state(sp); } gossip_debug(); } //end for loop mbuf_dealloc(seeds_buf); seeds_buf = NULL; return NULL; }
static int read_stream_open(struct ausrc_st *st, const struct ausrc_prm *prm, unsigned int dev) { WAVEFORMATEX wfmt; MMRESULT res; uint32_t sampc; unsigned format; int i, err = 0; st->sampsz = aufmt_sample_size(prm->fmt); format = winwave_get_format(prm->fmt); if (format == WAVE_FORMAT_UNKNOWN) { warning("winwave: source: unsupported sample format (%s)\n", aufmt_name(prm->fmt)); return ENOTSUP; } /* Open an audio INPUT stream. */ st->wavein = NULL; st->pos = 0; st->rdy = false; sampc = prm->srate * prm->ch * prm->ptime / 1000; for (i = 0; i < READ_BUFFERS; i++) { memset(&st->bufs[i].wh, 0, sizeof(WAVEHDR)); st->bufs[i].mb = mbuf_alloc(st->sampsz * sampc); if (!st->bufs[i].mb) return ENOMEM; } wfmt.wFormatTag = format; wfmt.nChannels = prm->ch; wfmt.nSamplesPerSec = prm->srate; wfmt.wBitsPerSample = (WORD)(st->sampsz * 8); wfmt.nBlockAlign = (prm->ch * wfmt.wBitsPerSample) / 8; wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign; wfmt.cbSize = 0; res = waveInOpen(&st->wavein, dev, &wfmt, (DWORD_PTR) waveInCallback, (DWORD_PTR) st, CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT); if (res != MMSYSERR_NOERROR) { warning("winwave: waveInOpen: failed res=%d\n", res); return EINVAL; } /* Prepare enough IN buffers to suite at least 50ms of data */ for (i = 0; i < READ_BUFFERS; i++) err |= add_wave_in(st); waveInStart(st->wavein); return err; }
/** * Send a SIP request with formatted arguments * * @param reqp Pointer to allocated SIP request object * @param sip SIP Stack * @param stateful Stateful client transaction * @param met Null-terminated SIP Method string * @param uri Null-terminated Request URI string * @param route Next hop route URI (optional) * @param auth SIP authentication state * @param sendh Send handler * @param resph Response handler * @param arg Handler argument * @param fmt Formatted SIP headers * * @return 0 if success, otherwise errorcode */ int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful, const char *met, const char *uri, const struct uri *route, struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph, void *arg, const char *fmt, ...) { struct uri lroute; struct mbuf *mb; va_list ap; int err; if (!sip || !met || !uri || !fmt) return EINVAL; if (!route) { struct pl uripl; pl_set_str(&uripl, uri); err = uri_decode(&lroute, &uripl); if (err) return err; route = &lroute; } mb = mbuf_alloc(2048); if (!mb) return ENOMEM; err = mbuf_write_str(mb, "Max-Forwards: 70\r\n"); if (auth) err |= sip_auth_encode(mb, auth, met, uri); if (err) goto out; va_start(ap, fmt); err = mbuf_vprintf(mb, fmt, ap); va_end(ap); if (err) goto out; mb->pos = 0; err = sip_request(reqp, sip, stateful, met, -1, uri, -1, route, mb, sendh, resph, arg); if (err) goto out; out: mem_deref(mb); return err; }
void tcp_conn::recv() { struct mbuf *mb; struct le *le; bool hlp_estab = false; int err = 0; DEBUG_INFO("TCP Receive %u bytes\n", ctc->iBufRx.Length()); /* If no memory packet will be dropped */ mb = mbuf_alloc(ctc->iBufRx.Length()); if (mb) { (void)mbuf_write_mem(mb, (uint8_t *)ctc->iBufRx.Ptr(), ctc->iBufRx.Length()); mb->pos = 0; } ctc->StartReceiving(); if (!mb) goto out; le = list_head(&helpers); while (le) { struct tcp_helper *th; bool hdld; th = (struct tcp_helper *)le->data; le = le->next; if (!hlp_estab) hdld = th->recvh(&err, mb, &hlp_estab, arg); else hdld = th->estabh(&err, active, arg); if (hdld || err) { if (err) conn_close(err); goto out; } } mbuf_trim(mb); if (!hlp_estab) { if (recvh) recvh(mb, arg); } else { if (estabh) estabh(arg); } out: mem_deref(mb); }
static void tcp_recv_handler(struct mbuf *mb, void *arg) { struct request *request = arg; int ok; struct pl ver; struct pl code; struct pl phrase; struct pl headers; struct pl body; DEBUG_INFO("recv data[%d]\n", mbuf_get_left(mb)); if(request->state == STREAM) { request->stream_h(request, HTTP_STREAM_DATA, mb, request->arg); return; } if(request->body) { ok = mbuf_write_mem(request->body, mbuf_buf(mb), mbuf_get_left(mb)); goto clen; } ok = re_regex((const char*)mbuf_buf(mb), mbuf_get_left(mb), "HTTP/[^ \t\r\n]+ [0-9]+ [^\t\r\n]+\r\n[^]1", &ver, &code, &phrase, &headers); // XXX: check ok // XXX: check headers.l request->status = pl_u32(&code); headers.l = mbuf_get_left(mb) - (headers.p - (const char*)mbuf_buf(mb)); body.l = 0; parse_headers(request, (char*)headers.p, headers.l, &body); if(body.l) { request->body = mbuf_alloc(body.l); mbuf_write_mem(request->body, (const unsigned char*)body.p, body.l); } request->response = mem_ref(mb); clen: if(request->body && request->clen > request->body->end) return; if(request->status >= 200 || request->stream_h == NULL) { request->done_h(request, request->status, request->arg); request->state = END; mem_deref(request); return; } request->state = STREAM; request->stream_h(request, HTTP_STREAM_EST, mb, request->arg); }
static void tcp_estab_handler(void *arg) { DEBUG_INFO("connection established\n"); int ok; struct request * request = arg; struct mbuf *mb; char CN[256]; if(request->secure) { ok = tls_verify_cert(request->ssl, CN, sizeof(CN)); if(ok!=0) goto fail; DEBUG_INFO("https CN %s\n", CN); ok = strcmp(request->host, CN); if(ok!=0) goto fail; } mb = mbuf_alloc(1024); mbuf_printf(mb, "%s %s HTTP/1.1\r\n", request->meth, request->path); mbuf_printf(mb, "Host: %s\r\n", request->host); write_auth(request, mb); mbuf_write_str(mb, "Connection: close\r\n"); hash_apply(request->hdrht, hdr_write, mb); hash_flush(request->hdrht); if(request->post) { request->post->pos = 0; mbuf_printf(mb, "Content-Length: %d\r\n", mbuf_get_left(request->post)); if(request->form) mbuf_printf(mb, "Content-Type: " "application/x-www-form-urlencoded\r\n"); mbuf_printf(mb, "\r\n"); mbuf_write_mem(mb, mbuf_buf(request->post), mbuf_get_left(request->post)); } else { mbuf_write_str(mb, "\r\n"); } mb->pos = 0; tcp_send(request->tcp, mb); mem_deref(mb); return; fail: DEBUG_WARNING("ssl fail %p %d\n", request->app->tls, ok); }
static int src_alloc(struct ausrc_st **stp, struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; int err; (void)ctx; (void)errh; st = mem_zalloc(sizeof(*st), ausrc_destructor); if (!st) return ENOMEM; st->fd = -1; st->rh = rh; st->errh = errh; st->arg = arg; if (!device) device = oss_dev; prm->fmt = AUFMT_S16LE; st->mb = mbuf_alloc(2 * prm->frame_size); if (!st->mb) { err = ENOMEM; goto out; } st->fd = open(device, O_RDONLY); if (st->fd < 0) { err = errno; goto out; } err = fd_listen(st->fd, FD_READ, read_handler, st); if (err) goto out; err = oss_reset(st->fd, prm->srate, prm->ch, prm->frame_size, 1); if (err) goto out; st->as = mem_ref(as); out: if (err) mem_deref(st); else *stp = st; return err; }
/** * Test parsing of various SDP messages from various vendors */ int test_sdp_parse(void) { struct sdp_session *sess = NULL; struct sdp_media *audio; struct mbuf *mb; struct sa laddr; uint32_t i; int err; mb = mbuf_alloc(2048); if (!mb) return ENOMEM; sa_init(&laddr, AF_INET); for (i=0; i<ARRAY_SIZE(msgs); i++) { sess = mem_deref(sess); err = sdp_session_alloc(&sess, &laddr); if (err) goto out; err = sdp_media_add(&audio, sess, sdp_media_audio, 5004, sdp_proto_rtpavp); if (err) goto out; err = sdp_format_add(NULL, audio, false, ref_pt, ref_cname, ref_srate, 1, NULL, NULL, NULL, false, NULL); if (err) goto out; err = sdp_format_add(NULL, audio, false, "8", "PCMA", 8000, 1, NULL, NULL, NULL, false, NULL); if (err) goto out; mbuf_rewind(mb); (void)mbuf_write_str(mb, msgs[i]); mb->pos = 0; err = sdp_decode(sess, mb, true); if (err) goto out; } out: mem_deref(sess); mem_deref(mb); return err; }
TEST(chunk, decoder_from_file) { struct chunk_decoder *dec = NULL; struct mbuf *mb2=0, *mb3=0, *mb4, *mb_payload, *mb_ref; int err; err = chunk_decoder_alloc(&dec); ASSERT_EQ(0, err); /* load chunk2 */ mb2 = mbuf_load_file("./test/data/chunk2"); ASSERT_TRUE(mb2 != NULL); err = chunk_decoder_append_data(dec, mb2->buf, mb2->end); ASSERT_EQ(0, err); ASSERT_EQ(2, chunk_decoder_count_chunks(dec)); ASSERT_EQ(10924, chunk_decoder_length(dec)); ASSERT_FALSE(chunk_decoder_is_final(dec)); /* load chunk3 */ mb3 = mbuf_load_file("./test/data/chunk3"); ASSERT_TRUE(mb3 != NULL); err = chunk_decoder_append_data(dec, mb3->buf, mb3->end); ASSERT_EQ(0, err); ASSERT_EQ(6, chunk_decoder_count_chunks(dec)); ASSERT_EQ(29948, chunk_decoder_length(dec)); ASSERT_FALSE(chunk_decoder_is_final(dec)); /* load chunk4 */ mb4 = mbuf_load_file("./test/data/chunk4"); ASSERT_TRUE(mb4 != NULL); err = chunk_decoder_append_data(dec, mb4->buf, mb4->end); ASSERT_EQ(0, err); ASSERT_EQ(8, chunk_decoder_count_chunks(dec)); ASSERT_EQ(36142, chunk_decoder_length(dec)); ASSERT_TRUE(chunk_decoder_is_final(dec)); /* finally, decode the whole buffer */ mb_payload = mbuf_alloc(8192); err = chunk_decoder_unchunk(dec, mb_payload); ASSERT_EQ(0, err); ASSERT_EQ(36142, mb_payload->end); mb_ref = mbuf_load_file("./test/data/chunk_total"); ASSERT_TRUE(mb_ref != NULL); ASSERT_EQ(36142, mb_ref->end); ASSERT_TRUE(0 == memcmp(mb_ref->buf, mb_payload->buf, mb_ref->end)); mem_deref(dec); mem_deref(mb4); mem_deref(mb3); mem_deref(mb2); mem_deref(mb_payload); mem_deref(mb_ref); }
/** * Connect an outgoing call to a given SIP uri * * @param ua User-Agent * @param callp Optional pointer to allocated call object * @param from_uri Optional From uri, or NULL for default AOR * @param uri SIP uri to connect to * @param params Optional URI parameters * @param vmode Video mode * * @return 0 if success, otherwise errorcode */ int ua_connect(struct ua *ua, struct call **callp, const char *from_uri, const char *uri, const char *params, enum vidmode vmode) { struct call *call = NULL; struct mbuf *dialbuf; struct pl pl; int err = 0; if (!ua || !str_isset(uri)) return EINVAL; dialbuf = mbuf_alloc(64); if (!dialbuf) return ENOMEM; if (params) err |= mbuf_printf(dialbuf, "<"); err |= uri_complete(ua, dialbuf, uri); if (params) { err |= mbuf_printf(dialbuf, ";%s", params); } /* Append any optional URI parameters */ err |= mbuf_write_pl(dialbuf, &ua->acc->luri.params); if (params) err |= mbuf_printf(dialbuf, ">"); if (err) goto out; err = ua_call_alloc(&call, ua, vmode, NULL, NULL, from_uri); if (err) goto out; pl.p = (char *)dialbuf->buf; pl.l = dialbuf->end; err = call_connect(call, &pl); if (err) mem_deref(call); else if (callp) *callp = call; out: mem_deref(dialbuf); return err; }