Changeset 1104 for pjproject/trunk
- Timestamp:
- Mar 25, 2007 6:44:51 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 3 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/build/pjlib_util.vcproj
r1102 r1104 17 17 <Configuration 18 18 Name="Release|Win32" 19 OutputDirectory=". \./output/pjlib-util-i386-win32-vc6-release"20 IntermediateDirectory=". \./output/pjlib-util-i386-win32-vc6-release"19 OutputDirectory="./output/pjlib-util-i386-win32-vc8-release" 20 IntermediateDirectory="./output/pjlib-util-i386-win32-vc8-release" 21 21 ConfigurationType="4" 22 22 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" … … 49 49 RuntimeLibrary="2" 50 50 EnableFunctionLevelLinking="true" 51 PrecompiledHeaderFile=". \./output/pjlib-util-i386-win32-vc6-release/pjlib_util.pch"52 AssemblerListingLocation=". \./output/pjlib-util-i386-win32-vc6-release/"53 ObjectFile=". \./output/pjlib-util-i386-win32-vc6-release/"54 ProgramDataBaseFileName=". \./output/pjlib-util-i386-win32-vc6-release/"51 PrecompiledHeaderFile="./output/pjlib-util-i386-win32-vc8-release/pjlib_util.pch" 52 AssemblerListingLocation="./output/pjlib-util-i386-win32-vc8-release/" 53 ObjectFile="./output/pjlib-util-i386-win32-vc8-release/" 54 ProgramDataBaseFileName="./output/pjlib-util-i386-win32-vc8-release/" 55 55 BrowseInformation="1" 56 56 WarningLevel="4" … … 71 71 <Tool 72 72 Name="VCLibrarianTool" 73 OutputFile="../lib/pjlib-util-i386-win32-vc 6-release.lib"73 OutputFile="../lib/pjlib-util-i386-win32-vc8-release.lib" 74 74 SuppressStartupBanner="true" 75 75 /> … … 83 83 Name="VCBscMakeTool" 84 84 SuppressStartupBanner="true" 85 OutputFile=". \./output/pjlib-util-i386-win32-vc6-release/pjlib_util.bsc"85 OutputFile="./output/pjlib-util-i386-win32-vc8-release/pjlib_util.bsc" 86 86 /> 87 87 <Tool … … 94 94 <Configuration 95 95 Name="Debug|Win32" 96 OutputDirectory=". \./output/pjlib-util-i386-win32-vc6-debug"97 IntermediateDirectory=". \./output/pjlib-util-i386-win32-vc6-debug"96 OutputDirectory="./output/pjlib-util-i386-win32-vc8-debug" 97 IntermediateDirectory="./output/pjlib-util-i386-win32-vc8-debug" 98 98 ConfigurationType="4" 99 99 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" … … 125 125 BasicRuntimeChecks="3" 126 126 RuntimeLibrary="1" 127 PrecompiledHeaderFile=". \./output/pjlib-util-i386-win32-vc6-debug/pjlib_util.pch"128 AssemblerListingLocation=". \./output/pjlib-util-i386-win32-vc6-debug/"129 ObjectFile=". \./output/pjlib-util-i386-win32-vc6-debug/"130 ProgramDataBaseFileName=". \./output/pjlib-util-i386-win32-vc6-debug/"127 PrecompiledHeaderFile="./output/pjlib-util-i386-win32-vc8-debug/pjlib_util.pch" 128 AssemblerListingLocation="./output/pjlib-util-i386-win32-vc8-debug/" 129 ObjectFile="./output/pjlib-util-i386-win32-vc8-debug/" 130 ProgramDataBaseFileName="./output/pjlib-util-i386-win32-vc8-debug/" 131 131 BrowseInformation="1" 132 132 WarningLevel="4" … … 147 147 <Tool 148 148 Name="VCLibrarianTool" 149 OutputFile="../lib/pjlib-util-i386-win32-vc 6-debug.lib"149 OutputFile="../lib/pjlib-util-i386-win32-vc8-debug.lib" 150 150 SuppressStartupBanner="true" 151 151 /> … … 159 159 Name="VCBscMakeTool" 160 160 SuppressStartupBanner="true" 161 OutputFile=". \./output/pjlib-util-i386-win32-vc6-debug/pjlib_util.bsc"161 OutputFile="./output/pjlib-util-i386-win32-vc8-debug/pjlib_util.bsc" 162 162 /> 163 163 <Tool -
pjproject/trunk/pjlib/build/pjlib.dsp
r950 r1104 111 111 # Begin Source File 112 112 113 SOURCE=..\src\pj\ip_helper_generic.c 114 # PROP Exclude_From_Build 1 115 # End Source File 116 # Begin Source File 117 113 118 SOURCE=..\src\pj\log_writer_printk.c 114 119 # PROP Exclude_From_Build 1 … … 252 257 !ENDIF 253 258 259 # End Source File 260 # Begin Source File 261 262 SOURCE=..\src\pj\ip_helper_win32.c 254 263 # End Source File 255 264 # Begin Source File … … 516 525 517 526 SOURCE=..\include\pj\ioqueue.h 527 # End Source File 528 # Begin Source File 529 530 SOURCE=..\include\pj\ip_helper.h 518 531 # End Source File 519 532 # Begin Source File -
pjproject/trunk/pjlib/build/pjlib.vcproj
r1100 r1104 17 17 <Configuration 18 18 Name="Debug|Win32" 19 OutputDirectory=".\output\pjlib-i386-win32-vc 6-debug"20 IntermediateDirectory=".\output\pjlib-i386-win32-vc 6-debug"19 OutputDirectory=".\output\pjlib-i386-win32-vc8-debug" 20 IntermediateDirectory=".\output\pjlib-i386-win32-vc8-debug" 21 21 ConfigurationType="4" 22 22 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" … … 48 48 BasicRuntimeChecks="3" 49 49 RuntimeLibrary="1" 50 PrecompiledHeaderFile=".\output\pjlib-i386-win32-vc 6-debug/pjlib.pch"51 AssemblerListingLocation=".\output\pjlib-i386-win32-vc 6-debug/"52 ObjectFile=".\output\pjlib-i386-win32-vc 6-debug/"53 ProgramDataBaseFileName=".\output\pjlib-i386-win32-vc 6-debug/"50 PrecompiledHeaderFile=".\output\pjlib-i386-win32-vc8-debug/pjlib.pch" 51 AssemblerListingLocation=".\output\pjlib-i386-win32-vc8-debug/" 52 ObjectFile=".\output\pjlib-i386-win32-vc8-debug/" 53 ProgramDataBaseFileName=".\output\pjlib-i386-win32-vc8-debug/" 54 54 BrowseInformation="1" 55 55 WarningLevel="4" … … 70 70 <Tool 71 71 Name="VCLibrarianTool" 72 OutputFile="../lib/pjlib-i386-win32-vc 6-debug.lib"72 OutputFile="../lib/pjlib-i386-win32-vc8-debug.lib" 73 73 SuppressStartupBanner="true" 74 74 /> … … 82 82 Name="VCBscMakeTool" 83 83 SuppressStartupBanner="true" 84 OutputFile=".\output\pjlib-i386-win32-vc 6-debug/pjlib.bsc"84 OutputFile=".\output\pjlib-i386-win32-vc8-debug/pjlib.bsc" 85 85 /> 86 86 <Tool … … 93 93 <Configuration 94 94 Name="Release|Win32" 95 OutputDirectory=".\output\pjlib-i386-win32-vc 6-release"96 IntermediateDirectory=".\output\pjlib-i386-win32-vc 6-release"95 OutputDirectory=".\output\pjlib-i386-win32-vc8-release" 96 IntermediateDirectory=".\output\pjlib-i386-win32-vc8-release" 97 97 ConfigurationType="4" 98 98 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops" … … 125 125 RuntimeLibrary="2" 126 126 EnableFunctionLevelLinking="true" 127 PrecompiledHeaderFile=".\output\pjlib-i386-win32-vc 6-release/pjlib.pch"128 AssemblerListingLocation=".\output\pjlib-i386-win32-vc 6-release/"129 ObjectFile=".\output\pjlib-i386-win32-vc 6-release/"130 ProgramDataBaseFileName=".\output\pjlib-i386-win32-vc 6-release/"127 PrecompiledHeaderFile=".\output\pjlib-i386-win32-vc8-release/pjlib.pch" 128 AssemblerListingLocation=".\output\pjlib-i386-win32-vc8-release/" 129 ObjectFile=".\output\pjlib-i386-win32-vc8-release/" 130 ProgramDataBaseFileName=".\output\pjlib-i386-win32-vc8-release/" 131 131 BrowseInformation="1" 132 132 WarningLevel="4" … … 147 147 <Tool 148 148 Name="VCLibrarianTool" 149 OutputFile="../lib/pjlib-i386-win32-vc 6-release.lib"149 OutputFile="../lib/pjlib-i386-win32-vc8-release.lib" 150 150 SuppressStartupBanner="true" 151 151 /> … … 159 159 Name="VCBscMakeTool" 160 160 SuppressStartupBanner="true" 161 OutputFile=".\output\pjlib-i386-win32-vc 6-release/pjlib.bsc"161 OutputFile=".\output\pjlib-i386-win32-vc8-release/pjlib.bsc" 162 162 /> 163 163 <Tool … … 539 539 </File> 540 540 <File 541 RelativePath="..\src\pj\ip_helper_win32.c" 542 > 543 </File> 544 <File 541 545 RelativePath="..\src\pj\list.c" 542 546 > … … 1118 1122 AdditionalIncludeDirectories="" 1119 1123 PreprocessorDefinitions="" 1124 /> 1125 </FileConfiguration> 1126 </File> 1127 <File 1128 RelativePath="..\src\pj\ip_helper_generic.c" 1129 > 1130 <FileConfiguration 1131 Name="Debug|Win32" 1132 ExcludedFromBuild="true" 1133 > 1134 <Tool 1135 Name="VCCLCompilerTool" 1136 /> 1137 </FileConfiguration> 1138 <FileConfiguration 1139 Name="Release|Win32" 1140 ExcludedFromBuild="true" 1141 > 1142 <Tool 1143 Name="VCCLCompilerTool" 1120 1144 /> 1121 1145 </FileConfiguration> … … 1460 1484 </File> 1461 1485 <File 1486 RelativePath="..\include\pj\ip_helper.h" 1487 > 1488 </File> 1489 <File 1462 1490 RelativePath="..\include\pj\list.h" 1463 1491 > -
pjproject/trunk/pjlib/include/pj/sock.h
r1080 r1104 208 208 }; 209 209 210 #undef s6_addr 210 211 211 212 /** -
pjproject/trunk/pjlib/include/pjlib.h
r974 r1104 38 38 #include <pj/hash.h> 39 39 #include <pj/ioqueue.h> 40 #include <pj/ip_helper.h> 40 41 #include <pj/list.h> 41 42 #include <pj/lock.h> -
pjproject/trunk/pjmedia/include/pjmedia/transport_ice.h
r1098 r1104 47 47 PJ_DECL(pj_status_t) pjmedia_ice_destroy(pjmedia_transport *tp); 48 48 49 PJ_DECL(pj_ice_st*) pjmedia_ice_get_ice_st(pjmedia_transport *tp); 49 PJ_DECL(pj_status_t) pjmedia_ice_start_init(pjmedia_transport *tp, 50 unsigned options, 51 const pj_sockaddr_in *start_addr, 52 const pj_sockaddr_in *stun_srv, 53 const pj_sockaddr_in *turn_srv); 54 PJ_DECL(pj_status_t) pjmedia_ice_get_init_status(pjmedia_transport *tp); 50 55 56 PJ_DECL(pj_status_t) pjmedia_ice_get_comp(pjmedia_transport *tp, 57 unsigned comp_id, 58 pj_ice_st_comp *comp); 51 59 52 60 PJ_DECL(pj_status_t) pjmedia_ice_init_ice(pjmedia_transport *tp, -
pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c
r1101 r1104 70 70 * And these are ICE callbacks. 71 71 */ 72 static void ice_on_rx_data(pj_ice_st *ice_st, 73 unsigned comp_id, unsigned cand_id, 72 static void ice_on_rx_data(pj_ice_st *ice_st, unsigned comp_id, 74 73 void *pkt, pj_size_t size, 75 74 const pj_sockaddr_t *src_addr, … … 100 99 pj_ice_st_cb ice_st_cb; 101 100 struct transport_ice *tp_ice; 102 unsigned i;103 101 pj_status_t status; 104 102 … … 111 109 112 110 /* Create ICE */ 113 status = pj_ice_st_create(stun_cfg, name, NULL, &ice_st_cb, &ice_st); 111 status = pj_ice_st_create(stun_cfg, name, comp_cnt, NULL, 112 &ice_st_cb, &ice_st); 114 113 if (status != PJ_SUCCESS) 115 114 return status; 116 115 117 /* Add components */118 for (i=0; i<comp_cnt; ++i) {119 status = pj_ice_st_add_comp(ice_st, i+1);120 if (status != PJ_SUCCESS)121 goto on_error;122 }123 116 124 117 /* Create transport instance and attach to ICE */ … … 136 129 137 130 return PJ_SUCCESS; 138 139 on_error:140 pj_ice_st_destroy(ice_st);141 return status;142 131 } 143 132 … … 158 147 159 148 160 PJ_DECL(pj_ice_st*) pjmedia_ice_get_ice_st(pjmedia_transport *tp) 149 PJ_DEF(pj_status_t) pjmedia_ice_start_init( pjmedia_transport *tp, 150 unsigned options, 151 const pj_sockaddr_in *start_addr, 152 const pj_sockaddr_in *stun_srv, 153 const pj_sockaddr_in *turn_srv) 154 { 155 struct transport_ice *tp_ice = (struct transport_ice*)tp; 156 unsigned comp_id; 157 pj_status_t status; 158 159 status = pj_ice_st_set_stun_srv(tp_ice->ice_st, stun_srv, turn_srv); 160 if (status != PJ_SUCCESS) 161 return status; 162 163 status = pj_ice_st_create_comp(tp_ice->ice_st, 1, options, start_addr, 164 &comp_id); 165 if (status != PJ_SUCCESS) 166 return status; 167 168 if (tp_ice->ice_st->comp_cnt > 1) { 169 pj_sockaddr_in addr; 170 171 pj_memcpy(&addr, &tp_ice->ice_st->comp[0]->local_addr.ipv4, 172 sizeof(pj_sockaddr_in)); 173 if (start_addr) 174 addr.sin_addr.s_addr = start_addr->sin_addr.s_addr; 175 else 176 addr.sin_addr.s_addr = 0; 177 178 addr.sin_port = (pj_uint16_t)(pj_ntohs(addr.sin_port)+1); 179 status = pj_ice_st_create_comp(tp_ice->ice_st, 2, options, 180 &addr, &comp_id); 181 if (status != PJ_SUCCESS) 182 return status; 183 } 184 return status; 185 } 186 187 188 PJ_DEF(pj_status_t) pjmedia_ice_get_init_status(pjmedia_transport *tp) 189 { 190 struct transport_ice *tp_ice = (struct transport_ice*)tp; 191 return pj_ice_st_get_comps_status(tp_ice->ice_st); 192 } 193 194 195 PJ_DEF(pj_status_t) pjmedia_ice_get_comp( pjmedia_transport *tp, 196 unsigned comp_id, 197 pj_ice_st_comp *comp) 198 { 199 struct transport_ice *tp_ice = (struct transport_ice*)tp; 200 PJ_ASSERT_RETURN(tp && comp_id && comp_id <= tp_ice->ice_st->comp_cnt && 201 comp, PJ_EINVAL); 202 203 pj_memcpy(comp, tp_ice->ice_st->comp[comp_id-1], sizeof(pj_ice_st_comp)); 204 return PJ_SUCCESS; 205 } 206 207 PJ_DEF(pj_ice_st*) pjmedia_ice_get_ice_st(pjmedia_transport *tp) 161 208 { 162 209 struct transport_ice *tp_ice = (struct transport_ice*)tp; … … 416 463 { 417 464 struct transport_ice *tp_ice = (struct transport_ice*)tp; 418 int rel_idx = -1, srflx_idx = -1, host_idx = -1, idx = -1;419 unsigned i;465 pj_ice_st *ice_st = tp_ice->ice_st; 466 pj_ice_st_comp *comp; 420 467 421 468 pj_bzero(info, sizeof(*info)); 422 469 info->rtp_sock = info->rtcp_sock = PJ_INVALID_SOCKET; 423 470 424 for (i=0; i<tp_ice->ice_st->itf_cnt; ++i) { 425 pj_ice_st_interface *itf = tp_ice->ice_st->itfs[i]; 426 427 if (itf->type == PJ_ICE_CAND_TYPE_HOST && host_idx == -1) 428 host_idx = i; 429 else if (itf->type == PJ_ICE_CAND_TYPE_RELAYED && rel_idx == -1) 430 rel_idx = i; 431 else if (itf->type == PJ_ICE_CAND_TYPE_SRFLX && srflx_idx == -1) 432 srflx_idx = i; 433 } 434 435 if (idx == -1 && srflx_idx != -1) 436 idx = srflx_idx; 437 else if (idx == -1 && rel_idx != -1) 438 idx = rel_idx; 439 else if (idx == -1 && host_idx != -1) 440 idx = host_idx; 441 442 PJ_ASSERT_RETURN(idx != -1, PJ_EBUG); 443 444 pj_memcpy(&info->rtp_addr_name, &tp_ice->ice_st->itfs[idx]->addr, 471 /* Retrieve address of default candidate for component 1 (RTP) */ 472 comp = ice_st->comp[0]; 473 pj_assert(comp->default_cand >= 0); 474 info->rtp_sock = comp->sock; 475 pj_memcpy(&info->rtp_addr_name, 476 &comp->cand_list[comp->default_cand].addr, 445 477 sizeof(pj_sockaddr_in)); 478 479 /* Retrieve address of default candidate for component 12(RTCP) */ 480 if (ice_st->comp_cnt > 1) { 481 comp = ice_st->comp[1]; 482 pj_assert(comp->default_cand >= 0); 483 info->rtp_sock = comp->sock; 484 pj_memcpy(&info->rtp_addr_name, 485 &comp->cand_list[comp->default_cand].addr, 486 sizeof(pj_sockaddr_in)); 487 } 488 446 489 447 490 return PJ_SUCCESS; … … 492 535 { 493 536 struct transport_ice *tp_ice = (struct transport_ice*)tp; 494 if (tp_ice->ice_st->ice) { 495 return pj_ice_st_send_data(tp_ice->ice_st, 1, pkt, size); 496 } else { 497 return pj_ice_st_sendto(tp_ice->ice_st, 1, 0, 498 pkt, size, &tp_ice->remote_rtp, 499 sizeof(pj_sockaddr_in)); 500 } 537 return pj_ice_st_sendto(tp_ice->ice_st, 1, 538 pkt, size, &tp_ice->remote_rtp, 539 sizeof(pj_sockaddr_in)); 501 540 } 502 541 … … 506 545 pj_size_t size) 507 546 { 508 #if 0 509 struct transport_ice *tp_ice = (struct transport_ice*)tp; 510 return pj_ice_st_send_data(tp_ice->ice_st, 1, pkt, size); 511 #else 512 PJ_TODO(SUPPORT_RTCP); 513 PJ_UNUSED_ARG(tp); 514 PJ_UNUSED_ARG(pkt); 515 PJ_UNUSED_ARG(size); 516 return PJ_SUCCESS; 517 #endif 518 } 519 520 521 static void ice_on_rx_data(pj_ice_st *ice_st, 522 unsigned comp_id, unsigned cand_id, 547 struct transport_ice *tp_ice = (struct transport_ice*)tp; 548 if (tp_ice->ice_st->comp_cnt > 1) { 549 return pj_ice_st_sendto(tp_ice->ice_st, 2, 550 pkt, size, &tp_ice->remote_rtp, 551 sizeof(pj_sockaddr_in)); 552 } else { 553 return PJ_SUCCESS; 554 } 555 } 556 557 558 static void ice_on_rx_data(pj_ice_st *ice_st, unsigned comp_id, 523 559 void *pkt, pj_size_t size, 524 560 const pj_sockaddr_t *src_addr, … … 532 568 (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size); 533 569 534 PJ_UNUSED_ARG(cand_id);535 570 PJ_UNUSED_ARG(src_addr); 536 571 PJ_UNUSED_ARG(src_addr_len); 572 573 PJ_TODO(SWITCH_SOURCE_ADDRESS); 537 574 } 538 575 -
pjproject/trunk/pjnath/include/pjnath/ice.h
r1101 r1104 151 151 unsigned dst_addr_len); 152 152 void (*on_rx_data)(pj_ice *ice, unsigned comp_id, 153 unsigned cand_id,154 153 void *pkt, pj_size_t size, 155 154 const pj_sockaddr_t *src_addr, -
pjproject/trunk/pjnath/include/pjnath/ice_stream_transport.h
r1099 r1104 45 45 { 46 46 void (*on_rx_data)(pj_ice_st *ice_st, 47 unsigned comp_id, unsigned cand_id,47 unsigned comp_id, 48 48 void *pkt, pj_size_t size, 49 49 const pj_sockaddr_t *src_addr, … … 55 55 56 56 57 #ifndef PJ_ICE_ST_MAX_ALIASES 58 # define PJ_ICE_ST_MAX_ALIASES 8 59 #endif 60 61 enum pj_ice_st_option 62 { 63 PJ_ICE_ST_OPT_DISABLE_STUN = 1, 64 PJ_ICE_ST_OPT_DISABLE_RELAY = 2, 65 PJ_ICE_ST_OPT_NO_PORT_RETRY = 4, 66 }; 67 68 69 typedef struct pj_ice_st_cand 70 { 71 pj_ice_cand_type type; 72 pj_status_t status; 73 pj_sockaddr addr; 74 int cand_id; 75 pj_uint16_t local_pref; 76 pj_str_t foundation; 77 } pj_ice_st_cand; 78 79 57 80 typedef struct pj_ice_st_comp 58 81 { 82 pj_ice_st *ice_st; 59 83 unsigned comp_id; 60 } pj_ice_st_comp; 84 pj_uint32_t options; 85 pj_sock_t sock; 61 86 87 pj_stun_session *stun_sess; 62 88 63 typedef struct pj_ice_st_interface 64 { 65 pj_ice_st *ice_st; 66 pj_ice_cand_type type; 67 pj_status_t status; 68 unsigned comp_id; 69 int cand_id; 70 pj_str_t foundation; 71 pj_uint16_t local_pref; 72 pj_sock_t sock; 73 pj_sockaddr addr; 74 pj_sockaddr base_addr; 89 pj_sockaddr local_addr; 90 91 unsigned pending_cnt; 92 pj_status_t last_status; 93 94 unsigned cand_cnt; 95 pj_ice_st_cand cand_list[PJ_ICE_ST_MAX_ALIASES]; 96 int default_cand; 97 75 98 pj_ioqueue_key_t *key; 76 99 pj_uint8_t pkt[1500]; … … 79 102 pj_sockaddr src_addr; 80 103 int src_addr_len; 81 pj_stun_session *stun_sess; 82 } pj_ice_st_ interface;104 105 } pj_ice_st_comp; 83 106 84 107 … … 94 117 95 118 unsigned comp_cnt; 96 unsigned comps[PJ_ICE_MAX_COMP]; 97 98 unsigned itf_cnt; 99 pj_ice_st_interface *itfs[PJ_ICE_MAX_CAND]; 119 pj_ice_st_comp **comp; 100 120 101 121 pj_dns_resolver *resolver; 102 pj_bool_t relay_enabled; 103 pj_str_t stun_domain; 122 pj_bool_t has_resolver_job; 104 123 pj_sockaddr_in stun_srv; 124 pj_sockaddr_in turn_srv; 105 125 }; 106 126 … … 108 128 PJ_DECL(pj_status_t) pj_ice_st_create(pj_stun_config *stun_cfg, 109 129 const char *name, 130 unsigned comp_cnt, 110 131 void *user_data, 111 132 const pj_ice_st_cb *cb, … … 113 134 PJ_DECL(pj_status_t) pj_ice_st_destroy(pj_ice_st *ice_st); 114 135 115 PJ_DECL(pj_status_t) pj_ice_st_set_stun(pj_ice_st *ice_st, 116 pj_dns_resolver *resolver, 117 pj_bool_t enable_relay, 118 const pj_str_t *domain); 119 PJ_DECL(pj_status_t) pj_ice_st_set_stun_addr(pj_ice_st *ice_st, 120 pj_bool_t enable_relay, 121 const pj_sockaddr_in *srv_addr); 136 PJ_DECL(pj_status_t) pj_ice_st_set_stun_domain(pj_ice_st *ice_st, 137 pj_dns_resolver *resolver, 138 const pj_str_t *domain); 139 PJ_DECL(pj_status_t) pj_ice_st_set_stun_srv(pj_ice_st *ice_st, 140 const pj_sockaddr_in *stun_srv, 141 const pj_sockaddr_in *turn_srv); 122 142 123 PJ_DECL(pj_status_t) pj_ice_st_add_comp(pj_ice_st *ice_st, 124 unsigned comp_id); 143 PJ_DECL(pj_status_t) pj_ice_st_create_comp(pj_ice_st *ice_st, 144 unsigned comp_id, 145 pj_uint32_t options, 146 const pj_sockaddr_in *addr, 147 unsigned *p_itf_id); 125 148 126 PJ_DECL(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st, 127 unsigned comp_id, 128 pj_uint16_t local_pref, 129 const pj_sockaddr_in *addr, 130 unsigned *p_itf_id); 131 PJ_DECL(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st, 132 unsigned comp_id, 133 unsigned port); 134 PJ_DECL(pj_status_t) pj_ice_st_add_stun_interface(pj_ice_st *ice_st, 135 unsigned comp_id, 136 unsigned local_port, 137 unsigned *p_itf_id); 138 PJ_DECL(pj_status_t) pj_ice_st_add_relay_interface(pj_ice_st *ice_st, 139 unsigned comp_id, 140 unsigned local_port, 141 pj_bool_t notify, 142 void *notify_data); 143 PJ_DECL(pj_status_t) pj_ice_st_get_interfaces_status(pj_ice_st *ice_st); 149 PJ_DECL(pj_status_t) pj_ice_st_get_comps_status(pj_ice_st *ice_st); 144 150 145 151 PJ_DECL(pj_status_t) pj_ice_st_init_ice(pj_ice_st *ice_st, … … 157 163 PJ_DECL(pj_status_t) pj_ice_st_stop_ice(pj_ice_st *ice_st); 158 164 159 PJ_DECL(pj_status_t) pj_ice_st_send_data(pj_ice_st *ice_st,160 unsigned comp_id,161 const void *data,162 pj_size_t data_len);163 165 PJ_DECL(pj_status_t) pj_ice_st_sendto(pj_ice_st *ice_st, 164 166 unsigned comp_id, 165 unsigned itf_id,166 167 const void *data, 167 168 pj_size_t data_len, -
pjproject/trunk/pjnath/src/pjnath/ice.c
r1101 r1104 1710 1710 NULL, src_addr, src_addr_len); 1711 1711 } else { 1712 (*ice->cb.on_rx_data)(ice, comp_id, cand_id,pkt, pkt_size,1712 (*ice->cb.on_rx_data)(ice, comp_id, pkt, pkt_size, 1713 1713 src_addr, src_addr_len); 1714 1714 } -
pjproject/trunk/pjnath/src/pjnath/ice_stream_transport.c
r1101 r1104 21 21 #include <pj/addr_resolv.h> 22 22 #include <pj/assert.h> 23 #include <pj/ip_helper.h> 23 24 #include <pj/log.h> 24 25 #include <pj/pool.h> … … 29 30 /* ICE callbacks */ 30 31 static void on_ice_complete(pj_ice *ice, pj_status_t status); 31 static pj_status_t on_tx_pkt(pj_ice *ice, 32 unsigned comp_id, unsigned cand_id, 33 const void *pkt, pj_size_t size, 34 const pj_sockaddr_t *dst_addr, 35 unsigned dst_addr_len); 36 static void on_rx_data(pj_ice *ice, 32 static pj_status_t ice_tx_pkt(pj_ice *ice, 37 33 unsigned comp_id, unsigned cand_id, 34 const void *pkt, pj_size_t size, 35 const pj_sockaddr_t *dst_addr, 36 unsigned dst_addr_len); 37 static void ice_rx_data(pj_ice *ice, 38 unsigned comp_id, 38 39 void *pkt, pj_size_t size, 39 40 const pj_sockaddr_t *src_addr, … … 45 46 pj_ssize_t bytes_read); 46 47 47 static void destroy_ ice_interface(pj_ice_st_interface *is);48 static void destroy_component(pj_ice_st_comp *comp); 48 49 static void destroy_ice_st(pj_ice_st *ice_st, pj_status_t reason); 49 50 … … 86 87 87 88 /* 88 * Create new interface (i.e. socket)89 */90 static pj_status_t create_ice_interface(pj_ice_st *ice_st,91 pj_ice_cand_type type,92 unsigned comp_id,93 pj_uint16_t local_pref,94 const pj_sockaddr_in *addr,95 pj_ice_st_interface **p_is)96 {97 pj_ioqueue_callback ioqueue_cb;98 pj_ice_st_interface *is;99 char foundation[32];100 int addr_len;101 pj_status_t status;102 103 is = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_st_interface);104 is->type = type;105 is->comp_id = comp_id;106 is->cand_id = -1;107 is->sock = PJ_INVALID_SOCKET;108 is->ice_st = ice_st;109 is->local_pref = local_pref;110 111 status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &is->sock);112 if (status != PJ_SUCCESS)113 return status;114 115 /* Bind and get the local IP address */116 if (addr)117 pj_memcpy(&is->base_addr, addr, sizeof(pj_sockaddr_in));118 else119 pj_sockaddr_in_init(&is->base_addr.ipv4, NULL, 0);120 121 status = pj_sock_bind(is->sock, &is->base_addr, sizeof(pj_sockaddr_in));122 if (status != PJ_SUCCESS)123 goto on_error;124 125 addr_len = sizeof(is->base_addr);126 status = pj_sock_getsockname(is->sock, &is->base_addr, &addr_len);127 if (status != PJ_SUCCESS)128 goto on_error;129 130 if (is->base_addr.ipv4.sin_addr.s_addr == 0) {131 status = pj_gethostip(&is->base_addr.ipv4.sin_addr);132 if (status != PJ_SUCCESS)133 goto on_error;134 }135 136 /* Assign foundation */137 pj_ansi_snprintf(foundation, sizeof(foundation), "%c%x",138 get_type_prefix(type),139 (int)pj_ntohl(is->base_addr.ipv4.sin_addr.s_addr));140 pj_strdup2(ice_st->pool, &is->foundation, foundation);141 142 143 /* Register to ioqueue */144 pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));145 ioqueue_cb.on_read_complete = &on_read_complete;146 status = pj_ioqueue_register_sock(ice_st->pool, ice_st->stun_cfg.ioqueue,147 is->sock, is, &ioqueue_cb, &is->key);148 if (status != PJ_SUCCESS)149 goto on_error;150 151 pj_ioqueue_op_key_init(&is->read_op, sizeof(is->read_op));152 pj_ioqueue_op_key_init(&is->write_op, sizeof(is->write_op));153 154 /* Kick start reading the socket */155 on_read_complete(is->key, &is->read_op, 0);156 157 /* Done */158 *p_is = is;159 return PJ_SUCCESS;160 161 on_error:162 destroy_ice_interface(is);163 return status;164 }165 166 /*167 * This is callback called by ioqueue on incoming packet168 */169 static void on_read_complete(pj_ioqueue_key_t *key,170 pj_ioqueue_op_key_t *op_key,171 pj_ssize_t bytes_read)172 {173 pj_ice_st_interface *is = (pj_ice_st_interface*)174 pj_ioqueue_get_user_data(key);175 pj_ice_st *ice_st = is->ice_st;176 pj_ssize_t pkt_size;177 pj_status_t status;178 179 if (bytes_read > 0) {180 181 /* If we have an active ICE session, hand over all incoming182 * packets to the ICE session. Otherwise just drop the packet.183 */184 if (ice_st->ice) {185 status = pj_ice_on_rx_pkt(ice_st->ice,186 is->comp_id, is->cand_id,187 is->pkt, bytes_read,188 &is->src_addr, is->src_addr_len);189 } else if (is->stun_sess) {190 status = pj_stun_msg_check(is->pkt, bytes_read, PJ_STUN_IS_DATAGRAM);191 if (status == PJ_SUCCESS) {192 status = pj_stun_session_on_rx_pkt(is->stun_sess, is->pkt,193 bytes_read,194 PJ_STUN_IS_DATAGRAM, NULL,195 &is->src_addr,196 is->src_addr_len);197 } else {198 (*ice_st->cb.on_rx_data)(ice_st, is->comp_id, is->cand_id,199 is->pkt, bytes_read,200 &is->src_addr, is->src_addr_len);201 202 }203 } else {204 (*ice_st->cb.on_rx_data)(ice_st, is->comp_id, is->cand_id,205 is->pkt, bytes_read,206 &is->src_addr, is->src_addr_len);207 }208 209 } else if (bytes_read < 0) {210 ice_st_perror(is->ice_st, "ioqueue read callback error", -bytes_read);211 }212 213 /* Read next packet */214 pkt_size = sizeof(is->pkt);215 is->src_addr_len = sizeof(is->src_addr);216 status = pj_ioqueue_recvfrom(key, op_key, is->pkt, &pkt_size,217 PJ_IOQUEUE_ALWAYS_ASYNC,218 &is->src_addr, &is->src_addr_len);219 if (status != PJ_SUCCESS && status != PJ_EPENDING) {220 ice_st_perror(is->ice_st, "ioqueue recvfrom() error", status);221 }222 }223 224 /*225 * Destroy an interface226 */227 static void destroy_ice_interface(pj_ice_st_interface *is)228 {229 if (is->stun_sess) {230 pj_stun_session_destroy(is->stun_sess);231 is->stun_sess = NULL;232 }233 234 if (is->key) {235 pj_ioqueue_unregister(is->key);236 is->key = NULL;237 is->sock = PJ_INVALID_SOCKET;238 } else if (is->sock != PJ_INVALID_SOCKET && is->sock != 0) {239 pj_sock_close(is->sock);240 is->sock = PJ_INVALID_SOCKET;241 }242 }243 244 /*245 89 * Create ICE stream transport 246 90 */ 247 91 PJ_DECL(pj_status_t) pj_ice_st_create(pj_stun_config *stun_cfg, 248 92 const char *name, 93 unsigned comp_cnt, 249 94 void *user_data, 250 95 const pj_ice_st_cb *cb, … … 254 99 pj_ice_st *ice_st; 255 100 256 PJ_ASSERT_RETURN(stun_cfg && c b && p_ice_st, PJ_EINVAL);101 PJ_ASSERT_RETURN(stun_cfg && comp_cnt && cb && p_ice_st, PJ_EINVAL); 257 102 PJ_ASSERT_RETURN(stun_cfg->ioqueue && stun_cfg->timer_heap, PJ_EINVAL); 258 103 … … 266 111 ice_st->user_data = user_data; 267 112 113 ice_st->comp_cnt = comp_cnt; 114 ice_st->comp = (pj_ice_st_comp**) pj_pool_calloc(pool, comp_cnt, 115 sizeof(void*)); 116 268 117 pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 269 118 pj_memcpy(&ice_st->stun_cfg, stun_cfg, sizeof(*stun_cfg)); 270 119 120 271 121 PJ_LOG(4,(ice_st->obj_name, "ICE stream transport created")); 272 122 … … 275 125 } 276 126 127 /* Destroy ICE */ 277 128 static void destroy_ice_st(pj_ice_st *ice_st, pj_status_t reason) 278 129 { … … 291 142 } 292 143 293 /* Destroy all interfaces */ 294 for (i=0; i<ice_st->itf_cnt; ++i) { 295 destroy_ice_interface(ice_st->itfs[i]); 296 ice_st->itfs[i] = NULL; 297 } 298 ice_st->itf_cnt = 0; 144 /* Destroy all components */ 145 for (i=0; i<ice_st->comp_cnt; ++i) { 146 if (ice_st->comp[i]) { 147 destroy_component(ice_st->comp[i]); 148 ice_st->comp[i] = NULL; 149 } 150 } 151 ice_st->comp_cnt = 0; 299 152 300 153 /* Done */ … … 318 171 * Resolve STUN server 319 172 */ 320 PJ_DEF(pj_status_t) pj_ice_st_set_stun( pj_ice_st *ice_st, 321 pj_dns_resolver *resolver, 322 pj_bool_t enable_relay, 323 const pj_str_t *domain) 173 PJ_DEF(pj_status_t) pj_ice_st_set_stun_domain(pj_ice_st *ice_st, 174 pj_dns_resolver *resolver, 175 const pj_str_t *domain) 324 176 { 325 177 /* Yeah, TODO */ 326 178 PJ_UNUSED_ARG(ice_st); 327 179 PJ_UNUSED_ARG(resolver); 328 PJ_UNUSED_ARG(enable_relay);329 180 PJ_UNUSED_ARG(domain); 330 181 return -1; … … 334 185 * Set STUN server address. 335 186 */ 336 PJ_DEF(pj_status_t) pj_ice_st_set_stun_addr( pj_ice_st *ice_st, 337 pj_bool_t enable_relay, 338 const pj_sockaddr_in *srv_addr) 339 { 340 341 PJ_ASSERT_RETURN(ice_st && srv_addr, PJ_EINVAL); 342 343 ice_st->relay_enabled = enable_relay; 344 pj_strdup2(ice_st->pool, &ice_st->stun_domain, 345 pj_inet_ntoa(srv_addr->sin_addr)); 346 pj_memcpy(&ice_st->stun_srv, srv_addr, sizeof(pj_sockaddr_in)); 187 PJ_DEF(pj_status_t) pj_ice_st_set_stun_srv( pj_ice_st *ice_st, 188 const pj_sockaddr_in *stun_srv, 189 const pj_sockaddr_in *turn_srv) 190 { 191 PJ_ASSERT_RETURN(ice_st, PJ_EINVAL); 192 /* Must not have pending resolver job */ 193 PJ_ASSERT_RETURN(ice_st->has_resolver_job==PJ_FALSE, PJ_EINVALIDOP); 194 195 if (stun_srv) { 196 pj_memcpy(&ice_st->stun_srv, stun_srv, sizeof(pj_sockaddr_in)); 197 } else { 198 pj_bzero(&ice_st->stun_srv, sizeof(pj_sockaddr_in)); 199 } 200 201 if (turn_srv) { 202 pj_memcpy(&ice_st->turn_srv, turn_srv, sizeof(pj_sockaddr_in)); 203 } else { 204 pj_bzero(&ice_st->turn_srv, sizeof(pj_sockaddr_in)); 205 } 347 206 348 207 return PJ_SUCCESS; 349 208 } 350 209 351 /* 352 * Add new component. 353 */ 354 PJ_DEF(pj_status_t) pj_ice_st_add_comp(pj_ice_st *ice_st, 355 unsigned comp_id) 356 { 357 /* Verify arguments */ 358 PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL); 359 360 /* Can only add component when we don't have active ICE session */ 361 PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY); 362 363 /* Check that we don't have too many components */ 364 PJ_ASSERT_RETURN(ice_st->comp_cnt < PJ_ICE_MAX_COMP, PJ_ETOOMANY); 365 366 /* Component ID must be valid */ 367 PJ_ASSERT_RETURN(comp_id <= PJ_ICE_MAX_COMP, PJNATH_EICEINCOMPID); 368 369 /* First component ID must be 1, second must be 2, etc., and 370 * they must be registered in order. 371 */ 372 PJ_ASSERT_RETURN(ice_st->comps[comp_id-1] == ice_st->comp_cnt, 373 PJNATH_EICEINCOMPID); 374 375 /* All in order, add the component. */ 376 ice_st->comps[ice_st->comp_cnt++] = comp_id; 377 378 return PJ_SUCCESS; 379 } 380 381 /* Add interface */ 382 static void add_interface(pj_ice_st *ice_st, pj_ice_st_interface *is, 383 unsigned *p_itf_id) 384 { 385 unsigned itf_id; 386 387 itf_id = ice_st->itf_cnt++; 388 ice_st->itfs[itf_id] = is; 389 390 if (p_itf_id) 391 *p_itf_id = itf_id; 392 } 393 394 /* 395 * Add new host interface. 396 */ 397 PJ_DEF(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st, 398 unsigned comp_id, 399 pj_uint16_t local_pref, 400 const pj_sockaddr_in *addr, 401 unsigned *p_itf_id) 402 { 403 pj_ice_st_interface *is; 210 211 /* Calculate foundation */ 212 static pj_str_t calc_foundation(pj_pool_t *pool, 213 pj_ice_cand_type type, 214 const pj_in_addr *base_addr) 215 { 216 char foundation[32]; 217 pj_str_t result; 218 219 pj_ansi_snprintf(foundation, sizeof(foundation), "%c%x", 220 get_type_prefix(type), 221 (int)pj_ntohl(base_addr->s_addr)); 222 pj_strdup2(pool, &result, foundation); 223 224 return result; 225 } 226 227 /* Create new component (i.e. socket) */ 228 static pj_status_t create_component(pj_ice_st *ice_st, 229 unsigned comp_id, 230 pj_uint32_t options, 231 const pj_sockaddr_in *addr, 232 pj_ice_st_comp **p_comp) 233 { 234 enum { MAX_RETRY=100, PORT_INC=2 }; 235 pj_ioqueue_callback ioqueue_cb; 236 pj_ice_st_comp *comp; 237 int retry, addr_len; 404 238 pj_status_t status; 405 239 406 /* Verify arguments */ 407 PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL); 408 409 /* Check that component ID present */ 410 PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID); 411 412 /* Can't add new interface while ICE is running */ 413 PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY); 414 415 /* Create interface */ 416 status = create_ice_interface(ice_st, PJ_ICE_CAND_TYPE_HOST, comp_id, 417 local_pref, addr, &is); 240 comp = PJ_POOL_ZALLOC_T(ice_st->pool, pj_ice_st_comp); 241 comp->ice_st = ice_st; 242 comp->comp_id = comp_id; 243 comp->options = options; 244 comp->sock = PJ_INVALID_SOCKET; 245 comp->last_status = PJ_SUCCESS; 246 247 /* Create socket */ 248 status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &comp->sock); 418 249 if (status != PJ_SUCCESS) 419 250 return status; 420 251 421 /* For host interface, the address is the base address */ 422 pj_memcpy(&is->addr, &is->base_addr, sizeof(is->addr)); 423 424 /* Store this interface */ 425 add_interface(ice_st, is, p_itf_id); 426 427 /* Set interface status to SUCCESS */ 428 is->status = PJ_SUCCESS; 252 /* Init address */ 253 if (addr) 254 pj_memcpy(&comp->local_addr, addr, sizeof(pj_sockaddr_in)); 255 else 256 pj_sockaddr_in_init(&comp->local_addr.ipv4, NULL, 0); 257 258 /* Retry binding socket */ 259 for (retry=0; retry<MAX_RETRY; ++retry) { 260 pj_uint16_t port; 261 262 status = pj_sock_bind(comp->sock, &comp->local_addr, 263 sizeof(pj_sockaddr_in)); 264 if (status == PJ_SUCCESS) 265 break; 266 267 if (options & PJ_ICE_ST_OPT_NO_PORT_RETRY) 268 goto on_error; 269 270 port = pj_ntohs(comp->local_addr.ipv4.sin_port); 271 port += PORT_INC; 272 comp->local_addr.ipv4.sin_port = pj_htons(port); 273 } 274 275 /* Get the actual port where the socket is bound to. 276 * (don't care about the address, it will be retrieved later) 277 */ 278 addr_len = sizeof(comp->local_addr); 279 status = pj_sock_getsockname(comp->sock, &comp->local_addr, &addr_len); 280 if (status != PJ_SUCCESS) 281 goto on_error; 282 283 /* Register to ioqueue */ 284 pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb)); 285 ioqueue_cb.on_read_complete = &on_read_complete; 286 status = pj_ioqueue_register_sock(ice_st->pool, ice_st->stun_cfg.ioqueue, 287 comp->sock, comp, &ioqueue_cb, 288 &comp->key); 289 if (status != PJ_SUCCESS) 290 goto on_error; 291 292 pj_ioqueue_op_key_init(&comp->read_op, sizeof(comp->read_op)); 293 pj_ioqueue_op_key_init(&comp->write_op, sizeof(comp->write_op)); 294 295 /* Kick start reading the socket */ 296 on_read_complete(comp->key, &comp->read_op, 0); 297 298 /* If the socket is bound to INADDR_ANY, then lookup all interfaces in 299 * the host and add them into cand_list. Otherwise if the socket is bound 300 * to a specific interface, then only add that specific interface to 301 * cand_list. 302 */ 303 if (comp->local_addr.ipv4.sin_addr.s_addr == 0) { 304 /* Socket is bound to INADDR_ANY */ 305 unsigned i, ifs_cnt; 306 pj_in_addr ifs[PJ_ICE_ST_MAX_ALIASES-2]; 307 308 /* Reset default candidate */ 309 comp->default_cand = -1; 310 311 /* Enum all IP interfaces in the host */ 312 ifs_cnt = PJ_ARRAY_SIZE(ifs); 313 status = pj_enum_ip_interface(&ifs_cnt, ifs); 314 if (status != PJ_SUCCESS) 315 goto on_error; 316 317 /* Set default IP interface as the base address */ 318 status = pj_gethostip(&comp->local_addr.ipv4.sin_addr); 319 if (status != PJ_SUCCESS) 320 return status; 321 322 /* Add candidate entry for each interface */ 323 for (i=0; i<ifs_cnt; ++i) { 324 pj_ice_st_cand *cand = &comp->cand_list[i]; 325 326 cand->type = PJ_ICE_CAND_TYPE_HOST; 327 cand->status = PJ_SUCCESS; 328 pj_memcpy(&cand->addr, &comp->local_addr, sizeof(pj_sockaddr_in)); 329 cand->addr.ipv4.sin_addr.s_addr = ifs[i].s_addr; 330 cand->cand_id = -1; 331 cand->local_pref = 65535; 332 cand->foundation = calc_foundation(ice_st->pool, 333 PJ_ICE_CAND_TYPE_HOST, 334 &cand->addr.ipv4.sin_addr); 335 336 /* If the IP address is equal to local address, assign it 337 * as default candidate. 338 */ 339 if (cand->addr.ipv4.sin_addr.s_addr == 340 comp->local_addr.ipv4.sin_addr.s_addr) 341 { 342 comp->default_cand = i; 343 } 344 345 PJ_LOG(5,(ice_st->obj_name, 346 "Interface %s:%d added to component %d", 347 pj_inet_ntoa(cand->addr.ipv4.sin_addr), 348 (int)pj_ntohs(cand->addr.ipv4.sin_port), comp_id)); 349 } 350 comp->cand_cnt = ifs_cnt; 351 352 353 } else { 354 /* Socket is bound to specific address. 355 * In this case only add that address as a single entry in the 356 * cand_list table. 357 */ 358 pj_ice_st_cand *cand = &comp->cand_list[0]; 359 360 cand->type = PJ_ICE_CAND_TYPE_HOST; 361 cand->status = PJ_SUCCESS; 362 pj_memcpy(&cand->addr, &comp->local_addr, sizeof(pj_sockaddr_in)); 363 cand->cand_id = -1; 364 cand->local_pref = 65535; 365 cand->foundation = calc_foundation(ice_st->pool, 366 PJ_ICE_CAND_TYPE_HOST, 367 &cand->addr.ipv4.sin_addr); 368 369 comp->cand_cnt = 1; 370 comp->default_cand = 0; 371 372 PJ_LOG(5,(ice_st->obj_name, 373 "Interface %s:%d added to component %d", 374 pj_inet_ntoa(cand->addr.ipv4.sin_addr), 375 (int)pj_ntohs(cand->addr.ipv4.sin_port), comp_id)); 376 377 } 378 379 /* Done */ 380 if (p_comp) 381 *p_comp = comp; 429 382 430 383 return PJ_SUCCESS; 431 } 432 433 /* 434 * Enumerate and add all host interfaces. 435 */ 436 PJ_DEF(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st, 437 unsigned comp_id, 438 unsigned port) 439 { 440 pj_sockaddr_in addr; 384 385 on_error: 386 destroy_component(comp); 387 return status; 388 } 389 390 /* 391 * This is callback called by ioqueue on incoming packet 392 */ 393 static void on_read_complete(pj_ioqueue_key_t *key, 394 pj_ioqueue_op_key_t *op_key, 395 pj_ssize_t bytes_read) 396 { 397 pj_ice_st_comp *comp = (pj_ice_st_comp*) 398 pj_ioqueue_get_user_data(key); 399 pj_ice_st *ice_st = comp->ice_st; 400 pj_ssize_t pkt_size; 441 401 pj_status_t status; 442 402 443 /* Yeah, TODO. 444 * For now just add the default interface. 445 */ 446 pj_sockaddr_in_init(&addr, NULL, (pj_uint16_t)port); 447 448 status = pj_gethostip(&addr.sin_addr); 449 if (status != PJ_SUCCESS) 450 return status; 451 452 return pj_ice_st_add_host_interface(ice_st, comp_id, 65535, &addr, NULL); 453 } 454 455 /* 456 * Add STUN mapping interface. 457 */ 458 PJ_DEF(pj_status_t) pj_ice_st_add_stun_interface(pj_ice_st *ice_st, 459 unsigned comp_id, 460 unsigned local_port, 461 unsigned *p_itf_id) 462 { 463 pj_ice_st_interface *is; 464 pj_sockaddr_in local_addr; 403 if (bytes_read > 0) { 404 /* 405 * Okay, we got a packet from the socket for the component. There is 406 * a bit of situation here, since this packet could be one of these: 407 * 408 * 1) this could be the response of STUN binding request sent by 409 * this component to a) an initial request to get the STUN mapped 410 * address of this component, or b) subsequent request to keep 411 * the binding alive. 412 * 413 * 2) this could be a packet (STUN or not STUN) sent from the STUN 414 * relay server. In this case, still there are few options to do 415 * for this packet: a) process this locally if this packet is 416 * related to TURN session management (e.g. Allocate response), 417 * b) forward this packet to ICE if this is related to ICE 418 * discovery process. 419 * 420 * 3) this could be a STUN request or response sent as part of ICE 421 * discovery process. 422 * 423 * 4) this could be application's packet, e.g. when ICE processing 424 * is done and agents start sending RTP/RTCP packets to each 425 * other, or when ICE processing is not done and this ICE stream 426 * transport decides to allow sending data. 427 * 428 * So far we don't have good solution for this. 429 * The process below is just a workaround. 430 */ 431 if (ice_st->ice) { 432 PJ_TODO(DISTINGUISH_BETWEEN_LOCAL_AND_RELAY); 433 status = pj_ice_on_rx_pkt(ice_st->ice, comp->comp_id, 434 comp->cand_list[0].cand_id, 435 comp->pkt, bytes_read, 436 &comp->src_addr, comp->src_addr_len); 437 } else if (comp->stun_sess) { 438 status = pj_stun_msg_check(comp->pkt, bytes_read, 439 PJ_STUN_IS_DATAGRAM); 440 if (status == PJ_SUCCESS) { 441 status = pj_stun_session_on_rx_pkt(comp->stun_sess, comp->pkt, 442 bytes_read, 443 PJ_STUN_IS_DATAGRAM, NULL, 444 &comp->src_addr, 445 comp->src_addr_len); 446 } else { 447 (*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, 448 comp->pkt, bytes_read, 449 &comp->src_addr, comp->src_addr_len); 450 451 } 452 } else { 453 (*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, 454 comp->pkt, bytes_read, 455 &comp->src_addr, comp->src_addr_len); 456 } 457 458 } else if (bytes_read < 0) { 459 ice_st_perror(comp->ice_st, "ioqueue read callback error", 460 -bytes_read); 461 } 462 463 /* Read next packet */ 464 pkt_size = sizeof(comp->pkt); 465 comp->src_addr_len = sizeof(comp->src_addr); 466 status = pj_ioqueue_recvfrom(key, op_key, comp->pkt, &pkt_size, 467 PJ_IOQUEUE_ALWAYS_ASYNC, 468 &comp->src_addr, &comp->src_addr_len); 469 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 470 ice_st_perror(comp->ice_st, "ioqueue recvfrom() error", status); 471 } 472 } 473 474 /* 475 * Destroy a component 476 */ 477 static void destroy_component(pj_ice_st_comp *comp) 478 { 479 if (comp->stun_sess) { 480 pj_stun_session_destroy(comp->stun_sess); 481 comp->stun_sess = NULL; 482 } 483 484 if (comp->key) { 485 pj_ioqueue_unregister(comp->key); 486 comp->key = NULL; 487 comp->sock = PJ_INVALID_SOCKET; 488 } else if (comp->sock != PJ_INVALID_SOCKET && comp->sock != 0) { 489 pj_sock_close(comp->sock); 490 comp->sock = PJ_INVALID_SOCKET; 491 } 492 } 493 494 495 496 /* 497 * Add STUN mapping to a component. 498 */ 499 static pj_status_t get_stun_mapped_addr(pj_ice_st *ice_st, 500 pj_ice_st_comp *comp) 501 { 502 pj_ice_st_cand *cand; 465 503 pj_stun_session_cb sess_cb; 466 504 pj_stun_tx_data *tdata; 467 505 pj_status_t status; 468 506 469 PJ_ASSERT_RETURN(ice_st && comp _id, PJ_EINVAL);507 PJ_ASSERT_RETURN(ice_st && comp, PJ_EINVAL); 470 508 471 /* STUN server must have been configured */ 472 PJ_ASSERT_RETURN(ice_st->stun_srv.sin_family != 0, PJ_EINVALIDOP); 473 474 475 /* Create interface */ 476 pj_sockaddr_in_init(&local_addr, NULL, (pj_uint16_t)local_port); 477 status = create_ice_interface(ice_st, PJ_ICE_CAND_TYPE_SRFLX, comp_id, 478 65535, &local_addr, &is); 479 if (status != PJ_SUCCESS) 480 return status; 481 482 /* Create STUN session */ 509 /* Bail out if STUN server is still being resolved */ 510 if (ice_st->has_resolver_job) 511 return PJ_EBUSY; 512 513 /* Just return (successfully) if STUN server is not configured */ 514 if (ice_st->stun_srv.sin_family == 0) 515 return PJ_SUCCESS; 516 517 518 /* Create STUN session for this component */ 483 519 pj_bzero(&sess_cb, sizeof(sess_cb)); 484 520 sess_cb.on_request_complete = &stun_on_request_complete; 485 521 sess_cb.on_send_msg = &stun_on_send_msg; 486 522 status = pj_stun_session_create(&ice_st->stun_cfg, ice_st->obj_name, 487 &sess_cb, PJ_FALSE, & is->stun_sess);523 &sess_cb, PJ_FALSE, &comp->stun_sess); 488 524 if (status != PJ_SUCCESS) 489 goto on_error;490 491 /* Associate interfacewith STUN session */492 pj_stun_session_set_user_data( is->stun_sess, (void*)is);493 494 /* Create and sendSTUN binding request */495 status = pj_stun_session_create_req( is->stun_sess,525 return status; 526 527 /* Associate component with STUN session */ 528 pj_stun_session_set_user_data(comp->stun_sess, (void*)comp); 529 530 /* Create STUN binding request */ 531 status = pj_stun_session_create_req(comp->stun_sess, 496 532 PJ_STUN_BINDING_REQUEST, &tdata); 497 533 if (status != PJ_SUCCESS) 498 goto on_error; 499 500 status = pj_stun_session_send_msg(is->stun_sess, PJ_FALSE, 534 return status; 535 536 /* Attach alias instance to tdata */ 537 cand = &comp->cand_list[comp->cand_cnt]; 538 tdata->user_data = (void*)cand; 539 540 /* Send STUN binding request */ 541 status = pj_stun_session_send_msg(comp->stun_sess, PJ_FALSE, 501 542 &ice_st->stun_srv, 502 543 sizeof(pj_sockaddr_in), tdata); 503 544 if (status != PJ_SUCCESS) 504 goto on_error; 505 506 /* Mark interface as pending */ 507 is->status = PJ_EPENDING; 508 509 add_interface(ice_st, is, p_itf_id); 545 return status; 546 547 548 /* Add new alias to this component */ 549 cand->type = PJ_ICE_CAND_TYPE_SRFLX; 550 cand->status = PJ_EPENDING; 551 cand->cand_id = -1; 552 cand->local_pref = 65535; 553 cand->foundation = calc_foundation(ice_st->pool, PJ_ICE_CAND_TYPE_SRFLX, 554 &comp->local_addr.ipv4.sin_addr); 555 556 ++comp->cand_cnt; 557 558 /* Add pending count for this component */ 559 comp->pending_cnt++; 510 560 511 561 return PJ_SUCCESS; 512 513 on_error: 514 destroy_ice_interface(is); 515 return status; 516 } 517 518 /* 519 * Add TURN mapping interface. 520 */ 521 PJ_DEF(pj_status_t) pj_ice_st_add_relay_interface(pj_ice_st *ice_st, 522 unsigned comp_id, 523 unsigned local_port, 524 pj_bool_t notify, 525 void *notify_data) 526 { 527 /* Yeah, TODO */ 528 PJ_UNUSED_ARG(ice_st); 529 PJ_UNUSED_ARG(comp_id); 530 PJ_UNUSED_ARG(local_port); 531 PJ_UNUSED_ARG(notify); 532 PJ_UNUSED_ARG(notify_data); 533 return -1; 534 } 535 536 PJ_DEF(pj_status_t) pj_ice_st_get_interfaces_status(pj_ice_st *ice_st) 562 } 563 564 565 /* 566 * Create the component. 567 */ 568 PJ_DEF(pj_status_t) pj_ice_st_create_comp(pj_ice_st *ice_st, 569 unsigned comp_id, 570 pj_uint32_t options, 571 const pj_sockaddr_in *addr, 572 unsigned *p_itf_id) 573 { 574 pj_ice_st_comp *comp; 575 pj_status_t status; 576 577 /* Verify arguments */ 578 PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL); 579 580 /* Check that component ID present */ 581 PJ_ASSERT_RETURN(comp_id <= ice_st->comp_cnt, PJNATH_EICEINCOMPID); 582 583 /* Can't add new component while ICE is running */ 584 PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY); 585 586 /* Can't add new component while resolver is running */ 587 PJ_ASSERT_RETURN(ice_st->has_resolver_job == PJ_FALSE, PJ_EBUSY); 588 589 590 /* Create component */ 591 status = create_component(ice_st, comp_id, options, addr, &comp); 592 if (status != PJ_SUCCESS) 593 return status; 594 595 if ((options & PJ_ICE_ST_OPT_DISABLE_STUN) == 0) { 596 status = get_stun_mapped_addr(ice_st, comp); 597 if (status != PJ_SUCCESS) { 598 destroy_component(comp); 599 return status; 600 } 601 } 602 603 /* Store this component */ 604 if (p_itf_id) 605 *p_itf_id = ice_st->comp_cnt; 606 607 ice_st->comp[comp_id-1] = comp; 608 609 return PJ_SUCCESS; 610 } 611 612 613 PJ_DEF(pj_status_t) pj_ice_st_get_comps_status(pj_ice_st *ice_st) 537 614 { 538 615 unsigned i; 539 616 pj_status_t worst = PJ_SUCCESS; 540 617 541 for (i=0; i<ice_st-> itf_cnt; ++i) {542 pj_ice_st_ interface *itf = ice_st->itfs[i];543 544 if ( itf->status == PJ_SUCCESS) {618 for (i=0; i<ice_st->comp_cnt; ++i) { 619 pj_ice_st_comp *comp = ice_st->comp[i]; 620 621 if (comp->last_status == PJ_SUCCESS) { 545 622 /* okay */ 546 } else if (itf->status == PJ_EPENDING && worst==PJ_SUCCESS) { 547 worst = itf->status; 548 } else { 549 worst = itf->status; 623 } else if (comp->pending_cnt && worst==PJ_SUCCESS) { 624 worst = PJ_EPENDING; 625 break; 626 } else if (comp->last_status != PJ_SUCCESS) { 627 worst = comp->last_status; 628 break; 550 629 } 630 631 if (worst != PJ_SUCCESS) 632 break; 551 633 } 552 634 … … 574 656 pj_bzero(&ice_cb, sizeof(ice_cb)); 575 657 ice_cb.on_ice_complete = &on_ice_complete; 576 ice_cb.on_rx_data = & on_rx_data;577 ice_cb.on_tx_pkt = & on_tx_pkt;658 ice_cb.on_rx_data = &ice_rx_data; 659 ice_cb.on_tx_pkt = &ice_tx_pkt; 578 660 579 661 /* Create! */ … … 588 670 589 671 /* Add candidates */ 590 for (i=0; i<ice_st->itf_cnt; ++i) { 591 pj_ice_st_interface *is= ice_st->itfs[i]; 592 status = pj_ice_add_cand(ice_st->ice, is->comp_id, is->type, 593 is->local_pref, &is->foundation, 594 &is->addr, &is->base_addr, NULL, 595 sizeof(pj_sockaddr_in), 596 (unsigned*)&is->cand_id); 597 if (status != PJ_SUCCESS) 598 goto on_error; 672 for (i=0; i<ice_st->comp_cnt; ++i) { 673 unsigned j; 674 pj_ice_st_comp *comp= ice_st->comp[i]; 675 676 for (j=0; j<comp->cand_cnt; ++j) { 677 pj_ice_st_cand *cand = &comp->cand_list[j]; 678 679 /* Skip if candidate is not ready */ 680 if (cand->status != PJ_SUCCESS) { 681 PJ_LOG(5,(ice_st->obj_name, 682 "Candidate %d in component %d is not added", 683 j, i)); 684 continue; 685 } 686 687 status = pj_ice_add_cand(ice_st->ice, comp->comp_id, cand->type, 688 cand->local_pref, &cand->foundation, 689 &cand->addr, &comp->local_addr, NULL, 690 sizeof(pj_sockaddr_in), 691 (unsigned*)&cand->cand_id); 692 if (status != PJ_SUCCESS) 693 goto on_error; 694 } 599 695 } 600 696 … … 602 698 603 699 on_error: 604 for (i=0; i<ice_st->itf_cnt; ++i) { 605 ice_st->itfs[i]->cand_id = -1; 606 } 607 if (ice_st->ice) { 608 pj_ice_destroy(ice_st->ice); 609 ice_st->ice = NULL; 610 } 700 pj_ice_st_stop_ice(ice_st); 611 701 return status; 612 702 } … … 654 744 return status; 655 745 656 return pj_ice_start_check(ice_st->ice); 746 status = pj_ice_start_check(ice_st->ice); 747 if (status != PJ_SUCCESS) { 748 pj_ice_st_stop_ice(ice_st); 749 } 750 751 return status; 657 752 } 658 753 … … 662 757 PJ_DECL(pj_status_t) pj_ice_st_stop_ice(pj_ice_st *ice_st) 663 758 { 759 unsigned i; 760 664 761 if (ice_st->ice) { 665 762 pj_ice_destroy(ice_st->ice); … … 667 764 } 668 765 766 /* Invalidate all candidate Ids */ 767 for (i=0; i<ice_st->comp_cnt; ++i) { 768 unsigned j; 769 for (j=0; j<ice_st->comp[i]->cand_cnt; ++j) { 770 ice_st->comp[i]->cand_list[j].cand_id = -1; 771 } 772 } 773 669 774 return PJ_SUCCESS; 670 }671 672 /*673 * Send data to peer agent.674 */675 PJ_DEF(pj_status_t) pj_ice_st_send_data( pj_ice_st *ice_st,676 unsigned comp_id,677 const void *data,678 pj_size_t data_len)679 {680 if (!ice_st->ice)681 return PJNATH_ENOICE;682 683 return pj_ice_send_data(ice_st->ice, comp_id, data, data_len);684 775 } 685 776 … … 689 780 PJ_DEF(pj_status_t) pj_ice_st_sendto( pj_ice_st *ice_st, 690 781 unsigned comp_id, 691 unsigned itf_id,692 782 const void *data, 693 783 pj_size_t data_len, … … 696 786 { 697 787 pj_ssize_t pkt_size; 698 pj_ice_st_ interface *is = ice_st->itfs[itf_id];788 pj_ice_st_comp *comp; 699 789 pj_status_t status; 700 790 791 PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt && 792 dst_addr && dst_addr_len, PJ_EINVAL); 793 794 comp = ice_st->comp[comp_id-1]; 795 796 /* If ICE is available, send data with ICE */ 797 if (ice_st->ice) { 798 return pj_ice_send_data(ice_st->ice, comp_id, data, data_len); 799 } 800 801 /* Otherwise send direcly with the socket */ 701 802 pkt_size = data_len; 702 status = pj_ioqueue_sendto( is->key, &is->write_op,803 status = pj_ioqueue_sendto(comp->key, &comp->write_op, 703 804 data, &pkt_size, 0, 704 805 dst_addr, dst_addr_len); … … 722 823 * Callback called by ICE session when it wants to send outgoing packet. 723 824 */ 724 static pj_status_t on_tx_pkt(pj_ice *ice,725 unsigned comp_id, unsigned cand_id,726 const void *pkt, pj_size_t size,727 const pj_sockaddr_t *dst_addr,728 unsigned dst_addr_len)825 static pj_status_t ice_tx_pkt(pj_ice *ice, 826 unsigned comp_id, unsigned cand_id, 827 const void *pkt, pj_size_t size, 828 const pj_sockaddr_t *dst_addr, 829 unsigned dst_addr_len) 729 830 { 730 831 pj_ice_st *ice_st = (pj_ice_st*)ice->user_data; 731 pj_ice_st_interface *is = NULL; 732 unsigned i; 832 pj_ice_st_comp *comp = NULL; 733 833 pj_ssize_t pkt_size; 734 834 pj_status_t status; 735 835 736 PJ_UNUSED_ARG(comp_id); 737 738 for (i=0; i<ice_st->itf_cnt; ++i) { 739 if (ice_st->itfs[i]->cand_id == (int)cand_id) { 740 is = ice_st->itfs[i]; 741 break; 742 } 743 } 744 if (is == NULL) { 745 return PJNATH_EICEINCANDID; 746 } 836 PJ_TODO(TX_TO_RELAY); 837 838 PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); 839 comp = ice_st->comp[comp_id-1]; 747 840 748 841 pkt_size = size; 749 status = pj_ioqueue_sendto( is->key, &is->write_op,842 status = pj_ioqueue_sendto(comp->key, &comp->write_op, 750 843 pkt, &pkt_size, 0, 751 844 dst_addr, dst_addr_len); … … 757 850 * Callback called by ICE session when it receives application data. 758 851 */ 759 static void on_rx_data(pj_ice *ice,760 unsigned comp_id, unsigned cand_id,761 void *pkt, pj_size_t size,762 const pj_sockaddr_t *src_addr,763 unsigned src_addr_len)852 static void ice_rx_data(pj_ice *ice, 853 unsigned comp_id, 854 void *pkt, pj_size_t size, 855 const pj_sockaddr_t *src_addr, 856 unsigned src_addr_len) 764 857 { 765 858 pj_ice_st *ice_st = (pj_ice_st*)ice->user_data; 766 859 767 860 if (ice_st->cb.on_rx_data) { 768 (*ice_st->cb.on_rx_data)(ice_st, comp_id, cand_id,769 pkt, size,src_addr, src_addr_len);861 (*ice_st->cb.on_rx_data)(ice_st, comp_id, pkt, size, 862 src_addr, src_addr_len); 770 863 } 771 864 } … … 780 873 unsigned dst_addr_len) 781 874 { 782 pj_ice_st_ interface *is;875 pj_ice_st_comp *comp; 783 876 pj_ssize_t pkt_size; 784 877 pj_status_t status; 785 878 786 is = (pj_ice_st_interface*) pj_stun_session_get_user_data(sess);879 comp = (pj_ice_st_comp*) pj_stun_session_get_user_data(sess); 787 880 pkt_size = size; 788 status = pj_ioqueue_sendto( is->key, &is->write_op,881 status = pj_ioqueue_sendto(comp->key, &comp->write_op, 789 882 pkt, &pkt_size, 0, 790 883 dst_addr, dst_addr_len); … … 802 895 const pj_stun_msg *response) 803 896 { 804 pj_ice_st_interface *is; 897 pj_ice_st_comp *comp; 898 pj_ice_st_cand *cand = NULL; 805 899 pj_stun_xor_mapped_addr_attr *xa; 806 900 pj_stun_mapped_addr_attr *ma; 807 901 pj_sockaddr *mapped_addr; 808 902 809 PJ_UNUSED_ARG(tdata); 810 811 is = (pj_ice_st_interface*) pj_stun_session_get_user_data(sess); 903 comp = (pj_ice_st_comp*) pj_stun_session_get_user_data(sess); 904 cand = (pj_ice_st_cand*) tdata->user_data; 905 906 /* Decrement pending count for this component */ 907 pj_assert(comp->pending_cnt > 0); 908 comp->pending_cnt--; 909 812 910 if (status != PJ_SUCCESS) { 813 is->status = status; 814 ice_st_perror(is->ice_st, "STUN Binding request failed", is->status); 911 comp->last_status = cand->status = status; 912 ice_st_perror(comp->ice_st, "STUN Binding request failed", 913 cand->status); 815 914 return; 816 915 } … … 826 925 mapped_addr = &ma->sockaddr; 827 926 else { 828 is->status = PJNATH_ESTUNNOMAPPEDADDR; 829 ice_st_perror(is->ice_st, "STUN Binding request failed", is->status); 927 cand->status = PJNATH_ESTUNNOMAPPEDADDR; 928 ice_st_perror(comp->ice_st, "STUN Binding request failed", 929 cand->status); 830 930 return; 831 931 } 832 932 833 PJ_LOG(4,( is->ice_st->obj_name,933 PJ_LOG(4,(comp->ice_st->obj_name, 834 934 "STUN mapped address: %s:%d", 835 935 pj_inet_ntoa(mapped_addr->ipv4.sin_addr), 836 936 (int)pj_ntohs(mapped_addr->ipv4.sin_port))); 837 pj_memcpy(&is->addr, mapped_addr, sizeof(pj_sockaddr_in)); 838 is->status = PJ_SUCCESS; 839 840 } 841 937 pj_memcpy(&cand->addr, mapped_addr, sizeof(pj_sockaddr_in)); 938 cand->status = PJ_SUCCESS; 939 940 /* Set this candidate as the default candidate */ 941 comp->default_cand = (cand - comp->cand_list); 942 comp->last_status = PJ_SUCCESS; 943 } 944 -
pjproject/trunk/pjsip-apps/build/Samples-vc.mak
r1100 r1104 20 20 21 21 LIBS = $(PJSUA_LIB_LIB) $(PJSIP_UA_LIB) $(PJSIP_SIMPLE_LIB) \ 22 $(PJSIP_LIB) $(PJ NATH_LIB) $(PJMEDIA_CODEC_LIB) $(PJMEDIA_LIB) \22 $(PJSIP_LIB) $(PJMEDIA_CODEC_LIB) $(PJMEDIA_LIB) $(PJNATH_LIB) \ 23 23 $(PJLIB_UTIL_LIB) $(PJLIB_LIB) 24 24 … … 30 30 -I..\..\pjnath/include 31 31 LDFLAGS = $(BUILD_FLAGS) $(LIBS) \ 32 ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib \32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib \ 33 33 mswsock.lib ws2_32.lib 34 34 -
pjproject/trunk/pjsip-apps/build/pjsua.dsp
r1098 r1104 52 52 LINK32=link.exe 53 53 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 54 # ADD LINK32 ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map:"..\bin\pjsua_vc6.map" /debug /machine:I386 /out:"../bin/pjsua_vc6.exe" /fixed:no54 # ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map:"..\bin\pjsua_vc6.map" /debug /machine:I386 /out:"../bin/pjsua_vc6.exe" /fixed:no 55 55 # SUBTRACT LINK32 /pdb:none 56 56 … … 78 78 LINK32=link.exe 79 79 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 80 # ADD LINK32 ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjsua_vc6d.exe" /pdbtype:sept80 # ADD LINK32 Iphlpapi.lib ole32.lib user32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../bin/pjsua_vc6d.exe" /pdbtype:sept 81 81 82 82 !ENDIF -
pjproject/trunk/pjsip-apps/build/pjsua.vcproj
r1100 r1104 74 74 Name="VCLinkerTool" 75 75 AdditionalOptions="/FIXED:NO" 76 AdditionalDependencies=" dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"76 AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib" 77 77 OutputFile="../bin/pjsua_vc8.exe" 78 78 LinkIncremental="1" … … 169 169 <Tool 170 170 Name="VCLinkerTool" 171 AdditionalDependencies=" dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib"171 AdditionalDependencies="Iphlpapi.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib odbc32.lib odbccp32.lib ole32.lib user32.lib" 172 172 OutputFile="../bin/pjsua_vc8d.exe" 173 173 LinkIncremental="2" -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r1099 r1104 554 554 { 555 555 unsigned i; 556 pj_sockaddr_in addr; 556 557 pj_status_t status; 558 559 pj_sockaddr_in_init(&addr, 0, (pj_uint16_t)cfg->port); 557 560 558 561 /* Create each media transport */ 559 562 for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) { 560 pj_ice_st *ice_st; 563 pj_ice_st_comp comp; 564 int next_port; 561 565 562 566 status = pjmedia_ice_create(pjsua_var.med_endpt, NULL, 1, … … 569 573 } 570 574 571 ice_st = pjmedia_ice_get_ice_st(pjsua_var.calls[i].med_tp); 572 573 /* Add host candidates for RTP */ 574 status = pj_ice_st_add_all_host_interfaces(ice_st, 1, 0); 575 status = pjmedia_ice_start_init(pjsua_var.calls[i].med_tp, 0, &addr, 576 &pjsua_var.stun_srv.ipv4, NULL); 575 577 if (status != PJ_SUCCESS) { 576 pjsua_perror(THIS_FILE, "Error adding ICE host candidates",578 pjsua_perror(THIS_FILE, "Error starting ICE transport", 577 579 status); 578 580 goto on_error; 579 581 } 580 582 581 /* Configure STUN server */ 582 if (pjsua_var.stun_srv.addr.sa_family != 0) { 583 584 status = pj_ice_st_set_stun_addr(ice_st, 585 pjsua_var.media_cfg.enable_relay, 586 &pjsua_var.stun_srv.ipv4); 587 if (status != PJ_SUCCESS) { 588 pjsua_perror(THIS_FILE, "Error setting ICE's STUN server", 589 status); 590 goto on_error; 591 } 592 593 /* Add STUN server reflexive candidate for RTP */ 594 status = pj_ice_st_add_stun_interface(ice_st, 1, 0, NULL); 595 if (status != PJ_SUCCESS) { 596 pjsua_perror(THIS_FILE, "Error adding ICE address", 597 status); 598 goto on_error; 599 } 600 } 583 pjmedia_ice_get_comp(pjsua_var.calls[i].med_tp, 1, &comp); 584 next_port = pj_ntohs(comp.local_addr.ipv4.sin_port); 585 next_port += 2; 586 addr.sin_port = pj_htons((pj_uint16_t)next_port); 601 587 } 602 588 603 589 /* Wait until all ICE transports are ready */ 604 590 for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) { 605 pj_ice_st *ice_st;606 607 ice_st = pjmedia_ice_get_ice_st(pjsua_var.calls[i].med_tp);608 591 609 592 /* Wait until interface status is PJ_SUCCESS */ 610 593 for (;;) { 611 status = pj _ice_st_get_interfaces_status(ice_st);594 status = pjmedia_ice_get_init_status(pjsua_var.calls[i].med_tp); 612 595 if (status == PJ_EPENDING) 613 596 pjsua_handle_events(100);
Note: See TracChangeset
for help on using the changeset viewer.