summaryrefslogtreecommitdiff
path: root/indra/llwebrtc/llwebrtc.h
blob: 54eefc85545c44b849debeebfc62233c6b4aeeff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/**
 * @file llwebrtc.h
 * @brief WebRTC interface
 *
 * $LicenseInfo:firstyear=2023&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2023, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free tSoftware
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

/*
 * llwebrtc wraps the native webrtc c++ library in a dynamic library with a simlified interface
 * so that the viewer can use it.  This is done because native webrtc has a different
 * overall threading model than the viewer.
 * The native webrtc library is also compiled with clang, and has memory management
 * functions that conflict namespace-wise with those in the viewer.
 *
 * Due to these differences, code from the viewer cannot be pulled in to this
 * dynamic library, so it remains very simple.
 */

#ifndef LLWEBRTC_H
#define LLWEBRTC_H

#include <string>
#include <vector>

#ifdef LL_MAKEDLL
#ifdef WEBRTC_WIN
#define LLSYMEXPORT __declspec(dllexport)
#elif WEBRTC_LINUX
#define LLSYMEXPORT __attribute__((visibility("default")))
#else
#define LLSYMEXPORT /**/
#endif
#else
#define LLSYMEXPORT /**/
#endif // LL_MAKEDLL

namespace llwebrtc
{

// LLWebRTCVoiceDevice is a simple representation of the
// components of a device, used to communicate this
// information to the viewer.


// A note on threading.
// Native WebRTC has it's own threading model.  Some discussion
// can be found here (https://webrtc.github.io/webrtc-org/native-code/native-apis/)
//
// Note that all callbacks to observers will occurr on one of the WebRTC native threads
// (signaling, worker, etc.)  Care should be taken to assure there are not
// bad interactions with the viewer threads.

class LLWebRTCVoiceDevice
{
  public:
    std::string mDisplayName;  // friendly name for user interface purposes
    std::string mID;           // internal value for selection

    LLWebRTCVoiceDevice(const std::string &display_name, const std::string &id) :
        mDisplayName(display_name),
        mID(id)
    {
        if (mID.empty())
        {
            mID = display_name;
        }
    };
};

typedef std::vector<LLWebRTCVoiceDevice> LLWebRTCVoiceDeviceList;


// The LLWebRTCDeviceObserver should be implemented by the viewer
// webrtc module, which will receive notifications when devices
// change (are unplugged, etc.)
class LLWebRTCDevicesObserver
{
  public:
    virtual void OnDevicesChanged(const LLWebRTCVoiceDeviceList &render_devices,
                                  const LLWebRTCVoiceDeviceList &capture_devices) = 0;
};


// The LLWebRTCDeviceInterface provides a way for the viewer
// to enumerate, set, and get notifications of changes
// for both capture (microphone) and render (speaker)
// devices.

class LLWebRTCDeviceInterface
{
  public:
    struct AudioConfig {

        bool mAGC { true };

        bool mEchoCancellation { true };

        // TODO: The various levels of noise suppression are configured
        // on the APM which would require setting config on the APM.
        // We should pipe the various values through
        // later.
        typedef enum {
            NOISE_SUPPRESSION_LEVEL_NONE = 0,
            NOISE_SUPPRESSION_LEVEL_LOW,
            NOISE_SUPPRESSION_LEVEL_MODERATE,
            NOISE_SUPPRESSION_LEVEL_HIGH,
            NOISE_SUPPRESSION_LEVEL_VERY_HIGH
        } ENoiseSuppressionLevel;
        ENoiseSuppressionLevel mNoiseSuppressionLevel { NOISE_SUPPRESSION_LEVEL_VERY_HIGH };
    };

    virtual void setAudioConfig(AudioConfig config) = 0;

    // instructs webrtc to refresh the device list.
    virtual void refreshDevices() = 0;

    // set the capture and render devices using the unique identifier for the device
    virtual void setCaptureDevice(const std::string& id) = 0;
    virtual void setRenderDevice(const std::string& id) = 0;

    // Device observers for device change callbacks.
    virtual void setDevicesObserver(LLWebRTCDevicesObserver *observer) = 0;
    virtual void unsetDevicesObserver(LLWebRTCDevicesObserver *observer) = 0;

