/* Apply QoS */ PJ_DEF(pj_status_t) pj_sock_apply_qos( pj_sock_t sock, pj_qos_type qos_type, pj_qos_params *qos_params, unsigned log_level, const char *log_sender, const char *sock_name) { pj_status_t qos_type_rc = PJ_SUCCESS, qos_params_rc = PJ_SUCCESS; if (!log_sender) log_sender = THIS_FILE; if (!sock_name) sock_name = "socket"; if (qos_type != PJ_QOS_TYPE_BEST_EFFORT) { qos_type_rc = pj_sock_set_qos_type(sock, qos_type); if (qos_type_rc != PJ_SUCCESS) { pj_perror(log_level, log_sender, qos_type_rc, "Error setting QoS type %d to %s", qos_type, sock_name); } } if (qos_params && qos_params->flags) { qos_params_rc = pj_sock_set_qos_params(sock, qos_params); if (qos_params_rc != PJ_SUCCESS) { pj_perror(log_level, log_sender, qos_params_rc, "Error setting QoS params (flags=%d) to %s", qos_params->flags, sock_name); if (qos_type_rc != PJ_SUCCESS) return qos_params_rc; } } else if (qos_type_rc != PJ_SUCCESS) return qos_type_rc; return PJ_SUCCESS; }
static pj_status_t codec_get_frame(pjmedia_port *port, pjmedia_frame *frame) { codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata; pjmedia_vid_codec *codec = port_data->codec; pjmedia_frame enc_frame; pj_status_t status; enc_frame.buf = port_data->enc_buf; enc_frame.size = port_data->enc_buf_size; if (port_data->conv) { pj_size_t frame_size = frame->size; status = pjmedia_port_get_frame(port_data->src_port, frame); if (status != PJ_SUCCESS) goto on_error; status = pjmedia_vid_codec_decode(codec, 1, frame, frame->size, &enc_frame); if (status != PJ_SUCCESS) goto on_error; frame->size = frame_size; status = pjmedia_converter_convert(port_data->conv, &enc_frame, frame); if (status != PJ_SUCCESS) goto on_error; return PJ_SUCCESS; } status = pjmedia_port_get_frame(port_data->src_port, &enc_frame); if (status != PJ_SUCCESS) goto on_error; status = pjmedia_vid_codec_decode(codec, 1, &enc_frame, frame->size, frame); if (status != PJ_SUCCESS) goto on_error; return PJ_SUCCESS; on_error: pj_perror(3, THIS_FILE, status, "codec_get_frame() error"); return status; }
int errno_test(void) { enum { CUT = 6 }; pj_status_t rc = 0; char errbuf[256]; PJ_LOG(3,(THIS_FILE, "...errno test: check the msg carefully")); PJ_UNUSED_ARG(rc); /* * Windows platform error. */ # ifdef ERROR_INVALID_DATA rc = PJ_STATUS_FROM_OS(ERROR_INVALID_DATA); pj_set_os_error(rc); /* Whole */ pj_strerror(rc, errbuf, sizeof(errbuf)); trim_newlines(errbuf); PJ_LOG(3,(THIS_FILE, "...msg for rc=ERROR_INVALID_DATA: '%s'", errbuf)); if (my_stristr(errbuf, "invalid") == NULL) { PJ_LOG(3, (THIS_FILE, "...error: expecting \"invalid\" string in the msg")); #ifndef PJ_WIN32_WINCE return -20; #endif } /* Cut version. */ pj_strerror(rc, errbuf, CUT); PJ_LOG(3,(THIS_FILE, "...msg for rc=ERROR_INVALID_DATA (cut): '%s'", errbuf)); # endif /* * Unix errors */ # if defined(EINVAL) && !defined(PJ_SYMBIAN) rc = PJ_STATUS_FROM_OS(EINVAL); pj_set_os_error(rc); /* Whole */ pj_strerror(rc, errbuf, sizeof(errbuf)); trim_newlines(errbuf); PJ_LOG(3,(THIS_FILE, "...msg for rc=EINVAL: '%s'", errbuf)); if (my_stristr(errbuf, "invalid") == NULL) { PJ_LOG(3, (THIS_FILE, "...error: expecting \"invalid\" string in the msg")); return -30; } /* Cut */ pj_strerror(rc, errbuf, CUT); PJ_LOG(3,(THIS_FILE, "...msg for rc=EINVAL (cut): '%s'", errbuf)); # endif /* * Windows WSA errors */ # ifdef WSAEINVAL rc = PJ_STATUS_FROM_OS(WSAEINVAL); pj_set_os_error(rc); /* Whole */ pj_strerror(rc, errbuf, sizeof(errbuf)); trim_newlines(errbuf); PJ_LOG(3,(THIS_FILE, "...msg for rc=WSAEINVAL: '%s'", errbuf)); if (my_stristr(errbuf, "invalid") == NULL) { PJ_LOG(3, (THIS_FILE, "...error: expecting \"invalid\" string in the msg")); return -40; } /* Cut */ pj_strerror(rc, errbuf, CUT); PJ_LOG(3,(THIS_FILE, "...msg for rc=WSAEINVAL (cut): '%s'", errbuf)); # endif pj_strerror(PJ_EBUG, errbuf, sizeof(errbuf)); PJ_LOG(3,(THIS_FILE, "...msg for rc=PJ_EBUG: '%s'", errbuf)); if (my_stristr(errbuf, "BUG") == NULL) { PJ_LOG(3, (THIS_FILE, "...error: expecting \"BUG\" string in the msg")); return -20; } pj_strerror(PJ_EBUG, errbuf, CUT); PJ_LOG(3,(THIS_FILE, "...msg for rc=PJ_EBUG, cut at %d chars: '%s'", CUT, errbuf)); /* Perror */ pj_perror(3, THIS_FILE, PJ_SUCCESS, "...testing %s", "pj_perror"); PJ_PERROR(3,(THIS_FILE, PJ_SUCCESS, "...testing %s", "PJ_PERROR")); return 0; }
/* * Callback from TURN session when state has changed */ static void turn_on_state(pj_turn_session *sess, pj_turn_state_t old_state, pj_turn_state_t new_state) { pj_turn_sock *turn_sock = (pj_turn_sock*) pj_turn_session_get_user_data(sess); pj_status_t status; if (turn_sock == NULL) { /* We've been destroyed */ return; } /* Notify app first */ if (turn_sock->cb.on_state) { (*turn_sock->cb.on_state)(turn_sock, old_state, new_state); } /* Make sure user hasn't destroyed us in the callback */ if (turn_sock->sess && new_state == PJ_TURN_STATE_RESOLVED) { pj_turn_session_info info; pj_turn_session_get_info(turn_sock->sess, &info); new_state = info.state; } if (turn_sock->sess && new_state == PJ_TURN_STATE_RESOLVED) { /* * Once server has been resolved, initiate outgoing TCP * connection to the server. */ pj_turn_session_info info; char addrtxt[PJ_INET6_ADDRSTRLEN+8]; int sock_type; pj_sock_t sock; pj_activesock_cfg asock_cfg; pj_activesock_cb asock_cb; pj_sockaddr bound_addr, *cfg_bind_addr; pj_uint16_t max_bind_retry; /* Close existing connection, if any. This happens when * we're switching to alternate TURN server when either TCP * connection or ALLOCATE request failed. */ if (turn_sock->active_sock) { pj_activesock_close(turn_sock->active_sock); turn_sock->active_sock = NULL; } /* Get server address from session info */ pj_turn_session_get_info(sess, &info); if (turn_sock->conn_type == PJ_TURN_TP_UDP) sock_type = pj_SOCK_DGRAM(); else sock_type = pj_SOCK_STREAM(); /* Init socket */ status = pj_sock_socket(turn_sock->af, sock_type, 0, &sock); if (status != PJ_SUCCESS) { pj_turn_sock_destroy(turn_sock); return; } /* Bind socket */ cfg_bind_addr = &turn_sock->setting.bound_addr; max_bind_retry = MAX_BIND_RETRY; if (turn_sock->setting.port_range && turn_sock->setting.port_range < max_bind_retry) { max_bind_retry = turn_sock->setting.port_range; } pj_sockaddr_init(turn_sock->af, &bound_addr, NULL, 0); if (cfg_bind_addr->addr.sa_family == pj_AF_INET() || cfg_bind_addr->addr.sa_family == pj_AF_INET6()) { pj_sockaddr_cp(&bound_addr, cfg_bind_addr); } status = pj_sock_bind_random(sock, &bound_addr, turn_sock->setting.port_range, max_bind_retry); if (status != PJ_SUCCESS) { pj_turn_sock_destroy(turn_sock); return; } /* Apply QoS, if specified */ status = pj_sock_apply_qos2(sock, turn_sock->setting.qos_type, &turn_sock->setting.qos_params, (turn_sock->setting.qos_ignore_error?2:1), turn_sock->pool->obj_name, NULL); if (status != PJ_SUCCESS && !turn_sock->setting.qos_ignore_error) { pj_turn_sock_destroy(turn_sock); return; } /* Apply socket buffer size */ if (turn_sock->setting.so_rcvbuf_size > 0) { unsigned sobuf_size = turn_sock->setting.so_rcvbuf_size; status = pj_sock_setsockopt_sobuf(sock, pj_SO_RCVBUF(), PJ_TRUE, &sobuf_size); if (status != PJ_SUCCESS) { pj_perror(3, turn_sock->obj_name, status, "Failed setting SO_RCVBUF"); } else { if (sobuf_size < turn_sock->setting.so_rcvbuf_size) { PJ_LOG(4, (turn_sock->obj_name, "Warning! Cannot set SO_RCVBUF as configured," " now=%d, configured=%d", sobuf_size, turn_sock->setting.so_rcvbuf_size)); } else { PJ_LOG(5, (turn_sock->obj_name, "SO_RCVBUF set to %d", sobuf_size)); } } } if (turn_sock->setting.so_sndbuf_size > 0) { unsigned sobuf_size = turn_sock->setting.so_sndbuf_size; status = pj_sock_setsockopt_sobuf(sock, pj_SO_SNDBUF(), PJ_TRUE, &sobuf_size); if (status != PJ_SUCCESS) { pj_perror(3, turn_sock->obj_name, status, "Failed setting SO_SNDBUF"); } else { if (sobuf_size < turn_sock->setting.so_sndbuf_size) { PJ_LOG(4, (turn_sock->obj_name, "Warning! Cannot set SO_SNDBUF as configured," " now=%d, configured=%d", sobuf_size, turn_sock->setting.so_sndbuf_size)); } else { PJ_LOG(5, (turn_sock->obj_name, "SO_SNDBUF set to %d", sobuf_size)); } } } /* Create active socket */ pj_activesock_cfg_default(&asock_cfg); asock_cfg.grp_lock = turn_sock->grp_lock; pj_bzero(&asock_cb, sizeof(asock_cb)); asock_cb.on_data_read = &on_data_read; asock_cb.on_connect_complete = &on_connect_complete; status = pj_activesock_create(turn_sock->pool, sock, sock_type, &asock_cfg, turn_sock->cfg.ioqueue, &asock_cb, turn_sock, &turn_sock->active_sock); if (status != PJ_SUCCESS) { pj_turn_sock_destroy(turn_sock); return; } PJ_LOG(5,(turn_sock->pool->obj_name, "Connecting to %s", pj_sockaddr_print(&info.server, addrtxt, sizeof(addrtxt), 3))); /* Initiate non-blocking connect */ #if PJ_HAS_TCP status=pj_activesock_start_connect(turn_sock->active_sock, turn_sock->pool, &info.server, pj_sockaddr_get_len(&info.server)); if (status == PJ_SUCCESS) { on_connect_complete(turn_sock->active_sock, PJ_SUCCESS); } else if (status != PJ_EPENDING) { pj_turn_sock_destroy(turn_sock); return; } #else on_connect_complete(turn_sock->active_sock, PJ_SUCCESS); #endif /* Done for now. Subsequent work will be done in * on_connect_complete() callback. */ } if (new_state >= PJ_TURN_STATE_DESTROYING && turn_sock->sess) { pj_time_val delay = {0, 0}; turn_sock->sess = NULL; pj_turn_session_set_user_data(sess, NULL); pj_timer_heap_cancel_if_active(turn_sock->cfg.timer_heap, &turn_sock->timer, 0); pj_timer_heap_schedule_w_grp_lock(turn_sock->cfg.timer_heap, &turn_sock->timer, &delay, TIMER_DESTROY, turn_sock->grp_lock); } }
static pj_status_t codec_put_frame(pjmedia_port *port, pjmedia_frame *frame) { enum { MAX_PACKETS = 50 }; codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata; pj_status_t status; pjmedia_vid_codec *codec = port_data->codec; unsigned enc_cnt = 0; pj_uint8_t *enc_buf; unsigned enc_size_left; pjmedia_frame enc_frames[MAX_PACKETS]; pj_bool_t has_more = PJ_FALSE; enc_buf = port_data->enc_buf; enc_size_left = port_data->enc_buf_size; /* * Encode */ enc_frames[enc_cnt].buf = enc_buf; enc_frames[enc_cnt].size = enc_size_left; status = pjmedia_vid_codec_encode_begin(codec, NULL, frame, enc_size_left, &enc_frames[enc_cnt], &has_more); if (status != PJ_SUCCESS) goto on_error; enc_buf += enc_frames[enc_cnt].size; enc_size_left -= enc_frames[enc_cnt].size; ++enc_cnt; while (has_more) { enc_frames[enc_cnt].buf = enc_buf; enc_frames[enc_cnt].size = enc_size_left; status = pjmedia_vid_codec_encode_more(codec, enc_size_left, &enc_frames[enc_cnt], &has_more); if (status != PJ_SUCCESS) break; enc_buf += enc_frames[enc_cnt].size; enc_size_left -= enc_frames[enc_cnt].size; ++enc_cnt; if (enc_cnt >= MAX_PACKETS) { assert(!"Too many packets!"); break; } } /* * Decode */ status = pjmedia_vid_codec_decode(codec, enc_cnt, enc_frames, frame->size, frame); if (status != PJ_SUCCESS) goto on_error; /* Display */ status = pjmedia_port_put_frame( pjmedia_vid_port_get_passive_port(port_data->rdr_port), frame); if (status != PJ_SUCCESS) goto on_error; return PJ_SUCCESS; on_error: pj_perror(3, THIS_FILE, status, "codec_put_frame() error"); return status; }
/* Called by application to initialize the transport */ static pj_status_t transport_attach( pjmedia_transport *tp, void *user_data, const pj_sockaddr_t *rem_addr, const pj_sockaddr_t *rem_rtcp, unsigned addr_len, void (*rtp_cb)(void*, void*, pj_ssize_t), void (*rtcp_cb)(void*, void*, pj_ssize_t)) { struct transport_udp *udp = (struct transport_udp*) tp; const pj_sockaddr *rtcp_addr; /* Validate arguments */ PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); /* Must not be "attached" to existing application */ PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP); /* Lock the ioqueue keys to make sure that callbacks are * not executed. See ticket #844 for details. */ pj_ioqueue_lock_key(udp->rtp_key); pj_ioqueue_lock_key(udp->rtcp_key); /* "Attach" the application: */ /* Copy remote RTP address */ pj_memcpy(&udp->rem_rtp_addr, rem_addr, addr_len); /* Copy remote RTP address, if one is specified. */ rtcp_addr = (const pj_sockaddr*) rem_rtcp; if (rtcp_addr && pj_sockaddr_has_addr(rtcp_addr)) { pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, addr_len); } else { unsigned rtcp_port; /* Otherwise guess the RTCP address from the RTP address */ pj_memcpy(&udp->rem_rtcp_addr, rem_addr, addr_len); rtcp_port = pj_sockaddr_get_port(&udp->rem_rtp_addr) + 1; pj_sockaddr_set_port(&udp->rem_rtcp_addr, (pj_uint16_t)rtcp_port); } /* Save the callbacks */ udp->rtp_cb = rtp_cb; udp->rtcp_cb = rtcp_cb; udp->user_data = user_data; /* Save address length */ udp->addr_len = addr_len; /* Last, mark transport as attached */ udp->attached = PJ_TRUE; /* Reset source RTP & RTCP addresses and counter */ pj_bzero(&udp->rtp_src_addr, sizeof(udp->rtp_src_addr)); pj_bzero(&udp->rtcp_src_addr, sizeof(udp->rtcp_src_addr)); udp->rtp_src_cnt = 0; udp->rtcp_src_cnt = 0; /* Set buffer size for RTP socket */ #if PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE { unsigned sobuf_size = PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE; pj_status_t status; status = pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_RCVBUF(), PJ_TRUE, &sobuf_size); if (status != PJ_SUCCESS) { pj_perror(3, tp->name, status, "Failed setting SO_RCVBUF"); } else { if (sobuf_size < PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE) { PJ_LOG(4, (tp->name, "Warning! Cannot set SO_RCVBUF as configured, " "now=%d, configured=%d", sobuf_size, PJMEDIA_TRANSPORT_SO_RCVBUF_SIZE)); } else { PJ_LOG(5, (tp->name, "SO_RCVBUF set to %d", sobuf_size)); } } } #endif #if PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE { unsigned sobuf_size = PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE; pj_status_t status; status = pj_sock_setsockopt_sobuf(udp->rtp_sock, pj_SO_SNDBUF(), PJ_TRUE, &sobuf_size); if (status != PJ_SUCCESS) { pj_perror(3, tp->name, status, "Failed setting SO_SNDBUF"); } else { if (sobuf_size < PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE) { PJ_LOG(4, (tp->name, "Warning! Cannot set SO_SNDBUF as configured, " "now=%d, configured=%d", sobuf_size, PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE)); } else { PJ_LOG(5, (tp->name, "SO_SNDBUF set to %d", sobuf_size)); } } } #endif /* Unlock keys */ pj_ioqueue_unlock_key(udp->rtcp_key); pj_ioqueue_unlock_key(udp->rtp_key); return PJ_SUCCESS; }
/* Called when CLI (re)started */ void on_app_started(pj_status_t status, const char *msg) { pj_perror(3, THIS_FILE, status, (msg)?msg:""); }
/* * Create the STUN transport using the specified configuration. */ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg, const char *name, int af, const pj_stun_sock_cb *cb, const pj_stun_sock_cfg *cfg, void *user_data, pj_stun_sock **p_stun_sock) { pj_pool_t *pool; pj_stun_sock *stun_sock; pj_stun_sock_cfg default_cfg; pj_sockaddr bound_addr; unsigned i; pj_uint16_t max_bind_retry; pj_status_t status; PJ_ASSERT_RETURN(stun_cfg && cb && p_stun_sock, PJ_EINVAL); PJ_ASSERT_RETURN(af==pj_AF_INET()||af==pj_AF_INET6(), PJ_EAFNOTSUP); PJ_ASSERT_RETURN(!cfg || pj_stun_sock_cfg_is_valid(cfg), PJ_EINVAL); PJ_ASSERT_RETURN(cb->on_status, PJ_EINVAL); status = pj_stun_config_check_valid(stun_cfg); if (status != PJ_SUCCESS) return status; if (name == NULL) name = "stuntp%p"; if (cfg == NULL) { pj_stun_sock_cfg_default(&default_cfg); cfg = &default_cfg; } /* Create structure */ pool = pj_pool_create(stun_cfg->pf, name, 256, 512, NULL); stun_sock = PJ_POOL_ZALLOC_T(pool, pj_stun_sock); stun_sock->pool = pool; stun_sock->obj_name = pool->obj_name; stun_sock->user_data = user_data; stun_sock->af = af; stun_sock->sock_fd = PJ_INVALID_SOCKET; pj_memcpy(&stun_sock->stun_cfg, stun_cfg, sizeof(*stun_cfg)); pj_memcpy(&stun_sock->cb, cb, sizeof(*cb)); stun_sock->ka_interval = cfg->ka_interval; stun_sock->timerstat = cfg->timerstat; if (stun_sock->ka_interval == 0) stun_sock->ka_interval = PJ_STUN_KEEP_ALIVE_SEC; printf(": cfg->stunProtocol=%d\n", cfg->stunProtocol); printf("%s", cfg->timerstat ? "SBR keepalive enabled\n": "SBR keepalive disabled\n"); if (cfg->grp_lock) { stun_sock->grp_lock = cfg->grp_lock; } else { status = pj_grp_lock_create(pool, NULL, &stun_sock->grp_lock); if (status != PJ_SUCCESS) { pj_pool_release(pool); return status; } } pj_grp_lock_add_ref(stun_sock->grp_lock); pj_grp_lock_add_handler(stun_sock->grp_lock, pool, stun_sock, &stun_sock_destructor); /* Create socket and bind socket */ // status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd); if(cfg->stunProtocol == 1) status = pj_sock_socket(af, PJ_SOCK_STREAM, 0, &stun_sock->sock_fd); else status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd); if (status != PJ_SUCCESS) goto on_error; /* Apply QoS, if specified */ status = pj_sock_apply_qos2(stun_sock->sock_fd, cfg->qos_type, &cfg->qos_params, 2, stun_sock->obj_name, NULL); if (status != PJ_SUCCESS && !cfg->qos_ignore_error) goto on_error; /* Apply socket buffer size */ if (cfg->so_rcvbuf_size > 0) { unsigned sobuf_size = cfg->so_rcvbuf_size; status = pj_sock_setsockopt_sobuf(stun_sock->sock_fd, pj_SO_RCVBUF(), PJ_TRUE, &sobuf_size); if (status != PJ_SUCCESS) { pj_perror(3, stun_sock->obj_name, status, "Failed setting SO_RCVBUF"); } else { if (sobuf_size < cfg->so_rcvbuf_size) { PJ_LOG(4, (stun_sock->obj_name, "Warning! Cannot set SO_RCVBUF as configured, " "now=%d, configured=%d", sobuf_size, cfg->so_rcvbuf_size)); } else { PJ_LOG(5, (stun_sock->obj_name, "SO_RCVBUF set to %d", sobuf_size)); } } } if (cfg->so_sndbuf_size > 0) { unsigned sobuf_size = cfg->so_sndbuf_size; status = pj_sock_setsockopt_sobuf(stun_sock->sock_fd, pj_SO_SNDBUF(), PJ_TRUE, &sobuf_size); if (status != PJ_SUCCESS) { pj_perror(3, stun_sock->obj_name, status, "Failed setting SO_SNDBUF"); } else { if (sobuf_size < cfg->so_sndbuf_size) { PJ_LOG(4, (stun_sock->obj_name, "Warning! Cannot set SO_SNDBUF as configured, " "now=%d, configured=%d", sobuf_size, cfg->so_sndbuf_size)); } else { PJ_LOG(5, (stun_sock->obj_name, "SO_SNDBUF set to %d", sobuf_size)); } } } #if 1 /* Bind socket */ max_bind_retry = MAX_BIND_RETRY; if (cfg->port_range && cfg->port_range < max_bind_retry) max_bind_retry = cfg->port_range; pj_sockaddr_init(af, &bound_addr, NULL, 0); if (cfg->bound_addr.addr.sa_family == pj_AF_INET() || cfg->bound_addr.addr.sa_family == pj_AF_INET6()) { pj_sockaddr_cp(&bound_addr, &cfg->bound_addr); } status = pj_sock_bind_random(stun_sock->sock_fd, &bound_addr, cfg->port_range, max_bind_retry); if (status != PJ_SUCCESS) goto on_error; #endif /* Create more useful information string about this transport */ #if 0 { pj_sockaddr bound_addr; int addr_len = sizeof(bound_addr); status = pj_sock_getsockname(stun_sock->sock_fd, &bound_addr, &addr_len); if (status != PJ_SUCCESS) goto on_error; stun_sock->info = pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+10); pj_sockaddr_print(&bound_addr, stun_sock->info, PJ_INET6_ADDRSTRLEN, 3); } #endif /* Init active socket configuration */ { pj_activesock_cfg activesock_cfg; pj_activesock_cb activesock_cb; pj_activesock_cfg_default(&activesock_cfg); activesock_cfg.grp_lock = stun_sock->grp_lock; activesock_cfg.async_cnt = cfg->async_cnt; activesock_cfg.concurrency = 0; /* Create the active socket */ pj_bzero(&activesock_cb, sizeof(activesock_cb)); activesock_cb.on_data_recvfrom = &on_data_recvfrom; activesock_cb.on_data_sent = &on_data_sent; if(cfg->stunProtocol == 1) { status = pj_activesock_create(pool, stun_sock->sock_fd, PJ_SOCK_STREAM, &activesock_cfg, stun_cfg->ioqueue, &activesock_cb, stun_sock, &stun_sock->active_sock); } else { status = pj_activesock_create(pool, stun_sock->sock_fd, pj_SOCK_DGRAM(), //nish &activesock_cfg, stun_cfg->ioqueue, &activesock_cb, stun_sock, &stun_sock->active_sock); } if (status != PJ_SUCCESS) goto on_error; if(cfg->stunProtocol == 1) { stun_sock->srv_addr.addr.sa_family = AF_INET; stun_sock->srv_addr.ipv4.sin_port= pj_htons(cfg->sin_port); stun_sock->srv_addr.ipv4.sin_addr = (cfg->sin_addr); status=pj_activesock_start_connect(stun_sock->active_sock, pool, &(stun_sock->srv_addr), pj_sockaddr_get_len(&(stun_sock->srv_addr))); if (status == PJ_SUCCESS) { printf("actie sock connect succesful"); } } /* Start asynchronous read operations */ status = pj_activesock_start_recvfrom(stun_sock->active_sock, pool, cfg->max_pkt_size, 0); if (status != PJ_SUCCESS) goto on_error; /* Init send keys */ pj_ioqueue_op_key_init(&stun_sock->send_key, sizeof(stun_sock->send_key)); pj_ioqueue_op_key_init(&stun_sock->int_send_key, sizeof(stun_sock->int_send_key)); } /* Create STUN session */ { pj_stun_session_cb sess_cb; pj_bzero(&sess_cb, sizeof(sess_cb)); sess_cb.on_request_complete = &sess_on_request_complete; sess_cb.on_send_msg = &sess_on_send_msg; // stun_sock->stunProtocol = 1; //FIXME: cfg->stunProtocol; // stun_sock->stunProtocol = 0; //FIXME: cfg->stunProtocol; printf(" stun_sock->stunProtocol=%d\n", stun_sock->stunProtocol); status = pj_stun_session_create(&stun_sock->stun_cfg, stun_sock->obj_name, &sess_cb, PJ_FALSE, stun_sock->grp_lock, &stun_sock->stun_sess); if (status != PJ_SUCCESS) goto on_error; } /* Associate us with the STUN session */ pj_stun_session_set_user_data(stun_sock->stun_sess, stun_sock); /* Initialize random numbers to be used as STUN transaction ID for * outgoing Binding request. We use the 80bit number to distinguish * STUN messages we sent with STUN messages that the application sends. * The last 16bit value in the array is a counter. */ for (i=0; i<PJ_ARRAY_SIZE(stun_sock->tsx_id); ++i) { stun_sock->tsx_id[i] = (pj_uint16_t) pj_rand(); } stun_sock->tsx_id[5] = 0; /* Init timer entry */ stun_sock->ka_timer.cb = &ka_timer_cb; stun_sock->ka_timer.user_data = stun_sock; /* Done */ *p_stun_sock = stun_sock; return PJ_SUCCESS; on_error: pj_stun_sock_destroy(stun_sock); return status; }