1/*
2 * Copyright (C) 2017 Apple Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "config.h"
26#include "LibWebRTCDataChannelHandler.h"
27
28#if USE(LIBWEBRTC)
29
30#include "RTCDataChannel.h"
31#include <wtf/MainThread.h>
32
33namespace WebCore {
34
35LibWebRTCDataChannelHandler::~LibWebRTCDataChannelHandler()
36{
37 if (m_client)
38 m_channel->UnregisterObserver();
39}
40
41void LibWebRTCDataChannelHandler::setClient(RTCDataChannelHandlerClient* client)
42{
43 m_client = client;
44 if (m_client)
45 m_channel->RegisterObserver(this);
46 else
47 m_channel->UnregisterObserver();
48}
49
50bool LibWebRTCDataChannelHandler::sendStringData(const String& text)
51{
52 return m_channel->Send({rtc::CopyOnWriteBuffer(text.utf8().data(), text.length()), false});
53}
54
55bool LibWebRTCDataChannelHandler::sendRawData(const char* data, size_t length)
56{
57 return m_channel->Send({rtc::CopyOnWriteBuffer(data, length), true});
58}
59
60void LibWebRTCDataChannelHandler::close()
61{
62 m_channel->Close();
63}
64
65void LibWebRTCDataChannelHandler::OnStateChange()
66{
67 RTCDataChannel::ReadyState state;
68 switch (m_channel->state()) {
69 case webrtc::DataChannelInterface::kConnecting:
70 state = RTCDataChannel::ReadyStateConnecting;
71 break;
72 case webrtc::DataChannelInterface::kOpen:
73 state = RTCDataChannel::ReadyStateOpen;
74 break;
75 case webrtc::DataChannelInterface::kClosing:
76 state = RTCDataChannel::ReadyStateClosing;
77 break;
78 case webrtc::DataChannelInterface::kClosed:
79 state = RTCDataChannel::ReadyStateClosed;
80 break;
81 }
82 ASSERT(m_client);
83 callOnMainThread([protectedClient = makeRef(*m_client), state] {
84 protectedClient->didChangeReadyState(state);
85 });
86}
87
88void LibWebRTCDataChannelHandler::OnMessage(const webrtc::DataBuffer& buffer)
89{
90 ASSERT(m_client);
91 std::unique_ptr<webrtc::DataBuffer> protectedBuffer(new webrtc::DataBuffer(buffer));
92 callOnMainThread([protectedClient = makeRef(*m_client), buffer = WTFMove(protectedBuffer)] {
93 // FIXME: Ensure this is correct by adding some tests with non-ASCII characters.
94 const char* data = reinterpret_cast<const char*>(buffer->data.data());
95 if (buffer->binary)
96 protectedClient->didReceiveRawData(data, buffer->size());
97 else
98 protectedClient->didReceiveStringData(String(data, buffer->size()));
99 });
100}
101
102void LibWebRTCDataChannelHandler::OnBufferedAmountChange(uint64_t previousAmount)
103{
104 if (previousAmount <= m_channel->buffered_amount())
105 return;
106 ASSERT(m_client);
107 callOnMainThread([protectedClient = makeRef(*m_client)] {
108 protectedClient->bufferedAmountIsDecreasing();
109 });
110}
111
112} // namespace WebCore
113
114#endif // USE(LIBWEBRTC)