PjsuaCommunicator.hpp 2.6 KB

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