    // tuning and audio levels
    virtual void setTuningMode(bool enable) = 0;
    virtual float getTuningAudioLevel() = 0; // for use during tuning
    virtual float getPeerConnectionAudioLevel() = 0; // for use when not tuning
    virtual void setPeerConnectionGain(float gain) = 0;
};

// LLWebRTCAudioInterface provides the viewer with a way
// to set audio characteristics (mute, send and receive volume)
class LLWebRTCAudioInterface
{
  public:
    virtual void setMute(bool mute) = 0;
    virtual void setReceiveVolume(float volume) = 0;  // volume between 0.0 and 1.0
    virtual void setSendVolume(float volume) = 0;  // volume between 0.0 and 1.0
};

// LLWebRTCDataObserver allows the viewer voice module to be notified when
// data is received over the data channel.
class LLWebRTCDataObserver
{
public:
    virtual void OnDataReceived(const std::string& data, bool binary) = 0;
};

// LLWebRTCDataInterface allows the viewer to send data over the data channel.
class LLWebRTCDataInterface
{
public:

    virtual void sendData(const std::string& data, bool binary=false) = 0;

    virtual void setDataObserver(LLWebRTCDataObserver *observer) = 0;
    virtual void unsetDataObserver(LLWebRTCDataObserver *observer) = 0;
};

// LLWebRTCIceCandidate is a basic structure containing
// information needed for ICE trickling.
struct LLWebRTCIceCandidate
{
    std::string mCandidate;
    std::string mSdpMid;
    int         mMLineIndex;
};

// LLWebRTCSignalingObserver provides a way for the native
// webrtc library to notify the viewer voice module of
// various state changes.
class LLWebRTCSignalingObserver
{
  public:

    typedef enum e_ice_gathering_state {
        ICE_GATHERING_NEW,
        ICE_GATHERING_GATHERING,
        ICE_GATHERING_COMPLETE
    } EIceGatheringState;

    // Called when ICE gathering states have changed.
    // This may be called at any time, as ICE gathering
    // can be redone while a connection is up.
    virtual void OnIceGatheringState(EIceGatheringState state) = 0;

    // Called when a new ice candidate is available.
    virtual void OnIceCandidate(const LLWebRTCIceCandidate& candidate) = 0;

    // Called when an offer is available after a connection is requested.
    virtual void OnOfferAvailable(const std::string& sdp) = 0;

    // Called when a connection enters a failure state and renegotiation is needed.
    virtual void OnRenegotiationNeeded() = 0;

    // Called when a peer connection has shut down
    virtual void OnPeerConnectionClosed() = 0;

    // Called when the audio channel has been established and audio
    // can begin.
    virtual void OnAudioEstablished(LLWebRTCAudioInterface *audio_interface) = 0;

    // Called when the data channel has been established and data
    // transfer can begin.
    virtual void OnDataChannelReady(LLWebRTCDataInterface *data_interface) = 0;
};

// LLWebRTCPeerConnectionInterface representsd a connection to a peer,
// in most cases a Secondlife WebRTC server.  This interface
// allows for management of this peer connection.
class LLWebRTCPeerConnectionInterface
{
  public:

    struct InitOptions
    {
        // equivalent of PeerConnectionInterface::IceServer
        struct IceServers {

            // Valid formats are described in RFC7064 and RFC7065.
            // Urls should containe dns hostnames (not IP addresses)
            // as the TLS certificate policy is 'secure.'
            // and we do not currentply support TLS extensions.
            std::vector<std::string> mUrls;
            std::string mUserName;
            std::string mPassword;
        };

        std::vector<IceServers> mServers;
    };

    virtual bool initializeConnection(const InitOptions& options) = 0;
    virtual bool shutdownConnection() = 0;

    virtual void setSignalingObserver(LLWebRTCSignalingObserver* observer) = 0;
    virtual void unsetSignalingObserver(LLWebRTCSignalingObserver* observer) = 0;

    virtual void AnswerAvailable(const std::string &sdp) = 0;
};

// The following define the dynamic linked library
// exports.

// This library must be initialized before use.
LLSYMEXPORT void init();

// And should be terminated as part of shutdown.
LLSYMEXPORT void terminate();

// Return an interface for device management.
LLSYMEXPORT LLWebRTCDeviceInterface* getDeviceInterface();

// Allocate and free peer connections.
LLSYMEXPORT LLWebRTCPeerConnectionInterface* newPeerConnection();
LLSYMEXPORT void freePeerConnection(LLWebRTCPeerConnectionInterface *connection);
}

#endif // LLWEBRTC_H