1cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org/*
2cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * libjingle
3cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * Copyright 2013 Google Inc.
4cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *
5cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * Redistribution and use in source and binary forms, with or without
6cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * modification, are permitted provided that the following conditions are met:
7cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *
8cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
9cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *     this list of conditions and the following disclaimer.
10cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
11cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *     this list of conditions and the following disclaimer in the documentation
12cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *     and/or other materials provided with the distribution.
13cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *  3. The name of the author may not be used to endorse or promote products
14cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *     derived from this software without specific prior written permission.
15cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org *
16cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org */
27cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
288485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org#include "talk/app/webrtc/sctputils.h"
29cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
302a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/buffer.h"
312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/bytebuffer.h"
322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h"
33cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
348485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.orgnamespace webrtc {
35cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
36cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org// Format defined at
378485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org// http://tools.ietf.org/html/draft-ietf-rtcweb-data-protocol-01#section
38cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
39cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.orgstatic const uint8 DATA_CHANNEL_OPEN_MESSAGE_TYPE = 0x03;
408485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.orgstatic const uint8 DATA_CHANNEL_OPEN_ACK_MESSAGE_TYPE = 0x02;
41cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
42cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.orgenum DataChannelOpenMessageChannelType {
43cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  DCOMCT_ORDERED_RELIABLE = 0x00,
44cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  DCOMCT_ORDERED_PARTIAL_RTXS = 0x01,
45cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  DCOMCT_ORDERED_PARTIAL_TIME = 0x02,
46cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  DCOMCT_UNORDERED_RELIABLE = 0x80,
47cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  DCOMCT_UNORDERED_PARTIAL_RTXS = 0x81,
48cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  DCOMCT_UNORDERED_PARTIAL_TIME = 0x82,
49cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org};
50cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
512a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool ParseDataChannelOpenMessage(const rtc::Buffer& payload,
528485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org                                 std::string* label,
538485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org                                 DataChannelInit* config) {
54cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  // Format defined at
55cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  // http://tools.ietf.org/html/draft-jesup-rtcweb-data-protocol-04
56cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
572a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::ByteBuffer buffer(payload.data(), payload.length());
58cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
59cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint8 message_type;
60cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadUInt8(&message_type)) {
61cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message type.";
62cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
63cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
64cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (message_type != DATA_CHANNEL_OPEN_MESSAGE_TYPE) {
65cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Data Channel OPEN message of unexpected type: "
66cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org                    << message_type;
67cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
68cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
69cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
70cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint8 channel_type;
71cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadUInt8(&channel_type)) {
72cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message channel type.";
73cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
74cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
755c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
76cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint16 priority;
77cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadUInt16(&priority)) {
78cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message reliabilility prioirty.";
79cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
80cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
815c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  uint32 reliability_param;
825c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  if (!buffer.ReadUInt32(&reliability_param)) {
835c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message reliabilility param.";
845c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    return false;
855c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  }
86cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint16 label_length;
87cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadUInt16(&label_length)) {
88cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message label length.";
89cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
90cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
91cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint16 protocol_length;
92cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadUInt16(&protocol_length)) {
93cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message protocol length.";
94cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
95cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
96cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadString(label, (size_t) label_length)) {
97cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message label";
98cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
99cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
100cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (!buffer.ReadString(&config->protocol, protocol_length)) {
101cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN message protocol.";
102cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    return false;
103cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
104cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
105cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  config->ordered = true;
106cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  switch (channel_type) {
107cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_UNORDERED_RELIABLE:
108cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_UNORDERED_PARTIAL_RTXS:
109cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_UNORDERED_PARTIAL_TIME:
110cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      config->ordered = false;
111cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
112cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
113cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  config->maxRetransmits = -1;
114cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  config->maxRetransmitTime = -1;
115cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  switch (channel_type) {
116cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_ORDERED_PARTIAL_RTXS:
117cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_UNORDERED_PARTIAL_RTXS:
118cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      config->maxRetransmits = reliability_param;
1195c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org      break;
120cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_ORDERED_PARTIAL_TIME:
121cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    case DCOMCT_UNORDERED_PARTIAL_TIME:
122cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      config->maxRetransmitTime = reliability_param;
1235c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org      break;
124cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
1258485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  return true;
1268485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org}
1278485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org
1282a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool ParseDataChannelOpenAckMessage(const rtc::Buffer& payload) {
1292a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::ByteBuffer buffer(payload.data(), payload.length());
130cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
1318485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  uint8 message_type;
1328485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  if (!buffer.ReadUInt8(&message_type)) {
1338485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    LOG(LS_WARNING) << "Could not read OPEN_ACK message type.";
1348485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    return false;
1358485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  }
1368485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  if (message_type != DATA_CHANNEL_OPEN_ACK_MESSAGE_TYPE) {
1378485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    LOG(LS_WARNING) << "Data Channel OPEN_ACK message of unexpected type: "
1388485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org                    << message_type;
1398485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    return false;
1408485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  }
141cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  return true;
142cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org}
143cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
1448485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.orgbool WriteDataChannelOpenMessage(const std::string& label,
1458485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org                                 const DataChannelInit& config,
1462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                                 rtc::Buffer* payload) {
147cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  // Format defined at
1485c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // http://tools.ietf.org/html/draft-ietf-rtcweb-data-protocol-00#section-6.1
149cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint8 channel_type = 0;
1505c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  uint32 reliability_param = 0;
151cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  uint16 priority = 0;
152cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  if (config.ordered) {
153cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    if (config.maxRetransmits > -1) {
154cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      channel_type = DCOMCT_ORDERED_PARTIAL_RTXS;
155cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      reliability_param = config.maxRetransmits;
156cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    } else if (config.maxRetransmitTime > -1) {
157cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      channel_type = DCOMCT_ORDERED_PARTIAL_TIME;
158cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      reliability_param = config.maxRetransmitTime;
159cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    } else {
160cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      channel_type = DCOMCT_ORDERED_RELIABLE;
161cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    }
162cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  } else {
163cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    if (config.maxRetransmits > -1) {
164cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      channel_type = DCOMCT_UNORDERED_PARTIAL_RTXS;
165cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      reliability_param = config.maxRetransmits;
166cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    } else if (config.maxRetransmitTime > -1) {
167cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      channel_type = DCOMCT_UNORDERED_PARTIAL_TIME;
168cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      reliability_param = config.maxRetransmitTime;
169cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    } else {
170cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      channel_type = DCOMCT_UNORDERED_RELIABLE;
171cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org    }
172cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  }
173cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
1742a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::ByteBuffer buffer(
175cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org      NULL, 20 + label.length() + config.protocol.length(),
1762a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::ByteBuffer::ORDER_NETWORK);
177cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteUInt8(DATA_CHANNEL_OPEN_MESSAGE_TYPE);
178cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteUInt8(channel_type);
179cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteUInt16(priority);
1805c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  buffer.WriteUInt32(reliability_param);
181cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteUInt16(static_cast<uint16>(label.length()));
182cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteUInt16(static_cast<uint16>(config.protocol.length()));
183cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteString(label);
184cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  buffer.WriteString(config.protocol);
185cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  payload->SetData(buffer.Data(), buffer.Length());
186cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  return true;
187cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org}
188cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org
1892a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid WriteDataChannelOpenAckMessage(rtc::Buffer* payload) {
1902a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::ByteBuffer buffer(rtc::ByteBuffer::ORDER_NETWORK);
1918485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  buffer.WriteUInt8(DATA_CHANNEL_OPEN_ACK_MESSAGE_TYPE);
1928485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  payload->SetData(buffer.Data(), buffer.Length());
1938485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org}
1948485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org}  // namespace webrtc
195