1/*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * 3. Neither the name of Google Inc. nor the names of its contributors
15 * may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32
33#if ENABLE(MEDIA_STREAM)
34
35#include "RTCPeerConnection.h"
36
37#include "ExceptionCode.h"
38#include "ScriptExecutionContext.h"
39
40namespace WebCore {
41
42// FYI: RTCIceServer and RTCConfigration are placed here temporarily.
43// Their final place is in Source/WebCore/platform/mediastream.
44class RTCIceServer : public RefCounted<RTCIceServer> {
45public:
46 static PassRefPtr<RTCIceServer> create(const String& uri, const String& password) { return adoptRef(new RTCIceServer(uri, password)); }
47 virtual ~RTCIceServer() { }
48
49 const String& uri() { return m_uri; }
50 const String& password() { return m_password; }
51
52private:
53 RTCIceServer(const String& uri, const String& password) : m_uri(uri), m_password(password) { }
54
55 String m_uri;
56 String m_password;
57};
58
59class RTCConfiguration : public RefCounted<RTCConfiguration> {
60public:
61 static PassRefPtr<RTCConfiguration> create() { return adoptRef(new RTCConfiguration()); }
62 virtual ~RTCConfiguration() { }
63
64 void appendServer(PassRefPtr<RTCIceServer> server) { m_servers.append(server); }
65 size_t numberOfServers() { return m_servers.size(); }
66 RTCIceServer* server(size_t index) { return m_servers[index].get(); }
67
68private:
69 RTCConfiguration() { }
70
71 Vector<RefPtr<RTCIceServer> > m_servers;
72};
73
74PassRefPtr<RTCConfiguration> RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionCode& ec)
75{
76 if (configuration.isUndefinedOrNull())
77 return 0;
78
79 size_t numberOfServers;
80 bool ok = configuration.getArrayLength("iceServers", numberOfServers);
81 if (!ok) {
82 ec = TYPE_MISMATCH_ERR;
83 return 0;
84 }
85
86 RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();
87
88 for (size_t i = 0; i < numberOfServers; ++i) {
89 Dictionary serverConfiguration;
90 ok = configuration.getArrayItem("iceServers", i, serverConfiguration);
91 if (!ok) {
92 ec = TYPE_MISMATCH_ERR;
93 return 0;
94 }
95
96 String uri, password;
97 ok = serverConfiguration.get("uri", uri);
98 if (!ok) {
99 ec = TYPE_MISMATCH_ERR;
100 return 0;
101 }
102 serverConfiguration.get("credential", password);
103
104 rtcConfiguration->appendServer(RTCIceServer::create(uri, password));
105 }
106
107 return rtcConfiguration.release();
108}
109
110PassRefPtr<RTCPeerConnection> RTCPeerConnection::create(ScriptExecutionContext* context, const Dictionary& rtcConfiguration, const Dictionary&, ExceptionCode& ec)
111{
112 RefPtr<RTCConfiguration> configuration = parseConfiguration(rtcConfiguration, ec);
113 if (ec)
114 return 0;
115
116 RefPtr<RTCPeerConnection> peerConnection = adoptRef(new RTCPeerConnection(context, configuration.release(), ec));
117 if (ec)
118 return 0;
119
120 peerConnection->suspendIfNeeded();
121 return peerConnection.release();
122}
123
124RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext* context, PassRefPtr<RTCConfiguration>, ExceptionCode& ec)
125 : ActiveDOMObject(context, this)
126{
127}
128
129RTCPeerConnection::~RTCPeerConnection()
130{
131}
132
133const AtomicString& RTCPeerConnection::interfaceName() const
134{
135 return eventNames().interfaceForRTCPeerConnection;
136}
137
138ScriptExecutionContext* RTCPeerConnection::scriptExecutionContext() const
139{
140 return ActiveDOMObject::scriptExecutionContext();
141}
142
143void RTCPeerConnection::stop()
144{
145}
146
147EventTargetData* RTCPeerConnection::eventTargetData()
148{
149 return &m_eventTargetData;
150}
151
152EventTargetData* RTCPeerConnection::ensureEventTargetData()
153{
154 return &m_eventTargetData;
155}
156
157} // namespace WebCore
158
159#endif // ENABLE(MEDIA_STREAM)