PjsuaCommunicator.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma once
  2. #include "ICommunicator.hpp"
  3. #include <pjmedia.h>
  4. #include <pjsua-lib/pjsua.h>
  5. #undef isblank
  6. #include <log4cpp/Category.hh>
  7. #include <boost/noncopyable.hpp>
  8. #include <string>
  9. #include <stdexcept>
  10. #include <mutex>
  11. namespace sip {
  12. constexpr int DEFAULT_PORT = 5060;
  13. constexpr int SAMPLING_RATE = 48000;
  14. class Exception : public std::runtime_error {
  15. public:
  16. Exception(const char *title) : std::runtime_error(title) {
  17. mesg += title;
  18. }
  19. Exception(const char *title, pj_status_t status) : std::runtime_error(title) {
  20. char errorMsgBuffer[500];
  21. pj_strerror(status, errorMsgBuffer, sizeof(errorMsgBuffer));
  22. mesg += title;
  23. mesg += ": ";
  24. mesg += errorMsgBuffer;
  25. }
  26. virtual const char *what() const throw() {
  27. return mesg.c_str();
  28. }
  29. private:
  30. std::string mesg;
  31. };
  32. inline pj_str_t toPjString(std::string &str) {
  33. return pj_str(const_cast<char *>(str.c_str()));
  34. }
  35. pj_status_t MediaPort_getFrameRawCallback(pjmedia_port *port, pjmedia_frame *frame);
  36. pj_status_t MediaPort_putFrameRawCallback(pjmedia_port *port, pjmedia_frame *frame);
  37. void PjsuaCommunicator_onCallMediaState(pjsua_call_id call_id);
  38. class PjsuaCommunicator : public ICommunicator, boost::noncopyable {
  39. public:
  40. PjsuaCommunicator();
  41. void connect(
  42. std::string host,
  43. std::string user,
  44. std::string password,
  45. unsigned int port = DEFAULT_PORT);
  46. ~PjsuaCommunicator();
  47. virtual void sendPcmSamples(int16_t *samples, unsigned int length);
  48. std::function<void(std::string)> onStateChange;
  49. private:
  50. log4cpp::Category &logger;
  51. log4cpp::Category &callbackLogger;
  52. pjmedia_port *mediaPort = nullptr;
  53. pj_pool_t *pool = nullptr;
  54. pjmedia_circ_buf *inputBuff;
  55. std::mutex inBuffAccessMutex;
  56. // todo make it completely stateless
  57. pjmedia_port *createMediaPort();
  58. void registerAccount(std::string host,
  59. std::string user,
  60. std::string password);
  61. pj_status_t mediaPortGetFrame(pjmedia_frame *frame);
  62. void mediaPortPutFrame(pj_int16_t *samples, pj_size_t count);
  63. /**
  64. * For PJMEDIA implementation reasons, these callbacks have to be functions, not methods.
  65. * That is the reason to use 'friend'.
  66. */
  67. friend pj_status_t MediaPort_getFrameRawCallback(pjmedia_port *port,
  68. pjmedia_frame *frame);
  69. friend pj_status_t MediaPort_putFrameRawCallback(pjmedia_port *port,
  70. pjmedia_frame *frame);
  71. friend void PjsuaCommunicator_onCallMediaState(pjsua_call_id call_id);
  72. };
  73. }