Home --> Documentations --> PJNATH Reference
This sample demonstrates how to use ICE stream transport without using signaling protocol such as SIP. It provides interactive user interface to create and manage the ICE sessions as well as to exchange SDP with another ice_demo instance.
Features of the demo application:
- supports host, STUN, and TURN candidates
- disabling of host candidates
- DNS SRV resolution for STUN and TURN servers
- TCP connection to TURN server
- Optional use of fingerprint for TURN
- prints and parse SDP containing ICE infos
- exchange SDP with copy/paste
This file is pjsip-apps/src/samples/icedemo.c
Screenshot on WinXP:
ice_demo on WinXP
21#include <pjlib-util.h>
25#define THIS_FILE "icedemo.c"
30#define KA_INTERVAL 300
75static void icedemo_perror( const char *title, pj_status_t status)
80 PJ_LOG(1,(THIS_FILE, "%s: %s", title, errmsg));
86static void err_exit( const char *title, pj_status_t status)
89 icedemo_perror(title, status);
91 PJ_LOG(3,(THIS_FILE, "Shutting down.."));
98 icedemo.thread_quit_flag = PJ_TRUE;
104 if (icedemo.ice_cfg.stun_cfg.ioqueue)
107 if (icedemo.ice_cfg.stun_cfg.timer_heap)
114 if (icedemo.log_fhnd) {
115 fclose(icedemo.log_fhnd);
116 icedemo.log_fhnd = NULL;
122#define CHECK(expr) status=expr; \
123 if (status!=PJ_SUCCESS) { \
124 err_exit(#expr, status); \
131static pj_status_t handle_events( unsigned max_msec, unsigned *p_count)
133 enum { MAX_NET_EVENTS = 1 };
136 unsigned count = 0, net_event_count = 0;
139 max_timeout. msec = max_msec;
142 timeout. sec = timeout. msec = 0;
151 if (timeout. msec >= 1000) timeout. msec = 999;
157 timeout = max_timeout;
181 net_event_count += c;
182 timeout. sec = timeout. msec = 0;
184 } while (c > 0 && net_event_count < MAX_NET_EVENTS);
186 count += net_event_count;
197static int icedemo_worker_thread( void *unused)
201 while (!icedemo.thread_quit_flag) {
202 handle_events(500, NULL);
218 unsigned src_addr_len)
229 PJ_LOG(3,(THIS_FILE, "Component %d: received %d bytes data from %s: \"%.*s\"",
249 PJ_LOG(3,(THIS_FILE, "ICE %s successful", opname));
254 PJ_LOG(1,(THIS_FILE, "ICE %s failed: %s", opname, errmsg));
256 icedemo.icest = NULL;
261static void log_func( int level, const char *data, int len)
264 if (icedemo.log_fhnd) {
265 if (fwrite(data, len, 1, icedemo.log_fhnd) != 1)
279 if (icedemo.opt.log_file) {
280 icedemo.log_fhnd = fopen(icedemo.opt.log_file, "a");
295 icedemo.ice_cfg.stun_cfg.pf = &icedemo.cp.factory;
303 &icedemo.ice_cfg.stun_cfg.timer_heap) );
307 &icedemo.ice_cfg.stun_cfg.ioqueue) );
314 NULL, 0, 0, &icedemo.thread) );
319 if (icedemo.opt.ns.slen) {
323 icedemo.ice_cfg.stun_cfg.timer_heap,
324 icedemo.ice_cfg.stun_cfg.ioqueue,
325 &icedemo.ice_cfg.resolver) );
328 &icedemo.opt.ns, NULL) );
334 if (icedemo.opt.max_host != -1)
335 icedemo.ice_cfg.stun.max_host_cands = icedemo.opt.max_host;
338 if (icedemo.opt.regular)
339 icedemo.ice_cfg.opt.aggressive = PJ_FALSE;
341 icedemo.ice_cfg.opt.aggressive = PJ_TRUE;
344 if (icedemo.opt.stun_srv.slen) {
348 if ((pos= pj_strchr(&icedemo.opt.stun_srv, ':')) != NULL) {
349 icedemo.ice_cfg.stun.server.ptr = icedemo.opt.stun_srv.ptr;
350 icedemo.ice_cfg.stun.server.slen = (pos - icedemo.opt.stun_srv.ptr);
352 icedemo.ice_cfg.stun.port = ( pj_uint16_t)atoi(pos+1);
354 icedemo.ice_cfg.stun.server = icedemo.opt.stun_srv;
361 icedemo.ice_cfg.stun.cfg.ka_interval = KA_INTERVAL;
365 if (icedemo.opt.turn_srv.slen) {
369 if ((pos= pj_strchr(&icedemo.opt.turn_srv, ':')) != NULL) {
370 icedemo.ice_cfg.turn.server.ptr = icedemo.opt.turn_srv.ptr;
371 icedemo.ice_cfg.turn.server.slen = (pos - icedemo.opt.turn_srv.ptr);
373 icedemo.ice_cfg.turn.port = ( pj_uint16_t)atoi(pos+1);
375 icedemo.ice_cfg.turn.server = icedemo.opt.turn_srv;
381 icedemo.ice_cfg.turn.auth_cred.data.static_cred.username = icedemo.opt.turn_username;
383 icedemo.ice_cfg.turn.auth_cred.data.static_cred.data = icedemo.opt.turn_password;
386 if (icedemo.opt.turn_tcp)
394 icedemo.ice_cfg.turn.alloc_param.ka_interval = KA_INTERVAL;
405static void icedemo_create_instance( void)
410 if (icedemo.icest != NULL) {
411 puts( "ICE instance already created, destroy it first");
423 icedemo.opt.comp_cnt,
429 icedemo_perror( "error creating ice", status);
431 PJ_LOG(3,(THIS_FILE, "ICE instance successfully created"));
435static void reset_rem_info( void)
437 pj_bzero(&icedemo.rem, sizeof(icedemo.rem));
444static void icedemo_destroy_instance( void)
446 if (icedemo.icest == NULL) {
447 PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
452 icedemo.icest = NULL;
456 PJ_LOG(3,(THIS_FILE, "ICE instance destroyed"));
463static void icedemo_init_session( unsigned rolechar)
470 if (icedemo.icest == NULL) {
471 PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
476 PJ_LOG(1,(THIS_FILE, "Error: Session already created"));
482 icedemo_perror( "error creating session", status);
484 PJ_LOG(3,(THIS_FILE, "ICE session created"));
493static void icedemo_stop_session( void)
497 if (icedemo.icest == NULL) {
498 PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
503 PJ_LOG(1,(THIS_FILE, "Error: No ICE session, initialize first"));
509 icedemo_perror( "error stopping session", status);
511 PJ_LOG(3,(THIS_FILE, "ICE session stopped"));
517 printed = pj_ansi_snprintf(p, maxlen - (p-buffer), \
519 if (printed <= 0 || printed >= (int)(maxlen - (p-buffer))) \
520 return -PJ_ETOOSMALL; \
525static int print_cand( char buffer[], unsigned maxlen,
532 PRINT( "a=candidate:%.*s %u UDP %u %s %u typ ",
544 if (p == buffer+maxlen)
549 return ( int)(p-buffer);
555static int encode_session( char buffer[], unsigned maxlen)
564 PRINT( "v=0\no=- 3414953978 3414953978 IN IP4 localhost\ns=ice\nt=0 0\n");
571 PRINT( "a=ice-ufrag:%.*s\na=ice-pwd:%.*s\n",
572 ( int)local_ufrag. slen,
578 for (comp=0; comp<icedemo.opt.comp_cnt; ++comp) {
579 unsigned j, cand_cnt;
591 PRINT( "m=audio %d RTP/AVP 0\n"
596 } else if (comp==1) {
598 PRINT( "a=rtcp:%d IN IP4 %s\n",
604 PRINT( "a=Xice-defcand:%d IN IP4 %s\n",
618 for (j=0; j<cand_cnt; ++j) {
619 printed = print_cand(p, maxlen - ( unsigned)(p-buffer), &cand[j]);
626 if (p == buffer+maxlen)
630 return ( int)(p - buffer);
638static void icedemo_show_ice( void)
640 static char buffer[1000];
643 if (icedemo.icest == NULL) {
644 PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
648 puts( "General info");
649 puts( "---------------");
650 printf( "Component count : %d\n", icedemo.opt.comp_cnt);
653 puts( "negotiation complete");
655 puts( "negotiation is in progress");
657 puts( "session ready");
659 puts( "session not created");
662 puts( "Create the session first to see more info");
666 printf( "Negotiated comp_cnt: %d\n",
668 printf( "Role : %s\n",
670 "controlled" : "controlling");
672 len = encode_session(buffer, sizeof(buffer));
674 err_exit( "not enough buffer to show ICE status", -len);
677 printf( "Local SDP (paste this to remote host):\n"
678 "--------------------------------------\n"
683 puts( "Remote info:\n"
684 "----------------------");
685 if (icedemo.rem.cand_cnt==0) {
686 puts( "No remote info yet");
690 printf( "Remote ufrag : %s\n", icedemo.rem.ufrag);
691 printf( "Remote password : %s\n", icedemo.rem.pwd);
692 printf( "Remote cand. cnt. : %d\n", icedemo.rem.cand_cnt);
694 for (i=0; i<icedemo.rem.cand_cnt; ++i) {
695 len = print_cand(buffer, sizeof(buffer), &icedemo.rem.cand[i]);
697 err_exit( "not enough buffer to show ICE status", -len);
699 printf( " %s", buffer);
709static void icedemo_input_remote( void)
712 unsigned media_cnt = 0;
713 unsigned comp0_port = 0;
717 puts( "Paste SDP from remote host, end with empty line");
721 comp0_addr[0] = '\0';
728 if (stdout) fflush(stdout);
730 if (fgets(linebuf, sizeof(linebuf), stdin)==NULL)
733 len = strlen(linebuf);
734 while (len && (linebuf[len-1] == '\r' || linebuf[len-1] == '\n'))
735 linebuf[--len] = '\0';
752 char media[32], portstr[32];
756 puts( "Media line ignored");
760 cnt = sscanf(line+2, "%s %s RTP/", media, portstr);
762 PJ_LOG(1,(THIS_FILE, "Error parsing media line"));
766 comp0_port = atoi(portstr);
773 char c[32], net[32], ip[80];
775 cnt = sscanf(line+2, "%s %s %s", c, net, ip);
777 PJ_LOG(1,(THIS_FILE, "Error parsing connection line"));
781 strcpy(comp0_addr, ip);
786 char *attr = strtok(line+2, ": \t\r\n");
787 if (strcmp(attr, "ice-ufrag")==0) {
788 strcpy(icedemo.rem.ufrag, attr+strlen(attr)+1);
789 } else if (strcmp(attr, "ice-pwd")==0) {
790 strcpy(icedemo.rem.pwd, attr+strlen(attr)+1);
791 } else if (strcmp(attr, "rtcp")==0) {
792 char *val = attr+strlen(attr)+1;
795 char net[32], ip[64];
799 cnt = sscanf(val, "%d IN %s %s", &port, net, ip);
801 PJ_LOG(1,(THIS_FILE, "Error parsing rtcp attribute"));
815 PJ_LOG(1,(THIS_FILE, "Invalid IP address"));
820 } else if (strcmp(attr, "candidate")==0) {
821 char *sdpcand = attr+strlen(attr)+1;
823 char foundation[32], transport[12], ipaddr[80], type[32];
825 int comp_id, prio, port;
829 cnt = sscanf(sdpcand, "%s %d %s %d %s %d typ %s",
838 PJ_LOG(1, (THIS_FILE, "error: Invalid ICE candidate line"));
842 cand = &icedemo.rem.cand[icedemo.rem.cand_cnt];
845 if (strcmp(type, "host")==0)
847 else if (strcmp(type, "srflx")==0)
849 else if (strcmp(type, "relay")==0)
852 PJ_LOG(1, (THIS_FILE, "Error: invalid candidate type '%s'",
861 if (strchr(ipaddr, ':'))
870 PJ_LOG(1,(THIS_FILE, "Error: invalid IP address '%s'",
877 ++icedemo.rem.cand_cnt;
879 if (cand-> comp_id > icedemo.rem.comp_cnt)
880 icedemo.rem.comp_cnt = cand-> comp_id;
887 if (icedemo.rem.cand_cnt==0 ||
888 icedemo.rem.ufrag[0]==0 ||
889 icedemo.rem.pwd[0]==0 ||
890 icedemo.rem.comp_cnt == 0)
892 PJ_LOG(1, (THIS_FILE, "Error: not enough info"));
896 if (comp0_port==0 || comp0_addr[0]== '\0') {
897 PJ_LOG(1, (THIS_FILE, "Error: default address for component 0 not found"));
904 if (strchr(comp0_addr, ':'))
910 tmp_addr = pj_str(comp0_addr);
914 PJ_LOG(1,(THIS_FILE, "Invalid IP address in c= line"));
920 PJ_LOG(3, (THIS_FILE, "Done, %d remote candidate(s) added",
921 icedemo.rem.cand_cnt));
932static void icedemo_start_nego( void)
937 if (icedemo.icest == NULL) {
938 PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
943 PJ_LOG(1,(THIS_FILE, "Error: No ICE session, initialize first"));
947 if (icedemo.rem.cand_cnt == 0) {
948 PJ_LOG(1,(THIS_FILE, "Error: No remote info, input remote info first"));
952 PJ_LOG(3,(THIS_FILE, "Starting ICE negotiation.."));
955 pj_cstr(&rufrag, icedemo.rem.ufrag),
956 pj_cstr(&rpwd, icedemo.rem.pwd),
957 icedemo.rem.cand_cnt,
960 icedemo_perror( "Error starting ICE", status);
962 PJ_LOG(3,(THIS_FILE, "ICE negotiation started"));
969static void icedemo_send_data( unsigned comp_id, const char *data)
973 if (icedemo.icest == NULL) {
974 PJ_LOG(1,(THIS_FILE, "Error: No ICE instance, create it first"));
979 PJ_LOG(1,(THIS_FILE, "Error: No ICE session, initialize first"));
991 PJ_LOG(1,(THIS_FILE, "Error: invalid component ID"));
996 &icedemo.rem.def_addr[comp_id-1],
998 if (status != PJ_SUCCESS && status != PJ_EPENDING)
999 icedemo_perror( "Error sending data", status);
1001 PJ_LOG(3,(THIS_FILE, "Data sent/will be sent"));
1008static void icedemo_help_menu( void)
1011 puts( "-= Help on using ICE and this icedemo program =-");
1013 puts( "This application demonstrates how to use ICE in pjnath without having\n"
1014 "to use the SIP protocol. To use this application, you will need to run\n"
1015 "two instances of this application, to simulate two ICE agents.\n");
1017 puts( "Basic ICE flow:\n"
1018 " create instance [menu \"c\"]\n"
1019 " repeat these steps as wanted:\n"
1020 " - init session as offerer or answerer [menu \"i\"]\n"
1021 " - display our SDP [menu \"s\"]\n"
1022 " - \"send\" our SDP from the \"show\" output above to remote, by\n"
1023 " copy-pasting the SDP to the other icedemo application\n"
1024 " - parse remote SDP, by pasting SDP generated by the other icedemo\n"
1025 " instance [menu \"r\"]\n"
1026 " - begin ICE negotiation in our end [menu \"b\"], and \n"
1027 " - immediately begin ICE negotiation in the other icedemo instance\n"
1028 " - ICE negotiation will run, and result will be printed to screen\n"
1029 " - send application data to remote [menu \"x\"]\n"
1030 " - end/stop ICE session [menu \"e\"]\n"
1031 " destroy instance [menu \"d\"]\n"
1035 puts( "This concludes the help screen.");
1043static void icedemo_print_menu( void)
1046 puts( "+----------------------------------------------------------------------+");
1047 puts( "| M E N U |");
1048 puts( "+---+------------------------------------------------------------------+");
1049 puts( "| c | create Create the instance |");
1050 puts( "| d | destroy Destroy the instance |");
1051 puts( "| i | init o|a Initialize ICE session as offerer or answerer |");
1052 puts( "| e | stop End/stop ICE session |");
1053 puts( "| s | show Display local ICE info |");
1054 puts( "| r | remote Input remote ICE info |");
1055 puts( "| b | start Begin ICE negotiation |");
1056 puts( "| x | send <compid> .. Send data to remote |");
1057 puts( "+---+------------------------------------------------------------------+");
1058 puts( "| h | help * Help! * |");
1059 puts( "| q | quit Quit |");
1060 puts( "+----------------------------------------------------------------------+");
1067static void icedemo_console( void)
1072 char input[80], *cmd;
1073 const char *SEP = " \t\r\n";
1076 icedemo_print_menu();
1079 if (stdout) fflush(stdout);
1082 if (fgets(input, sizeof(input), stdin) == NULL)
1085 len = strlen(input);
1086 while (len && (input[len-1]== '\r' || input[len-1]== '\n'))
1087 input[--len] = '\0';
1089 cmd = strtok(input, SEP);
1093 if (strcmp(cmd, "create")==0 || strcmp(cmd, "c")==0) {
1095 icedemo_create_instance();
1097 } else if (strcmp(cmd, "destroy")==0 || strcmp(cmd, "d")==0) {
1099 icedemo_destroy_instance();
1101 } else if (strcmp(cmd, "init")==0 || strcmp(cmd, "i")==0) {
1103 char *role = strtok(NULL, SEP);
1105 icedemo_init_session(*role);
1107 puts( "error: Role required");
1109 } else if (strcmp(cmd, "stop")==0 || strcmp(cmd, "e")==0) {
1111 icedemo_stop_session();
1113 } else if (strcmp(cmd, "show")==0 || strcmp(cmd, "s")==0) {
1117 } else if (strcmp(cmd, "remote")==0 || strcmp(cmd, "r")==0) {
1119 icedemo_input_remote();
1121 } else if (strcmp(cmd, "start")==0 || strcmp(cmd, "b")==0) {
1123 icedemo_start_nego();
1125 } else if (strcmp(cmd, "send")==0 || strcmp(cmd, "x")==0) {
1127 char *comp = strtok(NULL, SEP);
1130 PJ_LOG(1,(THIS_FILE, "Error: component ID required"));
1132 char *data = comp + strlen(comp) + 1;
1135 icedemo_send_data(atoi(comp), data);
1138 } else if (strcmp(cmd, "help")==0 || strcmp(cmd, "h")==0) {
1140 icedemo_help_menu();
1142 } else if (strcmp(cmd, "quit")==0 || strcmp(cmd, "q")==0) {
1148 printf( "Invalid command '%s'\n", cmd);
1158static void icedemo_usage()
1160 puts( "Usage: icedemo [optons]");
1163 puts( "General options:");
1164 puts( " --comp-cnt, -c N Component count (default=1)");
1165 puts( " --nameserver, -n IP Configure nameserver to activate DNS SRV");
1166 puts( " resolution");
1167 puts( " --max-host, -H N Set max number of host candidates to N");
1168 puts( " --regular, -R Use regular nomination (default aggressive)");
1169 puts( " --log-file, -L FILE Save output to log FILE");
1170 puts( " --help, -h Display this screen.");
1172 puts( "STUN related options:");
1173 puts( " --stun-srv, -s HOSTDOM Enable srflx candidate by resolving to STUN server.");
1174 puts( " HOSTDOM may be a \"host_or_ip[:port]\" or a domain");
1175 puts( " name if DNS SRV resolution is used.");
1177 puts( "TURN related options:");
1178 puts( " --turn-srv, -t HOSTDOM Enable relayed candidate by using this TURN server.");
1179 puts( " HOSTDOM may be a \"host_or_ip[:port]\" or a domain");
1180 puts( " name if DNS SRV resolution is used.");
1181 puts( " --turn-tcp, -T Use TCP to connect to TURN server");
1182 puts( " --turn-username, -u UID Set TURN username of the credential to UID");
1183 puts( " --turn-password, -p PWD Set password of the credential to WPWD");
1184 puts( " --turn-fingerprint, -F Use fingerprint for outgoing TURN requests");
1192int main( int argc, char *argv[])
1195 { "comp-cnt", 1, 0, 'c'},
1196 { "nameserver", 1, 0, 'n'},
1197 { "max-host", 1, 0, 'H'},
1198 { "help", 0, 0, 'h'},
1199 { "stun-srv", 1, 0, 's'},
1200 { "turn-srv", 1, 0, 't'},
1201 { "turn-tcp", 0, 0, 'T'},
1202 { "turn-username", 1, 0, 'u'},
1203 { "turn-password", 1, 0, 'p'},
1204 { "turn-fingerprint", 0, 0, 'F'},
1205 { "regular", 0, 0, 'R'},
1206 { "log-file", 1, 0, 'L'},
1211 icedemo.opt.comp_cnt = 1;
1212 icedemo.opt.max_host = -1;
1214 while((c=pj_getopt_long(argc,argv, "c:n:s:t:u:p:H:L:hTFR", long_options, &opt_id))!=-1) {
1217 icedemo.opt.comp_cnt = atoi(pj_optarg);
1218 if (icedemo.opt.comp_cnt < 1 || icedemo.opt.comp_cnt >= PJ_ICE_MAX_COMP) {
1219 puts( "Invalid component count value");
1224 icedemo.opt.ns = pj_str(pj_optarg);
1227 icedemo.opt.max_host = atoi(pj_optarg);
1233 icedemo.opt.stun_srv = pj_str(pj_optarg);
1236 icedemo.opt.turn_srv = pj_str(pj_optarg);
1239 icedemo.opt.turn_tcp = PJ_TRUE;
1242 icedemo.opt.turn_username = pj_str(pj_optarg);
1245 icedemo.opt.turn_password = pj_str(pj_optarg);
1248 icedemo.opt.turn_fingerprint = PJ_TRUE;
1251 icedemo.opt.regular = PJ_TRUE;
1254 icedemo.opt.log_file = pj_optarg;
1257 printf( "Argument \"%s\" is not valid. Use -h to see help",
1263 status = icedemo_init();
const char * pj_get_version(void)
pj_status_t pjlib_util_init(void)
#define PJ_STUN_PORT Definition: config.h:122
#define PJ_ICE_MAX_COMP Definition: config.h:288
#define PJ_ICE_ST_MAX_CAND Definition: config.h:250
pj_ice_sess_role Definition: ice_session.h:553
const char * pj_ice_get_cand_type_name(pj_ice_cand_type type)
@ PJ_ICE_SESS_ROLE_CONTROLLING Definition: ice_session.h:567
@ PJ_ICE_SESS_ROLE_CONTROLLED Definition: ice_session.h:562
@ PJ_ICE_CAND_TYPE_RELAYED Definition: ice_session.h:156
@ PJ_ICE_CAND_TYPE_HOST Definition: ice_session.h:137
@ PJ_ICE_CAND_TYPE_SRFLX Definition: ice_session.h:144
pj_bool_t pj_ice_strans_sess_is_complete(pj_ice_strans *ice_st)
pj_status_t pj_ice_strans_destroy(pj_ice_strans *ice_st)
pj_bool_t pj_ice_strans_sess_is_running(pj_ice_strans *ice_st)
pj_status_t pj_ice_strans_sendto2(pj_ice_strans *ice_st, unsigned comp_id, const void *data, pj_size_t data_len, const pj_sockaddr_t *dst_addr, int dst_addr_len)
pj_ice_sess_role pj_ice_strans_get_role(pj_ice_strans *ice_st)
pj_status_t pj_ice_strans_start_ice(pj_ice_strans *ice_st, const pj_str_t *rem_ufrag, const pj_str_t *rem_passwd, unsigned rcand_cnt, const pj_ice_sess_cand rcand[])
pj_bool_t pj_ice_strans_has_sess(pj_ice_strans *ice_st)
pj_status_t pj_ice_strans_enum_cands(pj_ice_strans *ice_st, unsigned comp_id, unsigned *count, pj_ice_sess_cand cand[])
pj_status_t pj_ice_strans_get_ufrag_pwd(pj_ice_strans *ice_st, pj_str_t *loc_ufrag, pj_str_t *loc_pwd, pj_str_t *rem_ufrag, pj_str_t *rem_pwd)
unsigned pj_ice_strans_get_running_comp_cnt(pj_ice_strans *ice_st)
pj_ice_strans_op Definition: ice_strans.h:128
void pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg)
struct pj_ice_strans pj_ice_strans Definition: ice_strans.h:124
pj_status_t pj_ice_strans_stop_ice(pj_ice_strans *ice_st)
pj_status_t pj_ice_strans_init_ice(pj_ice_strans *ice_st, pj_ice_sess_role role, const pj_str_t *local_ufrag, const pj_str_t *local_passwd)
pj_status_t pj_ice_strans_create(const char *name, const pj_ice_strans_cfg *cfg, unsigned comp_cnt, void *user_data, const pj_ice_strans_cb *cb, pj_ice_strans **p_ice_st)
pj_status_t pj_ice_strans_get_def_cand(pj_ice_strans *ice_st, unsigned comp_id, pj_ice_sess_cand *cand)
@ PJ_ICE_STRANS_OP_INIT Definition: ice_strans.h:130
@ PJ_ICE_STRANS_OP_NEGOTIATION Definition: ice_strans.h:133
@ PJ_STUN_AUTH_CRED_STATIC Definition: stun_auth.h:74
@ PJ_STUN_PASSWD_PLAIN Definition: stun_auth.h:95
@ PJ_TURN_TP_TCP Definition: turn_session.h:148
@ PJ_TURN_TP_UDP Definition: turn_session.h:143
pj_status_t pjnath_init(void)
pj_status_t pj_init(void)
unsigned short pj_uint16_t
struct pj_thread_t pj_thread_t
void pj_caching_pool_destroy(pj_caching_pool *ch_pool)
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
pj_status_t pj_dns_resolver_set_ns(pj_dns_resolver *resolver, unsigned count, const pj_str_t servers[], const pj_uint16_t ports[])
pj_status_t pj_dns_resolver_create(pj_pool_factory *pf, const char *name, unsigned options, pj_timer_heap_t *timer, pj_ioqueue_t *ioqueue, pj_dns_resolver **p_resolver)
pj_status_t pj_ioqueue_destroy(pj_ioqueue_t *ioque)
pj_status_t pj_ioqueue_create(pj_pool_t *pool, pj_size_t max_fd, pj_ioqueue_t **ioqueue)
int pj_ioqueue_poll(pj_ioqueue_t *ioque, const pj_time_val *timeout)
void pj_log_write(int level, const char *buffer, int len)
#define PJ_LOG(level, arg)
void pj_log_set_log_func(pj_log_func *func)
pj_pool_t * pj_pool_create(pj_pool_factory *factory, const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback)
pj_str_t pj_str(char *str)
pj_str_t * pj_strdup2(pj_pool_t *pool, pj_str_t *dst, const char *src)
const pj_str_t * pj_cstr(pj_str_t *str, const char *s)
char * pj_strchr(const pj_str_t *str, int chr)
void pj_bzero(void *dst, pj_size_t size)
pj_status_t pj_sockaddr_init(int af, pj_sockaddr *addr, const pj_str_t *cp, pj_uint16_t port)
char * pj_sockaddr_print(const pj_sockaddr_t *addr, char *buf, int size, unsigned flags)
#define PJ_INET6_ADDRSTRLEN
pj_uint16_t pj_sockaddr_get_port(const pj_sockaddr_t *addr)
pj_status_t pj_sockaddr_set_port(pj_sockaddr *addr, pj_uint16_t hostport)
pj_status_t pj_sockaddr_set_str_addr(int af, pj_sockaddr *addr, const pj_str_t *cp)
unsigned pj_sockaddr_get_len(const pj_sockaddr_t *addr)
pj_status_t pj_thread_destroy(pj_thread_t *thread)
pj_status_t pj_thread_join(pj_thread_t *thread)
pj_status_t pj_thread_create(pj_pool_t *pool, const char *thread_name, pj_thread_proc *proc, void *arg, pj_size_t stack_size, unsigned flags, pj_thread_t **thread)
pj_status_t pj_thread_sleep(unsigned msec)
unsigned pj_timer_heap_poll(pj_timer_heap_t *ht, pj_time_val *next_delay)
void pj_timer_heap_destroy(pj_timer_heap_t *ht)
pj_status_t pj_timer_heap_create(pj_pool_t *pool, pj_size_t count, pj_timer_heap_t **ht)
#define PJ_TIME_VAL_GT(t1, t2)
#define PJ_TIME_VAL_MSEC(t)
#define PJ_UNUSED_ARG(arg)
int pj_tolower(unsigned char c)
int pj_isspace(unsigned char c)
pj_str_t pj_strerror(pj_status_t statcode, char *buf, pj_size_t bufsize)
pj_status_t pj_get_netos_error(void)
Definition: ice_session.h:242
pj_sockaddr addr Definition: ice_session.h:302
pj_str_t foundation Definition: ice_session.h:284
pj_ice_cand_type type Definition: ice_session.h:251
pj_uint32_t prio Definition: ice_session.h:291
pj_uint8_t comp_id Definition: ice_session.h:266
Definition: ice_strans.h:151
void(* on_rx_data)(pj_ice_strans *ice_st, unsigned comp_id, void *pkt, pj_size_t size, const pj_sockaddr_t *src_addr, unsigned src_addr_len) Definition: ice_strans.h:164
void(* on_ice_complete)(pj_ice_strans *ice_st, pj_ice_strans_op op, pj_status_t status) Definition: ice_strans.h:198
Definition: ice_strans.h:386
.
|
PJNATH - Open Source NAT traversal helper library supporting STUN, TURN, and ICE
Copyright (C) 2006-2009 Teluu Inc.
|