PjsuaCommunicator.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "PjsuaCommunicator.hpp"
  2. #include <pjlib.h>
  3. #include <pjsua-lib/pjsua.h>
  4. #include <functional>
  5. //todo wywalić
  6. #define THIS_FILE "mumsi"
  7. using namespace std;
  8. /**
  9. * This is global, because there's no way to pass it's value to onCallMediaState callback.
  10. */
  11. static int mediaPortSlot;
  12. static void onCallMediaState(pjsua_call_id call_id) {
  13. pjsua_call_info ci;
  14. pjsua_call_get_info(call_id, &ci);
  15. if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
  16. pjsua_conf_connect(ci.conf_slot, mediaPortSlot);
  17. pjsua_conf_connect(mediaPortSlot, ci.conf_slot);
  18. }
  19. }
  20. static void onIncomingCall(pjsua_acc_id acc_id,
  21. pjsua_call_id call_id,
  22. pjsip_rx_data *rdata) {
  23. pjsua_call_info ci;
  24. PJ_UNUSED_ARG(acc_id);
  25. PJ_UNUSED_ARG(rdata);
  26. pjsua_call_get_info(call_id, &ci);
  27. PJ_LOG(3, (THIS_FILE, "Incoming call from %.*s!!",
  28. (int) ci.remote_info.slen,
  29. ci.remote_info.ptr));
  30. /* Automatically answer incoming calls with 200/OK */
  31. pjsua_call_answer(call_id, 200, NULL, NULL);
  32. }
  33. static void onCallState(pjsua_call_id call_id,
  34. pjsip_event *e) {
  35. pjsua_call_info ci;
  36. PJ_UNUSED_ARG(e);
  37. pjsua_call_get_info(call_id, &ci);
  38. PJ_LOG(3, (THIS_FILE, "Call %d state=%.*s", call_id,
  39. (int) ci.state_text.slen,
  40. ci.state_text.ptr));
  41. }
  42. pjsua::PjsuaCommunicator::PjsuaCommunicator(
  43. SoundSampleQueue<SOUND_SAMPLE_TYPE> &inputQueue,
  44. SoundSampleQueue<SOUND_SAMPLE_TYPE> &outputQueue,
  45. std::string host,
  46. std::string user,
  47. std::string password)
  48. : AbstractCommunicator(inputQueue, outputQueue),
  49. mediaPort(inputQueue, outputQueue) {
  50. pj_status_t status;
  51. status = pjsua_create();
  52. if (status != PJ_SUCCESS) {
  53. throw pjsua::Exception("Error in pjsua_create()", status);
  54. }
  55. /* Init pjsua */
  56. pjsua_config generalConfig;
  57. pjsua_config_default(&generalConfig);
  58. using namespace std::placeholders;
  59. generalConfig.cb.on_incoming_call = &onIncomingCall;
  60. generalConfig.cb.on_call_media_state = &onCallMediaState;
  61. generalConfig.cb.on_call_state = &onCallState;
  62. //todo zrobić coś z logami
  63. pjsua_logging_config logConfig;
  64. pjsua_logging_config_default(&logConfig);
  65. logConfig.console_level = 4;
  66. status = pjsua_init(&generalConfig, &logConfig, NULL);
  67. if (status != PJ_SUCCESS) {
  68. throw pjsua::Exception("Error in pjsua_init()", status);
  69. }
  70. /* Add UDP transport. */
  71. pjsua_transport_config transportConfig;
  72. pjsua_transport_config_default(&transportConfig);
  73. transportConfig.port = pjsua::SIP_PORT;
  74. status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &transportConfig, NULL);
  75. if (status != PJ_SUCCESS) {
  76. throw pjsua::Exception("Error creating transport", status);
  77. }
  78. pjsua_set_null_snd_dev();
  79. pj_caching_pool cachingPool;
  80. pj_caching_pool_init(&cachingPool, &pj_pool_factory_default_policy, 0);
  81. pj_pool_t *pool = pj_pool_create(&cachingPool.factory, "wav", 4096, 4096, nullptr);
  82. pjsua_conf_add_port(pool, mediaPort.create_pjmedia_port(), &mediaPortSlot);
  83. /* Initialization is done, now start pjsua */
  84. status = pjsua_start();
  85. if (status != PJ_SUCCESS) {
  86. throw pjsua::Exception("Error starting pjsua", status);
  87. }
  88. /* Register to SIP server by creating SIP account. */
  89. pjsua_acc_config accConfig;
  90. pjsua_acc_config_default(&accConfig);
  91. accConfig.id = toPjString(string("sip:") + user + "@" + host);
  92. accConfig.reg_uri = toPjString(string("sip:") + host);
  93. accConfig.cred_count = 1;
  94. accConfig.cred_info[0].realm = toPjString(host);
  95. accConfig.cred_info[0].scheme = toPjString("digest");
  96. accConfig.cred_info[0].username = toPjString(user);
  97. accConfig.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
  98. accConfig.cred_info[0].data = toPjString(password);
  99. pjsua_acc_id acc_id;
  100. status = pjsua_acc_add(&accConfig, PJ_TRUE, &acc_id);
  101. if (status != PJ_SUCCESS) {
  102. throw pjsua::Exception("Error adding account", status);
  103. }
  104. }
  105. pjsua::PjsuaCommunicator::~PjsuaCommunicator() {
  106. pjsua_destroy();
  107. }
  108. void pjsua::PjsuaCommunicator::loop() {
  109. }