test_peer_connection.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include "peer.h"
  6. #define MAX_CONNECTION_ATTEMPTS 25
  7. #define OFFER_DATACHANNEL_MESSAGE "Hello World"
  8. #define ANSWER_DATACHANNEL_MESSAGE "Foobar"
  9. #define DATACHANNEL_NAME "libpeer-datachannel"
  10. int test_complete = 0;
  11. typedef struct {
  12. PeerConnection *offer_peer_connection, *answer_peer_connection;
  13. int onmessage_offer_called, onmessage_answer_called, test_complete;
  14. } TestUserData;
  15. static void onconnectionstatechange_offerer_peer_connection(PeerConnectionState state, void* user_data) {
  16. printf("offer state is changed: %s\n", peer_connection_state_to_string(state));
  17. }
  18. static void onconnectionstatechange_answerer_peer_connection(PeerConnectionState state, void* user_data) {
  19. printf("answerer state is changed: %s\n", peer_connection_state_to_string(state));
  20. }
  21. static void onicecandidate_offerer_peer_connection(char* description, void* user_data) {
  22. }
  23. static void onicecandidate_answerer_peer_connection(char* description, void* user_data) {
  24. }
  25. static void ondatachannel_onmessage_offerer_peer_connection(char* msg, size_t len, void* userdata, uint16_t sid) {
  26. TestUserData* test_user_data = (TestUserData*)userdata;
  27. if (strcmp(msg, ANSWER_DATACHANNEL_MESSAGE) == 0) {
  28. test_user_data->onmessage_offer_called = 1;
  29. }
  30. }
  31. static void ondatachannel_onmessage_answerer_peer_connection(char* msg, size_t len, void* userdata, uint16_t sid) {
  32. TestUserData* test_user_data = (TestUserData*)userdata;
  33. if (strcmp(msg, OFFER_DATACHANNEL_MESSAGE) == 0) {
  34. test_user_data->onmessage_answer_called = 1;
  35. }
  36. }
  37. static void* peer_connection_task(void* user_data) {
  38. PeerConnection* peer_connection = (PeerConnection*)user_data;
  39. while (!test_complete) {
  40. peer_connection_loop(peer_connection);
  41. usleep(1000);
  42. }
  43. pthread_exit(NULL);
  44. return NULL;
  45. }
  46. int main(int argc, char* argv[]) {
  47. pthread_t offer_thread, answer_thread;
  48. TestUserData test_user_data = {
  49. .offer_peer_connection = NULL,
  50. .answer_peer_connection = NULL,
  51. };
  52. PeerConfiguration config = {
  53. .ice_servers = {
  54. {.urls = "stun:stun.l.google.com:19302"},
  55. },
  56. .datachannel = DATA_CHANNEL_STRING,
  57. .video_codec = CODEC_H264,
  58. .audio_codec = CODEC_OPUS,
  59. .user_data = &test_user_data,
  60. };
  61. peer_init();
  62. test_user_data.offer_peer_connection = peer_connection_create(&config);
  63. test_user_data.answer_peer_connection = peer_connection_create(&config);
  64. peer_connection_oniceconnectionstatechange(test_user_data.offer_peer_connection, onconnectionstatechange_offerer_peer_connection);
  65. peer_connection_oniceconnectionstatechange(test_user_data.answer_peer_connection, onconnectionstatechange_answerer_peer_connection);
  66. peer_connection_onicecandidate(test_user_data.offer_peer_connection, onicecandidate_offerer_peer_connection);
  67. peer_connection_onicecandidate(test_user_data.answer_peer_connection, onicecandidate_answerer_peer_connection);
  68. peer_connection_ondatachannel(test_user_data.offer_peer_connection, ondatachannel_onmessage_offerer_peer_connection, NULL, NULL);
  69. peer_connection_ondatachannel(test_user_data.answer_peer_connection, ondatachannel_onmessage_answerer_peer_connection, NULL, NULL);
  70. pthread_create(&offer_thread, NULL, peer_connection_task, test_user_data.offer_peer_connection);
  71. pthread_create(&answer_thread, NULL, peer_connection_task, test_user_data.answer_peer_connection);
  72. const char* offer = peer_connection_create_offer(test_user_data.offer_peer_connection);
  73. peer_connection_set_remote_description(test_user_data.answer_peer_connection, offer, SDP_TYPE_OFFER);
  74. const char* answer = peer_connection_create_answer(test_user_data.answer_peer_connection);
  75. peer_connection_set_remote_description(test_user_data.offer_peer_connection, answer, SDP_TYPE_ANSWER);
  76. int attempts = 0, datachannel_created = 0;
  77. while (attempts < MAX_CONNECTION_ATTEMPTS) {
  78. if (!datachannel_created && peer_connection_get_state(test_user_data.offer_peer_connection) == PEER_CONNECTION_COMPLETED) {
  79. if (peer_connection_create_datachannel(test_user_data.offer_peer_connection, DATA_CHANNEL_RELIABLE, 0, 0, DATACHANNEL_NAME, "bar") == 18) {
  80. datachannel_created = 1;
  81. }
  82. }
  83. if (peer_connection_get_state(test_user_data.offer_peer_connection) == PEER_CONNECTION_COMPLETED &&
  84. peer_connection_get_state(test_user_data.answer_peer_connection) == PEER_CONNECTION_COMPLETED &&
  85. test_user_data.onmessage_offer_called == 1 &&
  86. test_user_data.onmessage_answer_called == 1) {
  87. break;
  88. }
  89. peer_connection_datachannel_send(test_user_data.offer_peer_connection, OFFER_DATACHANNEL_MESSAGE, sizeof(OFFER_DATACHANNEL_MESSAGE));
  90. peer_connection_datachannel_send(test_user_data.answer_peer_connection, ANSWER_DATACHANNEL_MESSAGE, sizeof(ANSWER_DATACHANNEL_MESSAGE));
  91. attempts++;
  92. usleep(250000);
  93. }
  94. if (strcmp(DATACHANNEL_NAME, peer_connection_lookup_sid_label(test_user_data.answer_peer_connection, 0)) != 0) {
  95. return 1;
  96. }
  97. test_complete = 1;
  98. pthread_join(offer_thread, NULL);
  99. pthread_join(answer_thread, NULL);
  100. peer_connection_destroy(test_user_data.offer_peer_connection);
  101. peer_connection_destroy(test_user_data.answer_peer_connection);
  102. peer_deinit();
  103. return attempts == MAX_CONNECTION_ATTEMPTS ? 1 : 0;
  104. }