1 /**
2  * Copyright (C) 2022 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 <SocketWriterNode.h>
18 #include <ImsMediaTrace.h>
19 #include <ImsMediaTimer.h>
20 
SocketWriterNode(BaseSessionCallback * callback)21 SocketWriterNode::SocketWriterNode(BaseSessionCallback* callback) :
22         BaseNode(callback)
23 {
24     mSocket = nullptr;
25     mSocketOpened = false;
26     mDisableSocket = false;
27 }
28 
~SocketWriterNode()29 SocketWriterNode::~SocketWriterNode()
30 {
31     if (mSocket != nullptr)
32     {
33         IMLOGE0("[~SocketWriterNode] socket is not closed");
34     }
35 }
36 
GetNodeId()37 kBaseNodeId SocketWriterNode::GetNodeId()
38 {
39     return kNodeIdSocketWriter;
40 }
41 
Start()42 ImsMediaResult SocketWriterNode::Start()
43 {
44     IMLOGD1("[Start] media[%d]", mMediaType);
45     mSocket = ISocket::GetInstance(mLocalAddress.port, mPeerAddress.ipAddress, mPeerAddress.port);
46 
47     if (mSocket == nullptr)
48     {
49         IMLOGE0("[Start] can't create socket instance");
50         return RESULT_NOT_READY;
51     }
52 
53     // set local/peer address here
54     mSocket->SetLocalEndpoint(mLocalAddress.ipAddress, mLocalAddress.port);
55     mSocket->SetPeerEndpoint(mPeerAddress.ipAddress, mPeerAddress.port);
56 
57     if (!mSocket->Open(mLocalFd))
58     {
59         IMLOGE0("[Start] can't open socket");
60         mSocketOpened = false;
61         return RESULT_PORT_UNAVAILABLE;
62     }
63 
64     mSocket->SetSocketOpt(kSocketOptionIpTos, mDscp);
65     mSocketOpened = true;
66     mNodeState = kNodeStateRunning;
67     return RESULT_SUCCESS;
68 }
69 
Stop()70 void SocketWriterNode::Stop()
71 {
72     IMLOGD1("[Stop] media[%d]", mMediaType);
73 
74     if (mSocket != nullptr)
75     {
76         if (mSocketOpened)
77         {
78             mSocket->Close();
79             mSocketOpened = false;
80         }
81 
82         ISocket::ReleaseInstance(mSocket);
83         mSocket = nullptr;
84     }
85 
86     mNodeState = kNodeStateStopped;
87 }
88 
IsRunTime()89 bool SocketWriterNode::IsRunTime()
90 {
91     return true;
92 }
93 
IsSourceNode()94 bool SocketWriterNode::IsSourceNode()
95 {
96     return true;
97 }
98 
SetConfig(void * config)99 void SocketWriterNode::SetConfig(void* config)
100 {
101     if (config == nullptr)
102     {
103         return;
104     }
105 
106     RtpConfig* pConfig = reinterpret_cast<RtpConfig*>(config);
107 
108     if (mProtocolType == kProtocolRtp)
109     {
110         mPeerAddress = RtpAddress(pConfig->getRemoteAddress().c_str(), pConfig->getRemotePort());
111     }
112     else if (mProtocolType == kProtocolRtcp)
113     {
114         mPeerAddress =
115                 RtpAddress(pConfig->getRemoteAddress().c_str(), pConfig->getRemotePort() + 1);
116     }
117 
118     mDscp = pConfig->getDscp();
119 }
120 
IsSameConfig(void * config)121 bool SocketWriterNode::IsSameConfig(void* config)
122 {
123     if (config == nullptr)
124     {
125         return true;
126     }
127 
128     RtpConfig* pConfig = reinterpret_cast<RtpConfig*>(config);
129     RtpAddress peerAddress;
130 
131     if (mProtocolType == kProtocolRtp)
132     {
133         peerAddress = RtpAddress(pConfig->getRemoteAddress().c_str(), pConfig->getRemotePort());
134     }
135     else if (mProtocolType == kProtocolRtcp)
136     {
137         peerAddress = RtpAddress(pConfig->getRemoteAddress().c_str(), pConfig->getRemotePort() + 1);
138     }
139 
140     return (mPeerAddress == peerAddress && mDscp == pConfig->getDscp());
141 }
142 
OnDataFromFrontNode(ImsMediaSubType subtype,uint8_t * pData,uint32_t nDataSize,uint32_t nTimestamp,bool,uint32_t nSeqNum,ImsMediaSubType,uint32_t arrivalTime)143 void SocketWriterNode::OnDataFromFrontNode(ImsMediaSubType subtype, uint8_t* pData,
144         uint32_t nDataSize, uint32_t nTimestamp, bool /*bMark*/, uint32_t nSeqNum,
145         ImsMediaSubType /*nDataType*/, uint32_t arrivalTime)
146 {
147     if (mDisableSocket == true && subtype != MEDIASUBTYPE_RTCPPACKET_BYE)
148     {
149         IMLOGW3("[OnDataFromFrontNode] media[%d] subtype[%d] socket is disabled, bytes[%d]",
150                 mMediaType, subtype, nDataSize);
151     }
152 
153     IMLOGD_PACKET4(IM_PACKET_LOG_SOCKET,
154             "[OnDataFromFrontNode] TS[%d], SeqNum[%u], size[%u], timeDiff[%d]", nTimestamp, nSeqNum,
155             nDataSize, arrivalTime != 0 ? ImsMediaTimer::GetTimeInMilliSeconds() - arrivalTime : 0);
156 
157     if (mSocket == nullptr)
158     {
159         return;
160     }
161 
162     mSocket->SendTo(pData, nDataSize);
163 }
164 
SetLocalFd(int fd)165 void SocketWriterNode::SetLocalFd(int fd)
166 {
167     mLocalFd = fd;
168 }
169 
SetLocalAddress(const RtpAddress & address)170 void SocketWriterNode::SetLocalAddress(const RtpAddress& address)
171 {
172     mLocalAddress = address;
173 }
174 
SetPeerAddress(const RtpAddress & address)175 void SocketWriterNode::SetPeerAddress(const RtpAddress& address)
176 {
177     mPeerAddress = address;
178 }