VT: ARTPConnection: bind RTP/RTCP sockets to specific IP.
RTP/RTCP sockets needs to be bound specific IP in following cases.
- RTP/RTCP packets are coming from specific pdn.
- RTCP(ie. receiver reports) packets needs to be sent
through specific pdn.
Bug: 121230209
Change-Id: Ie695099e8182ad868c2472019fa43169ffcf5a87
Signed-off-by: Byeongjo Park <bjo.park@samsung.com>
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 6a4706d..f629d23 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -145,6 +145,77 @@
TRESPASS();
}
+// static
+void ARTPConnection::MakeRTPSocketPair(
+ int *rtpSocket, int *rtcpSocket, const char *localIp, const char *remoteIp,
+ unsigned localPort, unsigned remotePort) {
+ *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ CHECK_GE(*rtpSocket, 0);
+
+ bumpSocketBufferSize(*rtpSocket);
+
+ *rtcpSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ CHECK_GE(*rtcpSocket, 0);
+
+ bumpSocketBufferSize(*rtcpSocket);
+
+ struct sockaddr_in addr;
+ memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr(localIp);
+ addr.sin_port = htons(localPort);
+
+ int sockopt = 1;
+ setsockopt(*rtpSocket, SOL_SOCKET, SO_REUSEADDR, (int *)&sockopt, sizeof(sockopt));
+ setsockopt(*rtpSocket, SOL_SOCKET, SO_REUSEPORT, (int *)&sockopt, sizeof(sockopt));
+ setsockopt(*rtcpSocket, SOL_SOCKET, SO_REUSEADDR, (int *)&sockopt, sizeof(sockopt));
+ setsockopt(*rtcpSocket, SOL_SOCKET, SO_REUSEPORT, (int *)&sockopt, sizeof(sockopt));
+
+ if (bind(*rtpSocket,
+ (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
+ ALOGI("rtp socket successfully binded. addr=%s:%d", inet_ntoa(addr.sin_addr), localPort);
+ } else {
+ ALOGE("failed to bind rtp socket addr=%s:%d err=%s", inet_ntoa(addr.sin_addr),
+ localPort, strerror(errno));
+ return;
+ }
+
+ addr.sin_port = htons(localPort + 1);
+
+ if (bind(*rtcpSocket,
+ (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
+ ALOGI("rtcp socket successfully binded. addr=%s:%d", inet_ntoa(addr.sin_addr),
+ localPort + 1);
+ } else {
+ ALOGE("failed to bind rtcp socket addr=%s:%d err=%s", inet_ntoa(addr.sin_addr),
+ localPort + 1, strerror(errno));
+ }
+
+ // Re uses addr variable as remote addr.
+ memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr(remoteIp);
+ addr.sin_port = htons(remotePort);
+ if (connect(*rtpSocket, (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
+ ALOGI("rtp socket successfully connected to remote=%s:%d", inet_ntoa(addr.sin_addr),
+ remotePort);
+ } else {
+ ALOGE("failed to connect rtp socket to remote addr=%s:%d err=%s", inet_ntoa(addr.sin_addr),
+ remotePort, strerror(errno));
+ return;
+ }
+
+ addr.sin_port = htons(remotePort + 1);
+ if (connect(*rtcpSocket, (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
+ ALOGI("rtcp socket successfully connected to remote=%s:%d", inet_ntoa(addr.sin_addr),
+ remotePort);
+ } else {
+ ALOGE("failed to connect rtcp socket addr=%s:%d err=%s", inet_ntoa(addr.sin_addr),
+ remotePort + 1, strerror(errno));
+ return;
+ }
+}
+
void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatAddStream:
diff --git a/media/libstagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/ARTPConnection.h
index d5f7c2e..889ec30 100644
--- a/media/libstagefright/rtsp/ARTPConnection.h
+++ b/media/libstagefright/rtsp/ARTPConnection.h
@@ -49,6 +49,13 @@
// next higher port).
static void MakePortPair(
int *rtpSocket, int *rtcpSocket, unsigned *rtpPort);
+ // Creates a pair of UDP datagram sockets bound to assigned ip and
+ // ports (the rtpSocket is bound to an even port, the rtcpSocket
+ // to the next higher port).
+ static void MakeRTPSocketPair(
+ int *rtpSocket, int *rtcpSocket,
+ const char *localIp, const char *remoteIp,
+ unsigned localPort, unsigned remotePort);
protected:
virtual ~ARTPConnection();