1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <webrtc/RTPSession.h>
18
19 #include <android-base/logging.h>
20
21 #include <sstream>
22
RTPSession(std::string_view localUFrag,std::string_view localPassword,std::shared_ptr<X509> localCertificate,std::shared_ptr<EVP_PKEY> localKey)23 RTPSession::RTPSession(
24 std::string_view localUFrag,
25 std::string_view localPassword,
26 std::shared_ptr<X509> localCertificate,
27 std::shared_ptr<EVP_PKEY> localKey)
28 : mLocalUFrag(localUFrag),
29 mLocalPassword(localPassword),
30 mLocalCertificate(localCertificate),
31 mLocalKey(localKey),
32 mPingToken(0),
33 mIsActive(false) {
34 }
35
isActive() const36 bool RTPSession::isActive() const {
37 return mIsActive;
38 }
39
setIsActive()40 void RTPSession::setIsActive() {
41 mIsActive = true;
42 }
43
schedulePing(std::shared_ptr<RunLoop> runLoop,RunLoop::AsyncFunction cb,std::chrono::steady_clock::duration delay)44 void RTPSession::schedulePing(
45 std::shared_ptr<RunLoop> runLoop,
46 RunLoop::AsyncFunction cb,
47 std::chrono::steady_clock::duration delay) {
48 CHECK_EQ(mPingToken, 0);
49
50 mPingToken = runLoop->postWithDelay(
51 delay,
52 [weak_this = std::weak_ptr<RTPSession>(shared_from_this()),
53 runLoop, cb]() {
54 auto me = weak_this.lock();
55 if (me) {
56 me->mPingToken = 0;
57 cb();
58 }
59 });
60 }
61
setRemoteParams(std::string_view remoteUFrag,std::string_view remotePassword,std::string_view remoteFingerprint)62 void RTPSession::setRemoteParams(
63 std::string_view remoteUFrag,
64 std::string_view remotePassword,
65 std::string_view remoteFingerprint) {
66 CHECK(!mRemoteUFrag && !mRemotePassword && !mRemoteFingerprint);
67
68 mRemoteUFrag = remoteUFrag;
69 mRemotePassword = remotePassword;
70 mRemoteFingerprint = remoteFingerprint;
71 }
72
localUFrag() const73 std::string RTPSession::localUFrag() const {
74 return mLocalUFrag;
75 }
76
localPassword() const77 std::string RTPSession::localPassword() const {
78 return mLocalPassword;
79 }
80
localCertificate() const81 std::shared_ptr<X509> RTPSession::localCertificate() const {
82 return mLocalCertificate;
83 }
84
localKey() const85 std::shared_ptr<EVP_PKEY> RTPSession::localKey() const {
86 return mLocalKey;
87 }
88
localFingerprint() const89 std::string RTPSession::localFingerprint() const {
90 auto digest = EVP_sha256();
91
92 unsigned char md[EVP_MAX_MD_SIZE];
93 unsigned int n;
94 auto res = X509_digest(mLocalCertificate.get(), digest, md, &n);
95 CHECK_EQ(res, 1);
96
97 std::stringstream ss;
98 ss << "sha-256 ";
99 for (unsigned int i = 0; i < n; ++i) {
100 if (i > 0) {
101 ss << ":";
102 }
103
104 uint8_t byte = md[i];
105 uint8_t nibble = byte >> 4;
106 ss << (char)(nibble < 10 ? '0' + nibble : 'A' + nibble - 10);
107 nibble = byte & 0xf;
108 ss << (char)(nibble < 10 ? '0' + nibble : 'A' + nibble - 10);
109 }
110
111 return ss.str();
112 }
113
remoteUFrag() const114 std::string RTPSession::remoteUFrag() const {
115 CHECK(mRemoteUFrag.has_value());
116 return *mRemoteUFrag;
117 }
118
remotePassword() const119 std::string RTPSession::remotePassword() const {
120 CHECK(mRemotePassword.has_value());
121 return *mRemotePassword;
122 }
123
remoteFingerprint() const124 std::string RTPSession::remoteFingerprint() const {
125 CHECK(mRemoteFingerprint.has_value());
126 return *mRemoteFingerprint;
127 }
128
hasRemoteAddress() const129 bool RTPSession::hasRemoteAddress() const {
130 return mRemoteAddr.has_value();
131 }
132
remoteAddress() const133 sockaddr_storage RTPSession::remoteAddress() const {
134 CHECK(hasRemoteAddress());
135 return *mRemoteAddr;
136 }
137
setRemoteAddress(const sockaddr_storage & remoteAddr)138 void RTPSession::setRemoteAddress(const sockaddr_storage &remoteAddr) {
139 CHECK(!hasRemoteAddress());
140 mRemoteAddr = remoteAddr;
141 }
142
143