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();