/** * Create UDP stream transport. */ PJ_DEF(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt, const char *name, const pj_str_t *addr, int port, unsigned options, pjmedia_transport **p_tp) { pjmedia_sock_info si; pj_status_t status; /* Sanity check */ PJ_ASSERT_RETURN(endpt && port && p_tp, PJ_EINVAL); pj_bzero(&si, sizeof(pjmedia_sock_info)); si.rtp_sock = si.rtcp_sock = PJ_INVALID_SOCKET; /* Create RTP socket */ status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &si.rtp_sock); if (status != PJ_SUCCESS) goto on_error; /* Bind RTP socket */ pj_sockaddr_in_init(&si.rtp_addr_name, addr, (pj_uint16_t)port); status = pj_sock_bind(si.rtp_sock, &si.rtp_addr_name, sizeof(si.rtp_addr_name)); if (status != PJ_SUCCESS) goto on_error; /* Create RTCP socket */ status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &si.rtcp_sock); if (status != PJ_SUCCESS) goto on_error; /* Bind RTCP socket */ pj_sockaddr_in_init(&si.rtcp_addr_name, addr, (pj_uint16_t)(port+1)); status = pj_sock_bind(si.rtcp_sock, &si.rtcp_addr_name, sizeof(si.rtcp_addr_name)); if (status != PJ_SUCCESS) goto on_error; /* Create UDP transport by attaching socket info */ return pjmedia_transport_udp_attach( endpt, name, &si, options, p_tp); on_error: if (si.rtp_sock != PJ_INVALID_SOCKET) pj_sock_close(si.rtp_sock); if (si.rtcp_sock != PJ_INVALID_SOCKET) pj_sock_close(si.rtcp_sock); return status; }
/** * Create ipv6 transport */ PJ_DECL(pj_status_t) media_transports_create_ipv6(pjsua_transport_config rtp_cfg) { pjsua_media_transport tp[PJSUA_MAX_CALLS]; pj_status_t status; int port = rtp_cfg.port; unsigned i; //TODO : here should be get from config for (i=0; i<PJSUA_MAX_CALLS; ++i) { enum { MAX_RETRY = 10 }; pj_sock_t sock[2]; pjmedia_sock_info si; unsigned j; /* Get rid of uninitialized var compiler warning with MSVC */ status = PJ_SUCCESS; for (j=0; j<MAX_RETRY; ++j) { unsigned k; for (k=0; k<2; ++k) { pj_sockaddr bound_addr; status = pj_sock_socket(pj_AF_INET6(), pj_SOCK_DGRAM(), 0, &sock[k]); if (status != PJ_SUCCESS) break; status = pj_sockaddr_init(pj_AF_INET6(), &bound_addr, &rtp_cfg.bound_addr, (unsigned short)(port+k)); if (status != PJ_SUCCESS) break; status = pj_sock_bind(sock[k], &bound_addr, pj_sockaddr_get_len(&bound_addr)); if (status != PJ_SUCCESS) break; } if (status != PJ_SUCCESS) { if (k==1) pj_sock_close(sock[0]); if (port != 0) port += 10; else break; continue; } pj_bzero(&si, sizeof(si)); si.rtp_sock = sock[0]; si.rtcp_sock = sock[1]; pj_sockaddr_init(pj_AF_INET6(), &si.rtp_addr_name, &rtp_cfg.public_addr, (unsigned short)(port)); pj_sockaddr_init(pj_AF_INET6(), &si.rtcp_addr_name, &rtp_cfg.public_addr, (unsigned short)(port+1)); status = pjmedia_transport_udp_attach(pjsua_get_pjmedia_endpt(), NULL, &si, 0, &tp[i].transport); if (port != 0) port += 10; else break; if (status == PJ_SUCCESS) break; } if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error creating IPv6 UDP media transport", status); for (j=0; j<i; ++j) { pjmedia_transport_close(tp[j].transport); } return status; } } return pjsua_media_transports_attach(tp, i, PJ_TRUE); }