test_ice.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* Copyright (C) 2014 Mamadou DIOP.
  2. *
  3. * This file is part of Open Source Doubango Framework.
  4. *
  5. * DOUBANGO is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * DOUBANGO is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with DOUBANGO.
  17. *
  18. */
  19. #ifndef TNET_TEST_ICE_H
  20. #define TNET_TEST_ICE_H
  21. #undef kStunUsrName
  22. #undef kStunPwd
  23. #define kStunUsrName "bossiel@yahoo.fr"
  24. #define kStunPwd "tinynet"
  25. #define kStunServerIP "ns313841.ovh.net" /*"numb.viagenie.ca"*/ /*stun.ekiga.net*/
  26. #define kSkipHosts 1
  27. #define kSkipReflexives 1 // server reflexive: STUN
  28. #define kSkipPeers 1 // peer reflexive
  29. #define kSkipRelays 0 // relays: TURN
  30. #define kTurnTrue 1
  31. #define kStunTrue 1
  32. #define kTurnFalse 0
  33. #define kStunFalse 0
  34. static const tsk_bool_t use_rtcp = tsk_false;
  35. static struct tnet_ice_ctx_s *p_ice_ctx1 = tsk_null;
  36. static struct tnet_ice_ctx_s *p_ice_ctx2 = tsk_null;
  37. static void test_ice_print_local_candidates(const struct tnet_ice_ctx_s *pc_ctx)
  38. {
  39. tsk_size_t index = 0;
  40. const tnet_ice_candidate_t* candidate;
  41. char* p_str = tsk_null;
  42. while ((candidate = tnet_ice_ctx_get_local_candidate_at(pc_ctx, index++))) {
  43. tsk_strcat_2(&p_str, "%s\r\n", tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate));
  44. }
  45. TSK_DEBUG_INFO("ICE LOCAL CANDIDATES:\n%s", p_str);
  46. TSK_FREE(p_str);
  47. }
  48. static char* test_ice_get_local_candidates(const struct tnet_ice_ctx_s *pc_ctx)
  49. {
  50. tsk_size_t index = 0;
  51. const tnet_ice_candidate_t* candidate;
  52. char* p_str = tsk_null;
  53. while ((candidate = tnet_ice_ctx_get_local_candidate_at(pc_ctx, index++))) {
  54. if (kSkipHosts && candidate->type_e == tnet_ice_cand_type_host) {
  55. continue;
  56. }
  57. if (kSkipReflexives && candidate->type_e == tnet_ice_cand_type_srflx) {
  58. continue;
  59. }
  60. if (kSkipRelays && candidate->type_e == tnet_ice_cand_type_relay) {
  61. continue;
  62. }
  63. if (kSkipPeers && candidate->type_e == tnet_ice_cand_type_prflx) {
  64. continue;
  65. }
  66. tsk_strcat_2(&p_str, "%s\r\n", tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate));
  67. }
  68. return p_str;
  69. }
  70. static int test_ice_rtp_callback(const void* callback_data, const uint8_t* data_ptr, tsk_size_t data_size, tnet_fd_t local_fd, const struct sockaddr_storage* remote_addr)
  71. {
  72. struct tnet_ice_ctx_s *p_ice_ctx = (struct tnet_ice_ctx_s *)callback_data;
  73. TSK_DEBUG_INFO("\n\nICE rtp callback (incoming data): %.*s\n\n", data_size, data_ptr);
  74. #if 0
  75. tnet_ice_ctx_send_turn_rtp(p_ice_ctx, data_ptr, data_size);
  76. #endif
  77. return 0;
  78. }
  79. static int test_ice_state_callback(const tnet_ice_event_t *e)
  80. {
  81. struct tnet_ice_ctx_s *p_ice_ctx = (struct tnet_ice_ctx_s *)e->ctx;
  82. int ret = 0;
  83. TSK_DEBUG_INFO("ICE state callback: %s", e->phrase);
  84. switch(e->type) {
  85. case tnet_ice_event_type_gathering_completed: {
  86. test_ice_print_local_candidates(p_ice_ctx);
  87. if (p_ice_ctx == p_ice_ctx1) {
  88. if ((ret = tnet_ice_ctx_start(p_ice_ctx2))) {
  89. goto bail;
  90. }
  91. }
  92. else {
  93. const tnet_ice_candidate_t* candidate;
  94. char* p_cand;
  95. p_cand = test_ice_get_local_candidates(p_ice_ctx2);
  96. candidate = tnet_ice_ctx_get_local_candidate_first(p_ice_ctx2);
  97. ret = tnet_ice_ctx_set_remote_candidates(p_ice_ctx1, p_cand, candidate->ufrag, candidate->pwd, tsk_true, tsk_false);
  98. if (ret == 0) {
  99. TSK_FREE(p_cand);
  100. p_cand = test_ice_get_local_candidates(p_ice_ctx1);
  101. candidate = tnet_ice_ctx_get_local_candidate_first(p_ice_ctx1);
  102. ret = tnet_ice_ctx_set_remote_candidates(p_ice_ctx2, p_cand, candidate->ufrag, candidate->pwd, tsk_false, tsk_false);
  103. TSK_FREE(p_cand);
  104. }
  105. }
  106. break;
  107. }
  108. case tnet_ice_event_type_conncheck_succeed: {
  109. const char kTurnData[] = "TURN data to send for testing";
  110. const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
  111. // === RTP === //
  112. ret = tnet_ice_ctx_get_nominated_symetric_candidates(p_ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
  113. if (ret == 0) {
  114. TSK_DEBUG_INFO("Nominated candidate(RTP): Offer=[[%s]], AnswerSrc=[[%s]], AnswerDest=[[%s]]",
  115. tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_offer),
  116. tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_src),
  117. tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_dest));
  118. if (tnet_ice_ctx_is_turn_rtp_active(p_ice_ctx)) {
  119. tnet_ice_ctx_send_turn_rtp(p_ice_ctx, kTurnData, sizeof(kTurnData));
  120. }
  121. }
  122. // === RTCP === //
  123. if (use_rtcp) {
  124. ret = tnet_ice_ctx_get_nominated_symetric_candidates(p_ice_ctx, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
  125. if (ret == 0) {
  126. TSK_DEBUG_INFO("Nominated candidate(RTCP): Offer=[[%s]], AnswerSrc=[[%s]], AnswerDest=[[%s]]",
  127. tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_offer),
  128. tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_src),
  129. tnet_ice_candidate_tostring((tnet_ice_candidate_t*)candidate_answer_dest));
  130. if (tnet_ice_ctx_is_turn_rtcp_active(p_ice_ctx)) {
  131. tnet_ice_ctx_send_turn_rtcp(p_ice_ctx, kTurnData, sizeof(kTurnData));
  132. }
  133. }
  134. }
  135. break;
  136. }
  137. }
  138. bail:
  139. return ret;
  140. }
  141. void test_ice()
  142. {
  143. int ret;
  144. static const tsk_bool_t use_ipv6 = tsk_false;
  145. static const tsk_bool_t use_ice_jingle = tsk_false;
  146. static const tsk_bool_t use_video = tsk_false;
  147. if (!(p_ice_ctx1 = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, test_ice_state_callback, tsk_null))) {
  148. goto bail;
  149. }
  150. if (!(p_ice_ctx2 = tnet_ice_ctx_create(use_ice_jingle, use_ipv6, use_rtcp, use_video, test_ice_state_callback, tsk_null))) {
  151. goto bail;
  152. }
  153. if ((ret = tnet_ice_ctx_set_turn_enabled(p_ice_ctx1, 1))) {
  154. goto bail;
  155. }
  156. if ((ret = tnet_ice_ctx_set_turn_enabled(p_ice_ctx2, 1))) {
  157. goto bail;
  158. }
  159. if ((ret = tnet_ice_ctx_set_stun_enabled(p_ice_ctx1, 1))) {
  160. goto bail;
  161. }
  162. if ((ret = tnet_ice_ctx_set_stun_enabled(p_ice_ctx2, 1))) {
  163. goto bail;
  164. }
  165. if ((ret = tnet_ice_ctx_set_userdata(p_ice_ctx1, p_ice_ctx1))) {
  166. goto bail;
  167. }
  168. if ((ret = tnet_ice_ctx_set_userdata(p_ice_ctx2, p_ice_ctx2))) {
  169. goto bail;
  170. }
  171. if ((ret = tnet_ice_ctx_rtp_callback(p_ice_ctx1, test_ice_rtp_callback, p_ice_ctx1))) {
  172. goto bail;
  173. }
  174. if ((ret = tnet_ice_ctx_rtp_callback(p_ice_ctx2, test_ice_rtp_callback, p_ice_ctx2))) {
  175. goto bail;
  176. }
  177. #if 0 //@deprecated
  178. if ((ret = tnet_ice_ctx_set_stun(p_ice_ctx1, kStunServerIP, 3478, kStunSoftware, kStunUsrName, kStunPwd))) {
  179. goto bail;
  180. }
  181. if ((ret = tnet_ice_ctx_set_stun(p_ice_ctx2, kStunServerIP, 3478, kStunSoftware, kStunUsrName, kStunPwd))) {
  182. goto bail;
  183. }
  184. #else
  185. tnet_ice_ctx_add_server(p_ice_ctx1, "udp", kStunServerIP, 3478, kTurnFalse, kStunTrue, kStunUsrName, kStunPwd); // STUN-UDP
  186. tnet_ice_ctx_add_server(p_ice_ctx1, "tcp", kStunServerIP, 3478, kTurnTrue, kStunFalse, kStunUsrName, kStunPwd); // TURN-TCP
  187. tnet_ice_ctx_add_server(p_ice_ctx2, "udp", kStunServerIP, 3478, kTurnFalse, kStunTrue, kStunUsrName, kStunPwd); // STUN-UDP
  188. tnet_ice_ctx_add_server(p_ice_ctx2, "tcp", kStunServerIP, 3478, kTurnTrue, kStunFalse, kStunUsrName, kStunPwd); // TURN-TCP
  189. #endif
  190. if ((ret = tnet_ice_ctx_start(p_ice_ctx1))) {
  191. goto bail;
  192. }
  193. // start ctx2 when we finish gathering ctx1's candidates
  194. //if ((ret = tnet_ice_ctx_start(p_ice_ctx2))) {
  195. // goto bail;
  196. //}
  197. getchar();
  198. // ret = tnet_ice_ctx_stop(p_ice_ctx1);
  199. // ret = tnet_ice_ctx_stop(p_ice_ctx2);
  200. bail:
  201. TSK_OBJECT_SAFE_FREE(p_ice_ctx1);
  202. TSK_OBJECT_SAFE_FREE(p_ice_ctx2);
  203. }
  204. #endif /* TNET_TEST_ICE_H */