1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-30 04:39:03 +01:00
libtgvoip/VoIPController.h

693 lines
19 KiB
C
Raw Normal View History

//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
2017-02-02 17:24:40 +01:00
#ifndef __VOIPCONTROLLER_H
#define __VOIPCONTROLLER_H
#ifndef _WIN32
2017-02-02 17:24:40 +01:00
#include <arpa/inet.h>
#include <netinet/in.h>
#endif
#ifdef __APPLE__
#include <TargetConditionals.h>
2018-05-15 20:23:46 +02:00
#include "os/darwin/AudioUnitIO.h"
#endif
2017-02-02 17:24:40 +01:00
#include <stdint.h>
#include <vector>
2017-03-30 16:06:59 +02:00
#include <string>
2018-06-04 21:37:43 +02:00
#include <unordered_map>
#include <memory>
2017-02-02 17:24:40 +01:00
#include "audio/AudioInput.h"
#include "BlockingQueue.h"
#include "audio/AudioOutput.h"
#include "audio/AudioIO.h"
2017-02-02 17:24:40 +01:00
#include "JitterBuffer.h"
#include "OpusDecoder.h"
#include "OpusEncoder.h"
#include "EchoCanceller.h"
#include "CongestionControl.h"
#include "NetworkSocket.h"
2018-06-04 21:37:43 +02:00
#include "Buffers.h"
#include "PacketReassembler.h"
#include "MessageThread.h"
2017-02-02 17:24:40 +01:00
#define LIBTGVOIP_VERSION "2.2"
2017-02-02 17:24:40 +01:00
#ifdef _WIN32
#undef GetCurrentTime
2018-05-24 18:42:28 +02:00
#undef ERROR_TIMEOUT
#endif
2018-05-15 20:23:46 +02:00
#define TGVOIP_PEER_CAP_GROUP_CALLS 1
2017-02-02 17:24:40 +01:00
namespace tgvoip{
enum{
PROXY_NONE=0,
PROXY_SOCKS5,
//PROXY_HTTP
};
2018-05-15 20:23:46 +02:00
enum{
STATE_WAIT_INIT=1,
STATE_WAIT_INIT_ACK,
STATE_ESTABLISHED,
STATE_FAILED,
STATE_RECONNECTING
};
2018-05-15 20:23:46 +02:00
enum{
ERROR_UNKNOWN=0,
ERROR_INCOMPATIBLE,
ERROR_TIMEOUT,
2018-06-04 21:37:43 +02:00
ERROR_AUDIO_IO,
ERROR_PROXY
2018-05-15 20:23:46 +02:00
};
2018-05-15 20:23:46 +02:00
enum{
NET_TYPE_UNKNOWN=0,
NET_TYPE_GPRS,
NET_TYPE_EDGE,
NET_TYPE_3G,
NET_TYPE_HSPA,
NET_TYPE_LTE,
NET_TYPE_WIFI,
NET_TYPE_ETHERNET,
NET_TYPE_OTHER_HIGH_SPEED,
NET_TYPE_OTHER_LOW_SPEED,
NET_TYPE_DIALUP,
NET_TYPE_OTHER_MOBILE
};
2018-05-15 20:23:46 +02:00
enum{
DATA_SAVING_NEVER=0,
DATA_SAVING_MOBILE,
DATA_SAVING_ALWAYS
};
2018-06-04 21:37:43 +02:00
struct CryptoFunctions{
void (*rand_bytes)(uint8_t* buffer, size_t length);
void (*sha1)(uint8_t* msg, size_t length, uint8_t* output);
void (*sha256)(uint8_t* msg, size_t length, uint8_t* output);
void (*aes_ige_encrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
void (*aes_ige_decrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
void (*aes_ctr_encrypt)(uint8_t* inout, size_t length, uint8_t* key, uint8_t* iv, uint8_t* ecount, uint32_t* num);
void (*aes_cbc_encrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
void (*aes_cbc_decrypt)(uint8_t* in, uint8_t* out, size_t length, uint8_t* key, uint8_t* iv);
};
2018-05-15 20:23:46 +02:00
class Endpoint{
friend class VoIPController;
friend class VoIPGroupController;
public:
enum{
TYPE_UDP_P2P_INET=1,
TYPE_UDP_P2P_LAN,
TYPE_UDP_RELAY,
TYPE_TCP_RELAY
};
Endpoint(int64_t id, uint16_t port, IPv4Address& address, IPv6Address& v6address, char type, unsigned char* peerTag);
Endpoint();
2018-06-04 21:37:43 +02:00
~Endpoint();
NetworkAddress& GetAddress();
bool IsIPv6Only();
2018-05-15 20:23:46 +02:00
int64_t id;
uint16_t port;
IPv4Address address;
IPv6Address v6address;
char type;
unsigned char peerTag[16];
private:
double lastPingTime;
uint32_t lastPingSeq;
HistoricBuffer<double, 6> rtts;
2018-05-15 20:23:46 +02:00
double averageRTT;
NetworkSocket* socket;
int udpPongCount;
};
2018-05-15 20:23:46 +02:00
class AudioDevice{
public:
std::string id;
std::string displayName;
};
2018-05-15 20:23:46 +02:00
class AudioOutputDevice : public AudioDevice{
2018-05-15 20:23:46 +02:00
};
class AudioInputDevice : public AudioDevice{
};
2018-06-04 21:37:43 +02:00
struct EncodedVideoFrame{
unsigned char* data;
size_t size;
uint32_t flags;
EncodedVideoFrame(size_t size){
this->size=size;
data=(unsigned char*)malloc(size);
}
~EncodedVideoFrame(){
free(data);
}
};
2018-05-15 20:23:46 +02:00
class VoIPController{
friend class VoIPGroupController;
public:
2018-06-04 21:37:43 +02:00
struct Config{
2018-06-04 22:02:49 +02:00
Config(double initTimeout=30.0, double recvTimeout=20.0, int dataSaving=DATA_SAVING_NEVER, bool enableAEC=false, bool enableNS=false, bool enableAGC=false, bool enableCallUpgrade=false){
2018-06-04 21:37:43 +02:00
this->initTimeout=initTimeout;
this->recvTimeout=recvTimeout;
this->dataSaving=dataSaving;
this->enableAEC=enableAEC;
this->enableNS=enableNS;
this->enableAGC=enableAGC;
2018-06-04 21:59:58 +02:00
this->enableCallUpgrade=enableCallUpgrade;
2018-06-04 21:37:43 +02:00
}
double initTimeout;
double recvTimeout;
int dataSaving;
std::string logFilePath="";
std::string statsDumpFilePath="";
2018-06-04 21:59:58 +02:00
bool enableAEC;
bool enableNS;
bool enableAGC;
2018-06-04 21:37:43 +02:00
2018-06-04 21:59:58 +02:00
bool enableCallUpgrade;
2018-06-04 21:37:43 +02:00
};
struct TrafficStats{
uint64_t bytesSentWifi;
uint64_t bytesRecvdWifi;
uint64_t bytesSentMobile;
uint64_t bytesRecvdMobile;
};
2018-05-15 20:23:46 +02:00
VoIPController();
virtual ~VoIPController();
/**
* Set the initial endpoints (relays)
* @param endpoints Endpoints converted from phone.PhoneConnection TL objects
* @param allowP2p Whether p2p connectivity is allowed
*/
void SetRemoteEndpoints(std::vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer);
/**
* Initialize and start all the internal threads
*/
void Start();
/**
* Stop any internal threads. Don't call any other methods after this.
*/
void Stop();
/**
* Initiate connection
*/
void Connect();
Endpoint& GetRemoteEndpoint();
/**
* Get the debug info string to be displayed in client UI
*/
2018-06-04 21:37:43 +02:00
virtual std::string GetDebugString();
2018-05-15 20:23:46 +02:00
/**
* Notify the library of network type change
* @param type The new network type
*/
virtual void SetNetworkType(int type);
/**
* Get the average round-trip time for network packets
* @return
*/
double GetAverageRTT();
static double GetCurrentTime();
/**
* Use this field to store any of your context data associated with this call
*/
void* implData;
/**
*
* @param mute
*/
virtual void SetMicMute(bool mute);
/**
*
* @param key
* @param isOutgoing
*/
void SetEncryptionKey(char* key, bool isOutgoing);
/**
*
* @param cfg
*/
2018-06-04 21:59:58 +02:00
void SetConfig(const Config& cfg);
2018-05-15 20:23:46 +02:00
void DebugCtl(int request, int param);
/**
*
* @param stats
*/
2018-06-04 21:37:43 +02:00
void GetStats(TrafficStats* stats);
2018-05-15 20:23:46 +02:00
/**
*
* @return
*/
int64_t GetPreferredRelayID();
/**
*
* @return
*/
int GetLastError();
/**
*
*/
2018-06-04 21:37:43 +02:00
static CryptoFunctions crypto;
/**
*
* @return
*/
2018-05-15 20:23:46 +02:00
static const char* GetVersion();
/**
*
* @return
*/
std::string GetDebugLog();
/**
*
* @param buffer
*/
2018-05-15 20:23:46 +02:00
void GetDebugLog(char* buffer);
size_t GetDebugLogLength();
/**
*
* @return
*/
2018-05-15 20:23:46 +02:00
static std::vector<AudioInputDevice> EnumerateAudioInputs();
/**
*
* @return
*/
2018-05-15 20:23:46 +02:00
static std::vector<AudioOutputDevice> EnumerateAudioOutputs();
/**
*
* @param id
*/
2018-05-15 20:23:46 +02:00
void SetCurrentAudioInput(std::string id);
/**
*
* @param id
*/
2018-05-15 20:23:46 +02:00
void SetCurrentAudioOutput(std::string id);
/**
*
* @return
*/
2018-05-15 20:23:46 +02:00
std::string GetCurrentAudioInputID();
/**
*
* @return
*/
2018-05-15 20:23:46 +02:00
std::string GetCurrentAudioOutputID();
/**
* Set the proxy server to route the data through. Call this before connecting.
* @param protocol PROXY_NONE or PROXY_SOCKS5
* @param address IP address or domain name of the server
* @param port Port of the server
* @param username Username; empty string for anonymous
* @param password Password; empty string if none
*/
void SetProxy(int protocol, std::string address, uint16_t port, std::string username, std::string password);
2017-08-21 18:02:37 +02:00
/**
* Get the number of signal bars to display in the client UI.
* @return the number of signal bars, from 1 to 4
*/
int GetSignalBarsCount();
/**
* Enable or disable AGC (automatic gain control) on audio output. Should only be enabled on phones when the earpiece speaker is being used.
* The audio output will be louder with this on.
* AGC with speakerphone or other kinds of loud speakers has detrimental effects on some echo cancellation implementations.
* @param enabled I usually pick argument names to be self-explanatory
*/
void SetAudioOutputGainControlEnabled(bool enabled);
2018-05-15 20:23:46 +02:00
/**
* Get the additional capabilities of the peer client app
* @return corresponding TGVOIP_PEER_CAP_* flags OR'ed together
*/
uint32_t GetPeerCapabilities();
/**
* Send the peer the key for the group call to prepare this private call to an upgrade to a E2E group call.
* The peer must have the TGVOIP_PEER_CAP_GROUP_CALLS capability. After the peer acknowledges the key, Callbacks::groupCallKeySent will be called.
* @param key newly-generated group call key, must be exactly 265 bytes long
*/
void SendGroupCallKey(unsigned char* key);
/**
* In an incoming call, request the peer to generate a new encryption key, send it to you and upgrade this call to a E2E group call.
*/
void RequestCallUpgrade();
2017-12-27 18:25:47 +01:00
void SetEchoCancellationStrength(int strength);
2017-02-02 17:24:40 +01:00
2018-05-15 20:23:46 +02:00
struct Callbacks{
void (*connectionStateChanged)(VoIPController*, int);
void (*signalBarCountChanged)(VoIPController*, int);
void (*groupCallKeySent)(VoIPController*);
void (*groupCallKeyReceived)(VoIPController*, const unsigned char*);
2018-05-15 20:23:46 +02:00
void (*upgradeToGroupCallRequested)(VoIPController*);
};
void SetCallbacks(Callbacks callbacks);
float GetOutputLevel(){
return 0.0f;
};
2018-05-15 20:23:46 +02:00
2018-06-04 21:37:43 +02:00
private:
struct Stream;
struct UnacknowledgedExtraData;
2018-05-15 20:23:46 +02:00
protected:
struct RecentOutgoingPacket{
uint32_t seq;
uint16_t id; // for group calls only
double sendTime;
double ackTime;
};
struct PendingOutgoingPacket{
uint32_t seq;
unsigned char type;
2018-06-04 21:37:43 +02:00
//Buffer data;
2018-05-15 20:23:46 +02:00
size_t len;
unsigned char* data;
2018-06-04 21:37:43 +02:00
int64_t endpoint;
2018-05-15 20:23:46 +02:00
};
2018-06-04 21:37:43 +02:00
struct SegmentedPacket{
unsigned char type;
};
struct QueuedPacket{
Buffer data;
unsigned char type;
HistoricBuffer<uint32_t, 16> seqs;
2018-06-04 21:37:43 +02:00
double firstSentTime;
double lastSentTime;
double retryInterval;
double timeout;
};
virtual void ProcessIncomingPacket(NetworkPacket& packet, std::shared_ptr<Endpoint> srcEndpoint);
virtual void ProcessExtraData(Buffer& data);
2018-05-15 20:23:46 +02:00
virtual void WritePacketHeader(uint32_t seq, BufferOutputStream* s, unsigned char type, uint32_t length);
2018-06-04 21:37:43 +02:00
virtual void SendPacket(unsigned char* data, size_t len, std::shared_ptr<Endpoint> ep, PendingOutgoingPacket& srcPacket);
2018-05-15 20:23:46 +02:00
virtual void SendInit();
2018-06-04 21:37:43 +02:00
virtual void SendUdpPing(std::shared_ptr<Endpoint> endpoint);
2018-05-15 20:23:46 +02:00
virtual void SendRelayPings();
virtual void OnAudioOutputReady();
2018-06-04 21:37:43 +02:00
virtual void SendExtra(Buffer& data, unsigned char type);
void SendStreamFlags(Stream& stream);
void InitializeTimers();
2018-05-15 20:23:46 +02:00
private:
struct Stream{
int32_t userID;
unsigned char id;
unsigned char type;
uint32_t codec;
bool enabled;
2018-06-04 21:37:43 +02:00
bool extraECEnabled;
2018-05-15 20:23:46 +02:00
uint16_t frameDuration;
2018-06-04 21:37:43 +02:00
std::shared_ptr<JitterBuffer> jitterBuffer;
std::shared_ptr<OpusDecoder> decoder;
std::shared_ptr<PacketReassembler> packetReassembler;
std::shared_ptr<CallbackWrapper> callbackWrapper;
std::vector<Buffer> codecSpecificData;
};
struct UnacknowledgedExtraData{
unsigned char type;
Buffer data;
uint32_t firstContainingSeq;
2018-05-15 20:23:46 +02:00
};
enum{
UDP_UNKNOWN=0,
2018-07-29 20:21:34 +02:00
UDP_PING_PENDING,
2018-05-15 20:23:46 +02:00
UDP_PING_SENT,
UDP_AVAILABLE,
UDP_NOT_AVAILABLE,
UDP_BAD
};
void RunRecvThread(void* arg);
void RunSendThread(void* arg);
2018-06-04 21:37:43 +02:00
void HandleAudioInput(unsigned char* data, size_t len, unsigned char* secondaryData, size_t secondaryLen);
void HandleVideoInput(EncodedVideoFrame& frame);
void UpdateAudioBitrateLimit();
2018-05-15 20:23:46 +02:00
void SetState(int state);
void UpdateAudioOutputState();
void InitUDPProxy();
void UpdateDataSavingState();
void KDF(unsigned char* msgKey, size_t x, unsigned char* aesKey, unsigned char* aesIv);
void KDF2(unsigned char* msgKey, size_t x, unsigned char* aesKey, unsigned char* aesIv);
2018-06-04 21:37:43 +02:00
static void AudioInputCallback(unsigned char* data, size_t length, unsigned char* secondaryData, size_t secondaryLength, void* param);
2018-05-15 20:23:46 +02:00
void SendPublicEndpointsRequest();
void SendPublicEndpointsRequest(Endpoint& relay);
2018-06-04 21:37:43 +02:00
std::shared_ptr<Endpoint> GetEndpointByType(int type);
std::shared_ptr<Endpoint> GetEndpointByID(int64_t id);
2018-05-15 20:23:46 +02:00
void SendPacketReliably(unsigned char type, unsigned char* data, size_t len, double retryInterval, double timeout);
uint32_t GenerateOutSeq();
void LogDebugInfo();
2018-06-04 21:37:43 +02:00
void ActuallySendPacket(NetworkPacket& pkt, std::shared_ptr<Endpoint> ep);
2018-05-15 20:23:46 +02:00
void StartAudio();
2018-06-04 21:37:43 +02:00
void ProcessAcknowledgedOutgoingExtra(UnacknowledgedExtraData& extra);
void AddIPv6Relays();
void AddTCPRelays();
void SendUdpPings();
void EvaluateUdpPingResults();
void UpdateRTT();
void UpdateCongestion();
void UpdateAudioBitrate();
void UpdateSignalBars();
void UpdateQueuedPackets();
void SendNopPacket();
void TickJitterBufferAngCongestionControl();
2018-07-29 20:21:34 +02:00
void ResetUdpAvailability();
2018-05-15 20:23:46 +02:00
int state;
2018-06-04 21:37:43 +02:00
std::vector<std::shared_ptr<Endpoint>> endpoints;
std::shared_ptr<Endpoint> currentEndpoint;
std::shared_ptr<Endpoint> preferredRelay;
std::shared_ptr<Endpoint> peerPreferredRelay;
2018-05-15 20:23:46 +02:00
bool runReceiver;
uint32_t seq;
2018-05-15 20:23:46 +02:00
uint32_t lastRemoteSeq;
uint32_t lastRemoteAckSeq;
uint32_t lastSentSeq;
std::vector<RecentOutgoingPacket> recentOutgoingPackets;
double recvPacketTimes[32];
HistoricBuffer<uint32_t, 10, double> sendLossCountHistory;
2018-05-15 20:23:46 +02:00
uint32_t audioTimestampIn;
uint32_t audioTimestampOut;
std::shared_ptr<tgvoip::audio::AudioIO> audioIO;
2018-05-15 20:23:46 +02:00
tgvoip::audio::AudioInput* audioInput;
tgvoip::audio::AudioOutput* audioOutput;
2018-05-15 20:23:46 +02:00
OpusEncoder* encoder;
BlockingQueue<PendingOutgoingPacket>* sendQueue;
EchoCanceller* echoCanceller;
Mutex sendBufferMutex;
Mutex endpointsMutex;
2018-06-04 21:37:43 +02:00
Mutex socketSelectMutex;
2018-05-15 20:23:46 +02:00
bool stopping;
bool audioOutStarted;
Thread* recvThread;
Thread* sendThread;
2018-06-04 21:37:43 +02:00
uint32_t packetsReceived;
2018-05-15 20:23:46 +02:00
uint32_t recvLossCount;
uint32_t prevSendLossCount;
uint32_t firstSentPing;
HistoricBuffer<double, 32> rttHistory;
2018-05-15 20:23:46 +02:00
bool waitingForAcks;
int networkType;
int dontSendPackets;
int lastError;
bool micMuted;
uint32_t maxBitrate;
2018-06-04 21:37:43 +02:00
std::vector<std::shared_ptr<Stream>> outgoingStreams;
std::vector<std::shared_ptr<Stream>> incomingStreams;
2018-05-15 20:23:46 +02:00
unsigned char encryptionKey[256];
unsigned char keyFingerprint[8];
unsigned char callID[16];
double stateChangeTime;
bool waitingForRelayPeerInfo;
bool allowP2p;
bool dataSavingMode;
bool dataSavingRequestedByPeer;
std::string activeNetItfName;
double publicEndpointsReqTime;
2018-06-04 21:37:43 +02:00
std::vector<QueuedPacket> queuedPackets;
Mutex audioIOMutex;
2018-05-15 20:23:46 +02:00
Mutex queuedPacketsMutex;
double connectionInitTime;
double lastRecvPacketTime;
2018-06-04 21:37:43 +02:00
Config config;
2018-05-15 20:23:46 +02:00
int32_t peerVersion;
CongestionControl* conctl;
2018-06-04 21:37:43 +02:00
TrafficStats stats;
2018-05-15 20:23:46 +02:00
bool receivedInit;
bool receivedInitAck;
std::vector<std::string> debugLogs;
bool isOutgoing;
NetworkSocket* udpSocket;
NetworkSocket* realUdpSocket;
FILE* statsDump;
std::string currentAudioInput;
std::string currentAudioOutput;
bool useTCP;
bool useUDP;
bool didAddTcpRelays;
SocketSelectCanceller* selectCanceller;
NetworkSocket* openingTcpSocket;
HistoricBuffer<unsigned char, 4, int> signalBarsHistory;
2018-05-15 20:23:46 +02:00
BufferPool outgoingPacketsBufferPool;
int udpConnectivityState;
double lastUdpPingTime;
int udpPingCount;
int echoCancellationStrength;
int proxyProtocol;
std::string proxyAddress;
uint16_t proxyPort;
std::string proxyUsername;
std::string proxyPassword;
IPv4Address* resolvedProxyAddress;
2017-08-21 18:02:37 +02:00
AutomaticGainControl* outputAGC;
bool outputAGCEnabled;
2018-05-15 20:23:46 +02:00
uint32_t peerCapabilities;
Callbacks callbacks;
bool didReceiveGroupCallKey;
bool didReceiveGroupCallKeyAck;
bool didSendGroupCallKey;
bool didSendUpgradeRequest;
2018-06-04 21:37:43 +02:00
bool didInvokeUpgradeCallback;
2018-05-15 20:23:46 +02:00
int32_t connectionMaxLayer;
bool useMTProto2;
bool setCurrentEndpointToTCP;
2018-06-04 21:37:43 +02:00
std::vector<UnacknowledgedExtraData> currentExtras;
std::unordered_map<uint8_t, uint64_t> lastReceivedExtrasByType;
bool useIPv6;
bool peerIPv6Available;
IPv6Address myIPv6;
bool shittyInternetMode;
std::vector<Buffer> ecAudioPackets;
bool didAddIPv6Relays;
bool didSendIPv6Endpoint;
int publicEndpointsReqCount=0;
MessageThread messageThread;
bool wasEstablished=false;
uint32_t initTimeoutID=MessageThread::INVALID_ID;
uint32_t noStreamsNopID=MessageThread::INVALID_ID;
2018-07-29 20:21:34 +02:00
uint32_t udpPingTimeoutID=MessageThread::INVALID_ID;
2018-06-04 21:37:43 +02:00
2018-05-15 20:23:46 +02:00
/*** server config values ***/
uint32_t maxAudioBitrate;
uint32_t maxAudioBitrateEDGE;
uint32_t maxAudioBitrateGPRS;
uint32_t maxAudioBitrateSaving;
uint32_t initAudioBitrate;
uint32_t initAudioBitrateEDGE;
uint32_t initAudioBitrateGPRS;
uint32_t initAudioBitrateSaving;
uint32_t minAudioBitrate;
uint32_t audioBitrateStepIncr;
uint32_t audioBitrateStepDecr;
double relaySwitchThreshold;
double p2pToRelaySwitchThreshold;
double relayToP2pSwitchThreshold;
double reconnectingTimeout;
public:
#ifdef __APPLE__
2018-05-15 20:23:46 +02:00
static double machTimebase;
static uint64_t machTimestart;
#endif
#ifdef _WIN32
2018-05-15 20:23:46 +02:00
static int64_t win32TimeScale;
static bool didInitWin32TimeScale;
2017-02-02 17:24:40 +01:00
#endif
2018-05-15 20:23:46 +02:00
};
2017-02-02 17:24:40 +01:00
2018-05-15 20:23:46 +02:00
class VoIPGroupController : public VoIPController{
public:
VoIPGroupController(int32_t timeDifference);
virtual ~VoIPGroupController();
void SetGroupCallInfo(unsigned char* encryptionKey, unsigned char* reflectorGroupTag, unsigned char* reflectorSelfTag, unsigned char* reflectorSelfSecret, unsigned char* reflectorSelfTagHash, int32_t selfUserID, IPv4Address reflectorAddress, IPv6Address reflectorAddressV6, uint16_t reflectorPort);
void AddGroupCallParticipant(int32_t userID, unsigned char* memberTagHash, unsigned char* serializedStreams, size_t streamsLength);
void RemoveGroupCallParticipant(int32_t userID);
float GetParticipantAudioLevel(int32_t userID);
virtual void SetMicMute(bool mute);
void SetParticipantVolume(int32_t userID, float volume);
void SetParticipantStreams(int32_t userID, unsigned char* serializedStreams, size_t length);
static size_t GetInitialStreams(unsigned char* buf, size_t size);
struct Callbacks : public VoIPController::Callbacks{
void (*updateStreams)(VoIPGroupController*, unsigned char*, size_t);
void (*participantAudioStateChanged)(VoIPGroupController*, int32_t, bool);
};
void SetCallbacks(Callbacks callbacks);
2018-06-04 21:37:43 +02:00
virtual std::string GetDebugString();
2018-05-15 20:23:46 +02:00
virtual void SetNetworkType(int type);
protected:
2018-06-04 21:37:43 +02:00
virtual void ProcessIncomingPacket(NetworkPacket& packet, std::shared_ptr<Endpoint> srcEndpoint);
2018-05-15 20:23:46 +02:00
virtual void SendInit();
2018-06-04 21:37:43 +02:00
virtual void SendUdpPing(std::shared_ptr<Endpoint> endpoint);
2018-05-15 20:23:46 +02:00
virtual void SendRelayPings();
2018-06-04 21:37:43 +02:00
virtual void SendPacket(unsigned char* data, size_t len, std::shared_ptr<Endpoint> ep, PendingOutgoingPacket& srcPacket);
2018-05-15 20:23:46 +02:00
virtual void WritePacketHeader(uint32_t seq, BufferOutputStream* s, unsigned char type, uint32_t length);
virtual void OnAudioOutputReady();
private:
int32_t GetCurrentUnixtime();
2018-06-04 21:37:43 +02:00
std::vector<std::shared_ptr<Stream>> DeserializeStreams(BufferInputStream& in);
2018-05-15 20:23:46 +02:00
void SendRecentPacketsRequest();
void SendSpecialReflectorRequest(unsigned char* data, size_t len);
void SerializeAndUpdateOutgoingStreams();
struct GroupCallParticipant{
int32_t userID;
unsigned char memberTagHash[32];
2018-06-04 21:37:43 +02:00
std::vector<std::shared_ptr<Stream>> streams;
2018-05-15 20:23:46 +02:00
AudioLevelMeter* levelMeter;
};
std::vector<GroupCallParticipant> participants;
unsigned char reflectorSelfTag[16];
unsigned char reflectorSelfSecret[16];
unsigned char reflectorSelfTagHash[32];
int32_t userSelfID;
2018-06-04 21:37:43 +02:00
std::shared_ptr<Endpoint> groupReflector;
2018-05-15 20:23:46 +02:00
AudioMixer* audioMixer;
AudioLevelMeter selfLevelMeter;
Callbacks groupCallbacks;
struct PacketIdMapping{
uint32_t seq;
uint16_t id;
double ackTime;
};
std::vector<PacketIdMapping> recentSentPackets;
Mutex sentPacketsMutex;
Mutex participantsMutex;
int32_t timeDifference;
};
};
2017-02-02 17:24:40 +01:00
#endif