void tcsipcall_send(struct tcsipcall*call) { struct mbuf *mb; int err; char *to_uri, *to_user; char *from_uri, *from_name; pl_strdup(&to_uri, &call->remote->auri); pl_strdup(&to_user, &call->remote->uri.user); pl_strdup(&from_uri, &call->local->auri); if(call->local->dname.l) pl_strdup(&from_name, &call->local->dname); else pl_strdup(&from_name, &call->local->uri.user); char date[100]; struct tm *tv; tv = gmtime(&call->tv.tv_sec); strftime(date, sizeof(date), "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", tv); tcmedia_get_offer(call->media, &mb); err = sipsess_connect(&call->sess, call->uac->sock, to_uri, from_name, from_uri, to_user, NULL, 0, "application/sdp", mb, NULL, call, false, offer_handler, answer_handler, progress_handler, establish_handler, NULL, NULL, close_handler, call, date); mem_deref(mb); /* free SDP buffer */ if(err) call->cstate |= CSTATE_ERR; else call->cstate |= CSTATE_OUT_RING; mem_deref(to_uri); mem_deref(to_user); mem_deref(from_uri); mem_deref(from_name); }
static int send_invite(struct call *call) { const char *routev[1]; struct mbuf *desc; int err; routev[0] = ua_outbound(call->ua); err = call_sdp_get(call, &desc, true); if (err) return err; err = sipsess_connect(&call->sess, uag_sipsess_sock(), call->peer_uri, call->local_name, call->local_uri, ua_cuser(call->ua), routev[0] ? routev : NULL, routev[0] ? 1 : 0, "application/sdp", desc, auth_handler, call->acc, true, sipsess_offer_handler, sipsess_answer_handler, sipsess_progr_handler, sipsess_estab_handler, sipsess_info_handler, sipsess_refer_handler, sipsess_close_handler, call, "Allow: %s\r\n%H", uag_allowed_methods(), ua_print_supported, call->ua); if (err) { warning("call: sipsess_connect: %m\n", err); } /* save call setup timer */ call->time_conn = time(NULL); mem_deref(desc); return err; }
int test_sipsess(void) { struct test test; struct sa laddr; char to_uri[256]; int err; uint16_t port; memset(&test, 0, sizeof(test)); #ifndef WIN32 /* slurp warnings from SIP (todo: temp) */ (void)freopen("/dev/null", "w", stderr); #endif err = sip_alloc(&test.sip, NULL, 32, 32, 32, "retest", exit_handler, NULL); if (err) goto out; (void)sa_set_str(&laddr, "127.0.0.1", 0); err = sip_transp_add(test.sip, SIP_TRANSP_UDP, &laddr); if (err) goto out; err = sip_transp_laddr(test.sip, &laddr, SIP_TRANSP_UDP, NULL); if (err) goto out; port = sa_port(&laddr); err = sipsess_listen(&test.sock, test.sip, 32, conn_handler, &test); if (err) goto out; /* Connect to "b" */ (void)re_snprintf(to_uri, sizeof(to_uri), "sip:[email protected]:%u", port); err = sipsess_connect(&test.a, test.sock, to_uri, NULL, "sip:[email protected]", "a", NULL, 0, "application/sdp", NULL, NULL, NULL, false, offer_handler, answer_handler, NULL, estab_handler_a, NULL, NULL, close_handler, &test, NULL); if (err) goto out; err = re_main_timeout(200); if (err) goto out; if (test.err) { err = test.err; goto out; } /* okay here -- verify */ TEST_ASSERT(test.estab_a); TEST_ASSERT(test.estab_b); out: test.a = mem_deref(test.a); test.b = mem_deref(test.b); sipsess_close_all(test.sock); test.sock = mem_deref(test.sock); sip_close(test.sip, false); test.sip = mem_deref(test.sip); #ifndef WIN32 /* Restore stderr */ freopen("/dev/tty", "w", stderr); #endif return err; }
int main(int argc, char *argv[]) { struct sa nsv[16]; struct dnsc *dnsc = NULL; struct sa laddr; uint32_t nsc; int err; /* errno return values */ /* enable coredumps to aid debugging */ (void)sys_coredump_set(true); /* initialize libre state */ err = libre_init(); if (err) { re_fprintf(stderr, "re init failed: %s\n", strerror(err)); goto out; } nsc = ARRAY_SIZE(nsv); /* fetch list of DNS server IP addresses */ err = dns_srv_get(NULL, 0, nsv, &nsc); if (err) { re_fprintf(stderr, "unable to get dns servers: %s\n", strerror(err)); goto out; } /* create DNS client */ err = dnsc_alloc(&dnsc, NULL, nsv, nsc); if (err) { re_fprintf(stderr, "unable to create dns client: %s\n", strerror(err)); goto out; } /* create SIP stack instance */ err = sip_alloc(&sip, dnsc, 32, 32, 32, "ua demo v" VERSION " (" ARCH "/" OS ")", exit_handler, NULL); if (err) { re_fprintf(stderr, "sip error: %s\n", strerror(err)); goto out; } /* fetch local IP address */ err = net_default_source_addr_get(AF_INET, &laddr); if (err) { re_fprintf(stderr, "local address error: %s\n", strerror(err)); goto out; } /* listen on random port */ sa_set_port(&laddr, 0); /* add supported SIP transports */ err |= sip_transp_add(sip, SIP_TRANSP_UDP, &laddr); err |= sip_transp_add(sip, SIP_TRANSP_TCP, &laddr); if (err) { re_fprintf(stderr, "transport error: %s\n", strerror(err)); goto out; } /* create SIP session socket */ err = sipsess_listen(&sess_sock, sip, 32, connect_handler, NULL); if (err) { re_fprintf(stderr, "session listen error: %s\n", strerror(err)); goto out; } /* create the RTP/RTCP socket */ err = rtp_listen(&rtp, IPPROTO_UDP, &laddr, 10000, 30000, true, rtp_handler, rtcp_handler, NULL); if (err) { re_fprintf(stderr, "rtp listen error: %m\n", err); goto out; } re_printf("local RTP port is %u\n", sa_port(rtp_local(rtp))); /* create SDP session */ err = sdp_session_alloc(&sdp, &laddr); if (err) { re_fprintf(stderr, "sdp session error: %s\n", strerror(err)); goto out; } /* add audio sdp media, using port from RTP socket */ err = sdp_media_add(&sdp_media, sdp, "audio", sa_port(rtp_local(rtp)), "RTP/AVP"); if (err) { re_fprintf(stderr, "sdp media error: %s\n", strerror(err)); goto out; } /* add G.711 sdp media format */ err = sdp_format_add(NULL, sdp_media, false, "0", "PCMU", 8000, 1, NULL, NULL, NULL, false, NULL); if (err) { re_fprintf(stderr, "sdp format error: %s\n", strerror(err)); goto out; } /* invite provided URI */ if (argc > 1) { struct mbuf *mb; /* create SDP offer */ err = sdp_encode(&mb, sdp, true); if (err) { re_fprintf(stderr, "sdp encode error: %s\n", strerror(err)); goto out; } err = sipsess_connect(&sess, sess_sock, argv[1], name, uri, name, NULL, 0, "application/sdp", mb, auth_handler, NULL, false, offer_handler, answer_handler, progress_handler, establish_handler, NULL, NULL, close_handler, NULL, NULL); mem_deref(mb); /* free SDP buffer */ if (err) { re_fprintf(stderr, "session connect error: %s\n", strerror(err)); goto out; } re_printf("inviting <%s>...\n", argv[1]); } else { err = sipreg_register(®, sip, registrar, uri, uri, 60, name, NULL, 0, 0, auth_handler, NULL, false, register_handler, NULL, NULL, NULL); if (err) { re_fprintf(stderr, "register error: %s\n", strerror(err)); goto out; } re_printf("registering <%s>...\n", uri); } /* main loop */ err = re_main(signal_handler); out: /* clean up/free all state */ mem_deref(sdp); /* will also free sdp_media */ mem_deref(rtp); mem_deref(sess_sock); mem_deref(sip); mem_deref(dnsc); /* free librar state */ libre_close(); /* check for memory leaks */ tmr_debug(); mem_debug(); return err; }