16f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber/* 26f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * Copyright 2012, The Android Open Source Project 36f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * 46f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 56f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * you may not use this file except in compliance with the License. 66f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * You may obtain a copy of the License at 76f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * 86f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 96f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * 106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * Unless required by applicable law or agreed to in writing, software 116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * See the License for the specific language governing permissions and 146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber * limitations under the License. 156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber */ 166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber//#define LOG_NDEBUG 0 186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#define LOG_TAG "NetworkSession" 196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <utils/Log.h> 206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include "ANetworkSession.h" 226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include "ParsedMessage.h" 236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 246f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <arpa/inet.h> 256f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <fcntl.h> 2643433111d4adff6a138447dfadf531046497a008Andreas Huber#include <linux/tcp.h> 276f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <net/if.h> 286f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <netdb.h> 296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <netinet/in.h> 309dffd24e00a1b2abd5e2dcc2366c0327ec3701b8Andreas Huber#include <sys/ioctl.h> 316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <sys/socket.h> 326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <media/stagefright/foundation/ADebug.h> 356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <media/stagefright/foundation/AMessage.h> 366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#include <media/stagefright/foundation/hexdump.h> 376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Hubernamespace android { 396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 408060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huberstatic uint16_t U16_AT(const uint8_t *ptr) { 418060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return ptr[0] << 8 | ptr[1]; 428060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber} 438060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 448060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huberstatic uint32_t U32_AT(const uint8_t *ptr) { 458060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 468060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber} 478060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 488060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huberstatic uint64_t U64_AT(const uint8_t *ptr) { 498060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 508060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber} 518060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatic const size_t kMaxUDPSize = 1500; 5399f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhangstatic const int32_t kMaxUDPRetries = 200; 546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstruct ANetworkSession::NetworkThread : public Thread { 56090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh explicit NetworkThread(ANetworkSession *session); 576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberprotected: 596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber virtual ~NetworkThread(); 606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberprivate: 626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ANetworkSession *mSession; 636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber virtual bool threadLoop(); 656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(NetworkThread); 676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber}; 686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstruct ANetworkSession::Session : public RefBase { 708060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber enum Mode { 718060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber MODE_RTSP, 728060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber MODE_DATAGRAM, 738060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber MODE_WEBSOCKET, 748060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber }; 758060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber enum State { 776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CONNECTING, 786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CONNECTED, 797d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber LISTENING_RTSP, 807d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber LISTENING_TCP_DGRAMS, 816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber DATAGRAM, 826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber }; 836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Session(int32_t sessionID, 856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber State state, 866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int s, 876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<AMessage> ¬ify); 886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t sessionID() const; 906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int socket() const; 916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> getNotificationMessage() const; 926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 937d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber bool isRTSPServer() const; 947d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber bool isTCPDatagramServer() const; 956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber bool wantsToRead(); 976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber bool wantsToWrite(); 986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t readMore(); 1006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t writeMore(); 1016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 102632177b7446185a0407b7df96f684a9b8b980765Andreas Huber status_t sendRequest( 103632177b7446185a0407b7df96f684a9b8b980765Andreas Huber const void *data, ssize_t size, bool timeValid, int64_t timeUs); 1046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1058060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber void setMode(Mode mode); 1068060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 1078060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber status_t switchToWebSocketMode(); 1087d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 1096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberprotected: 1106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber virtual ~Session(); 1116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberprivate: 113632177b7446185a0407b7df96f684a9b8b980765Andreas Huber enum { 114632177b7446185a0407b7df96f684a9b8b980765Andreas Huber FRAGMENT_FLAG_TIME_VALID = 1, 115632177b7446185a0407b7df96f684a9b8b980765Andreas Huber }; 116632177b7446185a0407b7df96f684a9b8b980765Andreas Huber struct Fragment { 117632177b7446185a0407b7df96f684a9b8b980765Andreas Huber uint32_t mFlags; 118632177b7446185a0407b7df96f684a9b8b980765Andreas Huber int64_t mTimeUs; 119632177b7446185a0407b7df96f684a9b8b980765Andreas Huber sp<ABuffer> mBuffer; 120632177b7446185a0407b7df96f684a9b8b980765Andreas Huber }; 121632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 1226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t mSessionID; 1236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber State mState; 1248060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber Mode mMode; 1256f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int mSocket; 1266f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> mNotify; 1276f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber bool mSawReceiveFailure, mSawSendFailure; 12899f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang int32_t mUDPRetries; 1296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 130632177b7446185a0407b7df96f684a9b8b980765Andreas Huber List<Fragment> mOutFragments; 1316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber AString mInBuffer; 1336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 134e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber int64_t mLastStallReportUs; 135e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber 1366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber void notifyError(bool send, status_t err, const char *detail); 1376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber void notify(NotificationReason reason); 1386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 139632177b7446185a0407b7df96f684a9b8b980765Andreas Huber void dumpFragmentStats(const Fragment &frag); 140632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 1416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Session); 1426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber}; 1436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber//////////////////////////////////////////////////////////////////////////////// 1446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas HuberANetworkSession::NetworkThread::NetworkThread(ANetworkSession *session) 1466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber : mSession(session) { 1476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 1486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas HuberANetworkSession::NetworkThread::~NetworkThread() { 1506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 1516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberbool ANetworkSession::NetworkThread::threadLoop() { 1536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSession->threadLoop(); 1546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return true; 1566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 1576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber//////////////////////////////////////////////////////////////////////////////// 1596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas HuberANetworkSession::Session::Session( 1616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t sessionID, 1626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber State state, 1636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int s, 1646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<AMessage> ¬ify) 1656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber : mSessionID(sessionID), 1666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mState(state), 1678060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber mMode(MODE_DATAGRAM), 1686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSocket(s), 1696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mNotify(notify), 1706f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSawReceiveFailure(false), 171e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber mSawSendFailure(false), 17299f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries(kMaxUDPRetries), 173e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber mLastStallReportUs(-1ll) { 1746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mState == CONNECTED) { 1756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in localAddr; 1766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber socklen_t localAddrLen = sizeof(localAddr); 1776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int res = getsockname( 1796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSocket, (struct sockaddr *)&localAddr, &localAddrLen); 1806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_GE(res, 0); 1816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in remoteAddr; 1836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 1846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = getpeername( 1866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSocket, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 1876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_GE(res, 0); 1886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber in_addr_t addr = ntohl(localAddr.sin_addr.s_addr); 190a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AString localAddrString = AStringPrintf( 1916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber "%d.%d.%d.%d", 1926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 24), 1936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 16) & 0xff, 1946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 8) & 0xff, 1956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr & 0xff); 1966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr = ntohl(remoteAddr.sin_addr.s_addr); 198a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AString remoteAddrString = AStringPrintf( 1996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber "%d.%d.%d.%d", 2006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 24), 2016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 16) & 0xff, 2026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 8) & 0xff, 2036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr & 0xff); 2046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> msg = mNotify->dup(); 2066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("sessionID", mSessionID); 2076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("reason", kWhatClientConnected); 2086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setString("server-ip", localAddrString.c_str()); 2096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("server-port", ntohs(localAddr.sin_port)); 2106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setString("client-ip", remoteAddrString.c_str()); 2116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("client-port", ntohs(remoteAddr.sin_port)); 2126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->post(); 2136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 2146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas HuberANetworkSession::Session::~Session() { 217a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber ALOGV("Session %d gone", mSessionID); 2186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(mSocket); 2206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSocket = -1; 2216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberint32_t ANetworkSession::Session::sessionID() const { 2246f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return mSessionID; 2256f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2266f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2276f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberint ANetworkSession::Session::socket() const { 2286f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return mSocket; 2296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2306f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2318060060217ff16cd67c8f6a15c649f44c343acf0Andreas Hubervoid ANetworkSession::Session::setMode(Mode mode) { 2328060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber mMode = mode; 2338060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber} 2348060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 2358060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huberstatus_t ANetworkSession::Session::switchToWebSocketMode() { 2368060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (mState != CONNECTED || mMode != MODE_RTSP) { 2378060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return INVALID_OPERATION; 2388060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 2398060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 2408060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber mMode = MODE_WEBSOCKET; 2418060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 2428060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return OK; 2437d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber} 2447d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 2456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Hubersp<AMessage> ANetworkSession::Session::getNotificationMessage() const { 2466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return mNotify; 2476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2497d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huberbool ANetworkSession::Session::isRTSPServer() const { 2507d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber return mState == LISTENING_RTSP; 2517d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber} 2527d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 2537d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huberbool ANetworkSession::Session::isTCPDatagramServer() const { 2547d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber return mState == LISTENING_TCP_DGRAMS; 2556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberbool ANetworkSession::Session::wantsToRead() { 2586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return !mSawReceiveFailure && mState != CONNECTING; 2596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberbool ANetworkSession::Session::wantsToWrite() { 2626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return !mSawSendFailure 2636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber && (mState == CONNECTING 264632177b7446185a0407b7df96f684a9b8b980765Andreas Huber || (mState == CONNECTED && !mOutFragments.empty()) 265632177b7446185a0407b7df96f684a9b8b980765Andreas Huber || (mState == DATAGRAM && !mOutFragments.empty())); 2666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 2676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::Session::readMore() { 2696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mState == DATAGRAM) { 2708060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber CHECK_EQ(mMode, MODE_DATAGRAM); 2718060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 2726f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err; 2736f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 2746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<ABuffer> buf = new ABuffer(kMaxUDPSize); 2756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in remoteAddr; 2776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 2786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t n; 2806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 2816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber n = recvfrom( 2826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSocket, buf->data(), buf->capacity(), 0, 2836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (struct sockaddr *)&remoteAddr, &remoteAddrLen); 2846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } while (n < 0 && errno == EINTR); 2856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = OK; 2876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (n < 0) { 2886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 2896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else if (n == 0) { 2906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -ECONNRESET; 2916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 2926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber buf->setRange(0, n); 2936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 2956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber buf->meta()->setInt64("arrivalTimeUs", nowUs); 2966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 2976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> notify = mNotify->dup(); 2986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->setInt32("sessionID", mSessionID); 2996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->setInt32("reason", kWhatDatagram); 3006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber uint32_t ip = ntohl(remoteAddr.sin_addr.s_addr); 3026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->setString( 3036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber "fromAddr", 304a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AStringPrintf( 3056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber "%u.%u.%u.%u", 3066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ip >> 24, 3076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (ip >> 16) & 0xff, 3086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (ip >> 8) & 0xff, 3096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ip & 0xff).c_str()); 3106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->setInt32("fromPort", ntohs(remoteAddr.sin_port)); 3126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->setBuffer("data", buf); 3146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->post(); 3156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 3166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } while (err == OK); 3176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err == -EAGAIN) { 3196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = OK; 3206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 3216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 32399f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang if (!mUDPRetries) { 32499f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang notifyError(false /* send */, err, "Recvfrom failed."); 32599f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mSawReceiveFailure = true; 32699f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang } else { 32799f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries--; 32899f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang ALOGE("Recvfrom failed, %d/%d retries left", 32999f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries, kMaxUDPRetries); 33099f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang err = OK; 33199f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang } 33299f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang } else { 33399f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries = kMaxUDPRetries; 3346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 3356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 3376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 3386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber char tmp[512]; 3406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t n; 3416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 3426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber n = recv(mSocket, tmp, sizeof(tmp), 0); 3436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } while (n < 0 && errno == EINTR); 3446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = OK; 3466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (n > 0) { 3486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mInBuffer.append(tmp, n); 3496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#if 0 3516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGI("in:"); 3526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber hexdump(tmp, n); 3536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#endif 3546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else if (n < 0) { 3556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 3566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 3576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -ECONNRESET; 3586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 3596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3608060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (mMode == MODE_DATAGRAM) { 3617d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber // TCP stream carrying 16-bit length-prefixed datagrams. 3626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3637d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber while (mInBuffer.size() >= 2) { 3647d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber size_t packetSize = U16_AT((const uint8_t *)mInBuffer.c_str()); 3656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3667d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mInBuffer.size() < packetSize + 2) { 3676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber break; 3686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 3696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3707d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sp<ABuffer> packet = new ABuffer(packetSize); 3717d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber memcpy(packet->data(), mInBuffer.c_str() + 2, packetSize); 3727d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 37343433111d4adff6a138447dfadf531046497a008Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 37443433111d4adff6a138447dfadf531046497a008Andreas Huber packet->meta()->setInt64("arrivalTimeUs", nowUs); 37543433111d4adff6a138447dfadf531046497a008Andreas Huber 3766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> notify = mNotify->dup(); 3776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify->setInt32("sessionID", mSessionID); 3787d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setInt32("reason", kWhatDatagram); 3797d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setBuffer("data", packet); 3807d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->post(); 3816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3827d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber mInBuffer.erase(0, packetSize + 2); 3837d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 3848060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else if (mMode == MODE_RTSP) { 3857d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber for (;;) { 3867d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber size_t length; 3876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3887d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mInBuffer.size() > 0 && mInBuffer.c_str()[0] == '$') { 3897d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mInBuffer.size() < 4) { 3907d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber break; 3917d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 3926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3937d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber length = U16_AT((const uint8_t *)mInBuffer.c_str() + 2); 3946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3957d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mInBuffer.size() < 4 + length) { 3967d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber break; 3977d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 3986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 3997d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sp<AMessage> notify = mNotify->dup(); 4007d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setInt32("sessionID", mSessionID); 4017d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setInt32("reason", kWhatBinaryData); 4027d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setInt32("channel", mInBuffer.c_str()[1]); 4036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 4047d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sp<ABuffer> data = new ABuffer(length); 4057d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber memcpy(data->data(), mInBuffer.c_str() + 4, length); 4066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 4077d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 4087d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber data->meta()->setInt64("arrivalTimeUs", nowUs); 4097d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 4107d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setBuffer("data", data); 4117d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->post(); 4127d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 4137d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber mInBuffer.erase(0, 4 + length); 4147d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber continue; 4157d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 4167d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 4177d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sp<ParsedMessage> msg = 4187d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber ParsedMessage::Parse( 4197d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber mInBuffer.c_str(), mInBuffer.size(), err != OK, &length); 4207d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 4217d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (msg == NULL) { 4227d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber break; 4237d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 4247d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 4257d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sp<AMessage> notify = mNotify->dup(); 4267d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setInt32("sessionID", mSessionID); 4277d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setInt32("reason", kWhatData); 4287d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->setObject("data", msg); 4297d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify->post(); 4306f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 4316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#if 1 4327d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber // XXX The (old) dongle sends the wrong content length header on a 4337d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber // SET_PARAMETER request that signals a "wfd_idr_request". 4347d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber // (17 instead of 19). 4357d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber const char *content = msg->getContent(); 4367d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (content 4377d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber && !memcmp(content, "wfd_idr_request\r\n", 17) 4387d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber && length >= 19 4397d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber && mInBuffer.c_str()[length] == '\r' 4407d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber && mInBuffer.c_str()[length + 1] == '\n') { 4417d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber length += 2; 4427d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 4436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber#endif 4446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 4457d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber mInBuffer.erase(0, length); 4466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 4477d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (err != OK) { 4487d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber break; 4497d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 4506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 4518060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else { 4528060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber CHECK_EQ(mMode, MODE_WEBSOCKET); 4538060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4548060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber const uint8_t *data = (const uint8_t *)mInBuffer.c_str(); 4558060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber // hexdump(data, mInBuffer.size()); 4568060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4578060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber while (mInBuffer.size() >= 2) { 4588060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber size_t offset = 2; 4598060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4601f87316768127dc569135f8a488786135b88c221Robert Shih uint64_t payloadLen = data[1] & 0x7f; 4618060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (payloadLen == 126) { 4628060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (offset + 2 > mInBuffer.size()) { 4638060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber break; 4648060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 4658060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4668060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber payloadLen = U16_AT(&data[offset]); 4678060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber offset += 2; 4688060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else if (payloadLen == 127) { 4698060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (offset + 8 > mInBuffer.size()) { 4708060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber break; 4718060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 4728060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4738060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber payloadLen = U64_AT(&data[offset]); 4748060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber offset += 8; 4758060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 4768060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4778060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber uint32_t mask = 0; 4788060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (data[1] & 0x80) { 4798060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber // MASK==1 4808060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (offset + 4 > mInBuffer.size()) { 4818060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber break; 4828060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 4838060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4848060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber mask = U32_AT(&data[offset]); 4858060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber offset += 4; 4868060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 4878060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4881f87316768127dc569135f8a488786135b88c221Robert Shih if (payloadLen > mInBuffer.size() || offset > mInBuffer.size() - payloadLen) { 4898060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber break; 4908060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 4918060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4928060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber // We have the full message. 4938060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4948060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber sp<ABuffer> packet = new ABuffer(payloadLen); 4958060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber memcpy(packet->data(), &data[offset], payloadLen); 4968060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 4978060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (mask != 0) { 4988060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber for (size_t i = 0; i < payloadLen; ++i) { 4998060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber packet->data()[i] = 5008060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber data[offset + i] 5018060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber ^ ((mask >> (8 * (3 - (i % 4)))) & 0xff); 5028060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 5038060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 5048060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 5058060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber sp<AMessage> notify = mNotify->dup(); 5068060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber notify->setInt32("sessionID", mSessionID); 5078060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber notify->setInt32("reason", kWhatWebSocketMessage); 5088060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber notify->setBuffer("data", packet); 5098060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber notify->setInt32("headerByte", data[0]); 5108060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber notify->post(); 5118060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 5128060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber mInBuffer.erase(0, offset + payloadLen); 5138060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 5146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 5156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 5176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notifyError(false /* send */, err, "Recv failed."); 5186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSawReceiveFailure = true; 5196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 5206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 5226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 5236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 524d411b4ca2945cd8974a3a78199fce94646950128Andreas Hubervoid ANetworkSession::Session::dumpFragmentStats(const Fragment & /* frag */) { 525632177b7446185a0407b7df96f684a9b8b980765Andreas Huber#if 0 526632177b7446185a0407b7df96f684a9b8b980765Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 527632177b7446185a0407b7df96f684a9b8b980765Andreas Huber int64_t delayMs = (nowUs - frag.mTimeUs) / 1000ll; 528632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 529632177b7446185a0407b7df96f684a9b8b980765Andreas Huber static const int64_t kMinDelayMs = 0; 530632177b7446185a0407b7df96f684a9b8b980765Andreas Huber static const int64_t kMaxDelayMs = 300; 531632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 532632177b7446185a0407b7df96f684a9b8b980765Andreas Huber const char *kPattern = "########################################"; 533632177b7446185a0407b7df96f684a9b8b980765Andreas Huber size_t kPatternSize = strlen(kPattern); 534632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 535632177b7446185a0407b7df96f684a9b8b980765Andreas Huber int n = (kPatternSize * (delayMs - kMinDelayMs)) 536632177b7446185a0407b7df96f684a9b8b980765Andreas Huber / (kMaxDelayMs - kMinDelayMs); 537632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 538632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (n < 0) { 539632177b7446185a0407b7df96f684a9b8b980765Andreas Huber n = 0; 540632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } else if ((size_t)n > kPatternSize) { 541632177b7446185a0407b7df96f684a9b8b980765Andreas Huber n = kPatternSize; 542632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 543632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 544632177b7446185a0407b7df96f684a9b8b980765Andreas Huber ALOGI("[%lld]: (%4lld ms) %s\n", 545632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mTimeUs / 1000, 546632177b7446185a0407b7df96f684a9b8b980765Andreas Huber delayMs, 547632177b7446185a0407b7df96f684a9b8b980765Andreas Huber kPattern + kPatternSize - n); 548632177b7446185a0407b7df96f684a9b8b980765Andreas Huber#endif 549632177b7446185a0407b7df96f684a9b8b980765Andreas Huber} 550632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 5516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::Session::writeMore() { 5526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mState == DATAGRAM) { 553632177b7446185a0407b7df96f684a9b8b980765Andreas Huber CHECK(!mOutFragments.empty()); 5546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err; 5566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 557632177b7446185a0407b7df96f684a9b8b980765Andreas Huber const Fragment &frag = *mOutFragments.begin(); 558632177b7446185a0407b7df96f684a9b8b980765Andreas Huber const sp<ABuffer> &datagram = frag.mBuffer; 5596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int n; 5616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 562bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber n = send(mSocket, datagram->data(), datagram->size(), 0); 5636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } while (n < 0 && errno == EINTR); 5646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = OK; 5666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (n > 0) { 568632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (frag.mFlags & FRAGMENT_FLAG_TIME_VALID) { 569632177b7446185a0407b7df96f684a9b8b980765Andreas Huber dumpFragmentStats(frag); 570632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 571632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 572632177b7446185a0407b7df96f684a9b8b980765Andreas Huber mOutFragments.erase(mOutFragments.begin()); 5736f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else if (n < 0) { 5746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 5756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else if (n == 0) { 5766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -ECONNRESET; 5776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 578632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } while (err == OK && !mOutFragments.empty()); 5796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err == -EAGAIN) { 581632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (!mOutFragments.empty()) { 58267c036a3faada8b77d73cf81bd1b0be4cb60c562Colin Cross ALOGI("%zu datagrams remain queued.", mOutFragments.size()); 58383c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber } 5846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = OK; 5856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 5866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 5876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 58899f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang if (!mUDPRetries) { 58999f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang notifyError(true /* send */, err, "Send datagram failed."); 59099f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mSawSendFailure = true; 59199f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang } else { 59299f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries--; 59399f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang ALOGE("Send datagram failed, %d/%d retries left", 59499f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries, kMaxUDPRetries); 59599f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang err = OK; 59699f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang } 59799f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang } else { 59899f27cdf2c2711aa0c8b4d9ae4d12cae37ff94f6Chong Zhang mUDPRetries = kMaxUDPRetries; 5996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 6006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 6026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 6036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mState == CONNECTING) { 6056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int err; 6066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber socklen_t optionLen = sizeof(err); 6076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0); 6086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_EQ(optionLen, (socklen_t)sizeof(err)); 6096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != 0) { 6116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notifyError(kWhatError, -err, "Connection failed"); 6126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSawSendFailure = true; 6136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6147d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber return -err; 6156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 6166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mState = CONNECTED; 6186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify(kWhatConnected); 6196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return OK; 6216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 6226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_EQ(mState, CONNECTED); 624632177b7446185a0407b7df96f684a9b8b980765Andreas Huber CHECK(!mOutFragments.empty()); 6256f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6265d5f8a5d3cf24b5dcf1267ef512b24caa695787aAmit Pundir ssize_t n = -1; 627632177b7446185a0407b7df96f684a9b8b980765Andreas Huber while (!mOutFragments.empty()) { 628632177b7446185a0407b7df96f684a9b8b980765Andreas Huber const Fragment &frag = *mOutFragments.begin(); 6296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 630632177b7446185a0407b7df96f684a9b8b980765Andreas Huber do { 631632177b7446185a0407b7df96f684a9b8b980765Andreas Huber n = send(mSocket, frag.mBuffer->data(), frag.mBuffer->size(), 0); 632632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } while (n < 0 && errno == EINTR); 6336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 634632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (n <= 0) { 635632177b7446185a0407b7df96f684a9b8b980765Andreas Huber break; 636632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 6376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 638632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mBuffer->setRange( 639632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mBuffer->offset() + n, frag.mBuffer->size() - n); 640632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 641632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (frag.mBuffer->size() > 0) { 642632177b7446185a0407b7df96f684a9b8b980765Andreas Huber break; 643632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 644632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 645632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (frag.mFlags & FRAGMENT_FLAG_TIME_VALID) { 646632177b7446185a0407b7df96f684a9b8b980765Andreas Huber dumpFragmentStats(frag); 647632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 648632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 649632177b7446185a0407b7df96f684a9b8b980765Andreas Huber mOutFragments.erase(mOutFragments.begin()); 650632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 651632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 652632177b7446185a0407b7df96f684a9b8b980765Andreas Huber status_t err = OK; 653632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 654632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (n < 0) { 6556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 6566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else if (n == 0) { 6576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -ECONNRESET; 6586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 6596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 6606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 6616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notifyError(true /* send */, err, "Send failed."); 6626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSawSendFailure = true; 6636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 6646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 665dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber#if 0 6669dffd24e00a1b2abd5e2dcc2366c0327ec3701b8Andreas Huber int numBytesQueued; 6679dffd24e00a1b2abd5e2dcc2366c0327ec3701b8Andreas Huber int res = ioctl(mSocket, SIOCOUTQ, &numBytesQueued); 668e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber if (res == 0 && numBytesQueued > 50 * 1024) { 669e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber if (numBytesQueued > 409600) { 670e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber ALOGW("!!! numBytesQueued = %d", numBytesQueued); 671e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber } 672e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber 673e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 674e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber 675e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber if (mLastStallReportUs < 0ll 676dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber || nowUs > mLastStallReportUs + 100000ll) { 677e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber sp<AMessage> msg = mNotify->dup(); 678e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber msg->setInt32("sessionID", mSessionID); 679e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber msg->setInt32("reason", kWhatNetworkStall); 680e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber msg->setSize("numBytesQueued", numBytesQueued); 681e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber msg->post(); 682e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber 683e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber mLastStallReportUs = nowUs; 684e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber } 6859dffd24e00a1b2abd5e2dcc2366c0327ec3701b8Andreas Huber } 6869dffd24e00a1b2abd5e2dcc2366c0327ec3701b8Andreas Huber#endif 6879dffd24e00a1b2abd5e2dcc2366c0327ec3701b8Andreas Huber 6886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 6896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 6906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 691632177b7446185a0407b7df96f684a9b8b980765Andreas Huberstatus_t ANetworkSession::Session::sendRequest( 692632177b7446185a0407b7df96f684a9b8b980765Andreas Huber const void *data, ssize_t size, bool timeValid, int64_t timeUs) { 6936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK(mState == CONNECTED || mState == DATAGRAM); 6946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 695632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (size < 0) { 696632177b7446185a0407b7df96f684a9b8b980765Andreas Huber size = strlen((const char *)data); 697632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 698bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber 699632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (size == 0) { 700bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber return OK; 701bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber } 702bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber 703632177b7446185a0407b7df96f684a9b8b980765Andreas Huber sp<ABuffer> buffer; 704632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 7058060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (mState == CONNECTED && mMode == MODE_DATAGRAM) { 7067d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber CHECK_LE(size, 65535); 7077d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 708632177b7446185a0407b7df96f684a9b8b980765Andreas Huber buffer = new ABuffer(size + 2); 709632177b7446185a0407b7df96f684a9b8b980765Andreas Huber buffer->data()[0] = size >> 8; 710632177b7446185a0407b7df96f684a9b8b980765Andreas Huber buffer->data()[1] = size & 0xff; 711632177b7446185a0407b7df96f684a9b8b980765Andreas Huber memcpy(buffer->data() + 2, data, size); 7128060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else if (mState == CONNECTED && mMode == MODE_WEBSOCKET) { 7138060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber static const bool kUseMask = false; // Chromium doesn't like it. 7148060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 7158060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber size_t numHeaderBytes = 2 + (kUseMask ? 4 : 0); 7168060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (size > 65535) { 7178060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber numHeaderBytes += 8; 7188060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else if (size > 125) { 7198060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber numHeaderBytes += 2; 7208060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 7218060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 7228060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer = new ABuffer(numHeaderBytes + size); 7238060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[0] = 0x81; // FIN==1 | opcode=1 (text) 7248060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[1] = kUseMask ? 0x80 : 0x00; 7258060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 7268060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (size > 65535) { 7278060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[1] |= 127; 7288060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[2] = 0x00; 7298060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[3] = 0x00; 7308060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[4] = 0x00; 7318060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[5] = 0x00; 7328060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[6] = (size >> 24) & 0xff; 7338060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[7] = (size >> 16) & 0xff; 7348060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[8] = (size >> 8) & 0xff; 7358060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[9] = size & 0xff; 7368060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else if (size > 125) { 7378060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[1] |= 126; 7388060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[2] = (size >> 8) & 0xff; 7398060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[3] = size & 0xff; 7408060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else { 7418060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[1] |= size; 7428060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 7438060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 7448060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (kUseMask) { 7458060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber uint32_t mask = rand(); 7468060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 7478060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[numHeaderBytes - 4] = (mask >> 24) & 0xff; 7488060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[numHeaderBytes - 3] = (mask >> 16) & 0xff; 7498060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[numHeaderBytes - 2] = (mask >> 8) & 0xff; 7508060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[numHeaderBytes - 1] = mask & 0xff; 7518060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 7528060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber for (size_t i = 0; i < (size_t)size; ++i) { 7538060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber buffer->data()[numHeaderBytes + i] = 7548060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber ((const uint8_t *)data)[i] 7558060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber ^ ((mask >> (8 * (3 - (i % 4)))) & 0xff); 7568060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 7578060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } else { 7588060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber memcpy(buffer->data() + numHeaderBytes, data, size); 7598060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 760632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } else { 761632177b7446185a0407b7df96f684a9b8b980765Andreas Huber buffer = new ABuffer(size); 762632177b7446185a0407b7df96f684a9b8b980765Andreas Huber memcpy(buffer->data(), data, size); 763632177b7446185a0407b7df96f684a9b8b980765Andreas Huber } 7647d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 765632177b7446185a0407b7df96f684a9b8b980765Andreas Huber Fragment frag; 766632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 767632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mFlags = 0; 768632177b7446185a0407b7df96f684a9b8b980765Andreas Huber if (timeValid) { 769632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mFlags = FRAGMENT_FLAG_TIME_VALID; 770632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mTimeUs = timeUs; 7717d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 7727d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 773632177b7446185a0407b7df96f684a9b8b980765Andreas Huber frag.mBuffer = buffer; 774632177b7446185a0407b7df96f684a9b8b980765Andreas Huber 775632177b7446185a0407b7df96f684a9b8b980765Andreas Huber mOutFragments.push_back(frag); 7766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 7776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return OK; 7786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 7796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 7806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Hubervoid ANetworkSession::Session::notifyError( 7816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber bool send, status_t err, const char *detail) { 7826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> msg = mNotify->dup(); 7836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("sessionID", mSessionID); 7846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("reason", kWhatError); 7856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("send", send); 7866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("err", err); 7876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setString("detail", detail); 7886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->post(); 7896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 7906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 7916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Hubervoid ANetworkSession::Session::notify(NotificationReason reason) { 7926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<AMessage> msg = mNotify->dup(); 7936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("sessionID", mSessionID); 7946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->setInt32("reason", reason); 7956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber msg->post(); 7966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 7976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 7986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber//////////////////////////////////////////////////////////////////////////////// 7996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas HuberANetworkSession::ANetworkSession() 8016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber : mNextSessionID(1) { 8026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mPipeFd[0] = mPipeFd[1] = -1; 8036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas HuberANetworkSession::~ANetworkSession() { 8066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber stop(); 8076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::start() { 8106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mThread != NULL) { 8116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return INVALID_OPERATION; 8126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 8136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int res = pipe(mPipeFd); 8156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res != 0) { 8166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mPipeFd[0] = mPipeFd[1] = -1; 8176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return -errno; 8186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 8196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mThread = new NetworkThread(this); 8216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = mThread->run("ANetworkSession", ANDROID_PRIORITY_AUDIO); 8236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8246f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 8256f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mThread.clear(); 8266f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8276f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(mPipeFd[0]); 8286f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(mPipeFd[1]); 8296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mPipeFd[0] = mPipeFd[1] = -1; 8306f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 8326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 8336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return OK; 8356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::stop() { 8386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mThread == NULL) { 8396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return INVALID_OPERATION; 8406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 8416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mThread->requestExit(); 8436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber interrupt(); 8446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mThread->requestExitAndWait(); 8456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mThread.clear(); 8476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(mPipeFd[0]); 8496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(mPipeFd[1]); 8506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mPipeFd[0] = mPipeFd[1] = -1; 8516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return OK; 8536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::createRTSPClient( 8566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const char *host, unsigned port, const sp<AMessage> ¬ify, 8576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t *sessionID) { 8586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return createClientOrServer( 8596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber kModeCreateRTSPClient, 860ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber NULL /* addr */, 8616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 0 /* port */, 8626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber host, 8636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber port, 8646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify, 8656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sessionID); 8666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::createRTSPServer( 869ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber const struct in_addr &addr, unsigned port, 870ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber const sp<AMessage> ¬ify, int32_t *sessionID) { 8716f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return createClientOrServer( 8726f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber kModeCreateRTSPServer, 873ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber &addr, 8746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber port, 8756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber NULL /* remoteHost */, 8766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 0 /* remotePort */, 8776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify, 8786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sessionID); 8796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::createUDPSession( 8826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber unsigned localPort, const sp<AMessage> ¬ify, int32_t *sessionID) { 8836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return createUDPSession(localPort, NULL, 0, notify, sessionID); 8846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 8856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 8866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::createUDPSession( 8876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber unsigned localPort, 8886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const char *remoteHost, 8896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber unsigned remotePort, 8906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<AMessage> ¬ify, 8916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t *sessionID) { 8926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return createClientOrServer( 8936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber kModeCreateUDPSession, 894ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber NULL /* addr */, 8956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber localPort, 8966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteHost, 8976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remotePort, 8986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify, 8996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sessionID); 9006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 9016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9027d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huberstatus_t ANetworkSession::createTCPDatagramSession( 9037d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber const struct in_addr &addr, unsigned port, 9047d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber const sp<AMessage> ¬ify, int32_t *sessionID) { 9057d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber return createClientOrServer( 9067d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber kModeCreateTCPDatagramSessionPassive, 9077d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber &addr, 9087d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber port, 9097d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber NULL /* remoteHost */, 9107d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 0 /* remotePort */, 9117d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify, 9127d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sessionID); 9137d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber} 9147d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 9157d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huberstatus_t ANetworkSession::createTCPDatagramSession( 9167d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber unsigned localPort, 9177d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber const char *remoteHost, 9187d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber unsigned remotePort, 9197d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber const sp<AMessage> ¬ify, 9207d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber int32_t *sessionID) { 9217d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber return createClientOrServer( 9227d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber kModeCreateTCPDatagramSessionActive, 9237d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber NULL /* addr */, 9247d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber localPort, 9257d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber remoteHost, 9267d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber remotePort, 9277d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber notify, 9287d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber sessionID); 9297d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber} 9307d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 9316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::destroySession(int32_t sessionID) { 9326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mutex::Autolock autoLock(mLock); 9336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 9356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (index < 0) { 9376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return -ENOENT; 9386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 9396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSessions.removeItemsAt(index); 9416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber interrupt(); 9436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return OK; 9456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 9466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber// static 9486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::MakeSocketNonBlocking(int s) { 9496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int flags = fcntl(s, F_GETFL, 0); 9506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (flags < 0) { 9516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber flags = 0; 9526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 9536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int res = fcntl(s, F_SETFL, flags | O_NONBLOCK); 9556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 9566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return -errno; 9576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 9586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return OK; 9606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 9616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::createClientOrServer( 9636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mode mode, 964ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber const struct in_addr *localAddr, 9656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber unsigned port, 9666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const char *remoteHost, 9676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber unsigned remotePort, 9686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<AMessage> ¬ify, 9696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t *sessionID) { 9706f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mutex::Autolock autoLock(mLock); 9716f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9726f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber *sessionID = 0; 9736f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = OK; 9746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int s, res; 9756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<Session> session; 9766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s = socket( 9786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber AF_INET, 9796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (mode == kModeCreateUDPSession) ? SOCK_DGRAM : SOCK_STREAM, 9806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 0); 9816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (s < 0) { 9836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 9846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail; 9856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 9866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9877d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mode == kModeCreateRTSPServer 9887d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber || mode == kModeCreateTCPDatagramSessionPassive) { 9896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const int yes = 1; 9906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); 9916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 9936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 9946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 9956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 9966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 9976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 9986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (mode == kModeCreateUDPSession) { 9996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int size = 256 * 1024; 10006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); 10026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 10046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 10056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 10066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); 10096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 10116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 10126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 10136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 101443433111d4adff6a138447dfadf531046497a008Andreas Huber } else if (mode == kModeCreateTCPDatagramSessionActive) { 101543433111d4adff6a138447dfadf531046497a008Andreas Huber int flag = 1; 101643433111d4adff6a138447dfadf531046497a008Andreas Huber res = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); 101743433111d4adff6a138447dfadf531046497a008Andreas Huber 101843433111d4adff6a138447dfadf531046497a008Andreas Huber if (res < 0) { 101943433111d4adff6a138447dfadf531046497a008Andreas Huber err = -errno; 102043433111d4adff6a138447dfadf531046497a008Andreas Huber goto bail2; 102143433111d4adff6a138447dfadf531046497a008Andreas Huber } 10226e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber 10236e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber int tos = 224; // VOICE 10246e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber res = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); 10256e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber 10266e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber if (res < 0) { 10276e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber err = -errno; 10286e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber goto bail2; 10296e8aec8d185444e52ff0247b266f614c690ded13Andreas Huber } 10306f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = MakeSocketNonBlocking(s); 10336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 10356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 10366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in addr; 10396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 10406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr.sin_family = AF_INET; 10416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10427d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mode == kModeCreateRTSPClient 10437d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber || mode == kModeCreateTCPDatagramSessionActive) { 10446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct hostent *ent= gethostbyname(remoteHost); 10456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (ent == NULL) { 10466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -h_errno; 10476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 10486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 10516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr.sin_port = htons(remotePort); 1052ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber } else if (localAddr != NULL) { 1053ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber addr.sin_addr = *localAddr; 1054ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber addr.sin_port = htons(port); 10556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 1056ab1bd84889273bc21efdabe5ff6f4633eb918a85Andreas Huber addr.sin_addr.s_addr = htonl(INADDR_ANY); 10576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr.sin_port = htons(port); 10586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10607d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mode == kModeCreateRTSPClient 10617d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber || mode == kModeCreateTCPDatagramSessionActive) { 10627d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber in_addr_t x = ntohl(addr.sin_addr.s_addr); 10637d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber ALOGI("connecting socket %d to %d.%d.%d.%d:%d", 10647d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber s, 10657d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber (x >> 24), 10667d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber (x >> 16) & 0xff, 10677d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber (x >> 8) & 0xff, 10687d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber x & 0xff, 10697d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber ntohs(addr.sin_port)); 10707d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 10716f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = connect(s, (const struct sockaddr *)&addr, sizeof(addr)); 10726f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10736f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_LT(res, 0); 10746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (errno == EINPROGRESS) { 10756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = 0; 10766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 10786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = bind(s, (const struct sockaddr *)&addr, sizeof(addr)); 10796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res == 0) { 10817d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mode == kModeCreateRTSPServer 10827d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber || mode == kModeCreateTCPDatagramSessionPassive) { 10836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = listen(s, 4); 10846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 10856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_EQ(mode, kModeCreateUDPSession); 10866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (remoteHost != NULL) { 10886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in remoteAddr; 10896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero)); 10906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteAddr.sin_family = AF_INET; 10916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteAddr.sin_port = htons(remotePort); 10926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct hostent *ent= gethostbyname(remoteHost); 10946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (ent == NULL) { 10956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -h_errno; 10966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 10976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 10986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 10996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 11006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber res = connect( 11026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s, 11036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (const struct sockaddr *)&remoteAddr, 11046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sizeof(remoteAddr)); 11056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 11116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 11126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail2; 11136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Session::State state; 11166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber switch (mode) { 11176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber case kModeCreateRTSPClient: 11186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber state = Session::CONNECTING; 11196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber break; 11206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11217d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber case kModeCreateTCPDatagramSessionActive: 11227d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber state = Session::CONNECTING; 11237d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber break; 11247d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 11257d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber case kModeCreateTCPDatagramSessionPassive: 11267d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber state = Session::LISTENING_TCP_DGRAMS; 11277d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber break; 11287d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 11296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber case kModeCreateRTSPServer: 11307d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber state = Session::LISTENING_RTSP; 11316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber break; 11326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber default: 11346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber CHECK_EQ(mode, kModeCreateUDPSession); 11356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber state = Session::DATAGRAM; 11366f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber break; 11376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber session = new Session( 11406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mNextSessionID++, 11416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber state, 11426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s, 11436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber notify); 11446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11457d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (mode == kModeCreateTCPDatagramSessionActive) { 11468060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber session->setMode(Session::MODE_DATAGRAM); 11477d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } else if (mode == kModeCreateRTSPClient) { 11488060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber session->setMode(Session::MODE_RTSP); 11497d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber } 11507d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 11516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSessions.add(session->sessionID(), session); 11526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber interrupt(); 11546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber *sessionID = session->sessionID(); 11566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber goto bail; 11586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberbail2: 11606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(s); 11616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s = -1; 11626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberbail: 11646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 11656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 11666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::connectUDPSession( 11686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int32_t sessionID, const char *remoteHost, unsigned remotePort) { 11696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mutex::Autolock autoLock(mLock); 11706f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11716f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 11726f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11736f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (index < 0) { 11746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return -ENOENT; 11756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 11766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<Session> session = mSessions.valueAt(index); 11786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int s = session->socket(); 11796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in remoteAddr; 11816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero)); 11826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteAddr.sin_family = AF_INET; 11836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteAddr.sin_port = htons(remotePort); 11846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = OK; 11867d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber struct hostent *ent = gethostbyname(remoteHost); 11876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (ent == NULL) { 11886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -h_errno; 11896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 11906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 11916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int res = connect( 11936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s, 11946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (const struct sockaddr *)&remoteAddr, 11956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sizeof(remoteAddr)); 11966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 11976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 11986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err = -errno; 11996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 12036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 12046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huberstatus_t ANetworkSession::sendRequest( 1206632177b7446185a0407b7df96f684a9b8b980765Andreas Huber int32_t sessionID, const void *data, ssize_t size, 1207632177b7446185a0407b7df96f684a9b8b980765Andreas Huber bool timeValid, int64_t timeUs) { 12086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mutex::Autolock autoLock(mLock); 12096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 12116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (index < 0) { 12136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return -ENOENT; 12146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<Session> session = mSessions.valueAt(index); 12176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1218632177b7446185a0407b7df96f684a9b8b980765Andreas Huber status_t err = session->sendRequest(data, size, timeValid, timeUs); 12196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber interrupt(); 12216f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12226f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return err; 12236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 12246f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12258060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huberstatus_t ANetworkSession::switchToWebSocketMode(int32_t sessionID) { 12268060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber Mutex::Autolock autoLock(mLock); 12278060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 12288060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 12298060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 12308060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (index < 0) { 12318060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return -ENOENT; 12328060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 12338060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 12348060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber const sp<Session> session = mSessions.valueAt(index); 12358060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber return session->switchToWebSocketMode(); 12368060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber} 12378060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber 12386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Hubervoid ANetworkSession::interrupt() { 12396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber static const char dummy = 0; 12406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t n; 12426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 12436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber n = write(mPipeFd[1], &dummy, 1); 12446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } while (n < 0 && errno == EINTR); 12456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (n < 0) { 12476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGW("Error writing to pipe (%s)", strerror(errno)); 12486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 12506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Hubervoid ANetworkSession::threadLoop() { 12526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber fd_set rs, ws; 12536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber FD_ZERO(&rs); 12546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber FD_ZERO(&ws); 12556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber FD_SET(mPipeFd[0], &rs); 12576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int maxFd = mPipeFd[0]; 12586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber { 12606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mutex::Autolock autoLock(mLock); 12616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber for (size_t i = 0; i < mSessions.size(); ++i) { 12636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<Session> &session = mSessions.valueAt(i); 12646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int s = session->socket(); 12666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (s < 0) { 12686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber continue; 12696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12706f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12716f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (session->wantsToRead()) { 12726f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber FD_SET(s, &rs); 12736f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (s > maxFd) { 12746f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber maxFd = s; 12756f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12766f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (session->wantsToWrite()) { 12796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber FD_SET(s, &ws); 12806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (s > maxFd) { 12816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber maxFd = s; 12826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12866f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int res = select(maxFd + 1, &rs, &ws, NULL, NULL /* tv */); 12886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res == 0) { 12906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return; 12916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (res < 0) { 12946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (errno == EINTR) { 12956f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return; 12966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 12976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 12986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGE("select failed w/ error %d (%s)", errno, strerror(errno)); 12996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber return; 13006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (FD_ISSET(mPipeFd[0], &rs)) { 13036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber char c; 13046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ssize_t n; 13056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber do { 13066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber n = read(mPipeFd[0], &c, 1); 13076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } while (n < 0 && errno == EINTR); 13086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (n < 0) { 13106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGW("Error reading from pipe (%s)", strerror(errno)); 13116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13136f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber --res; 13146f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13156f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13166f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber { 13176f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Mutex::Autolock autoLock(mLock); 13186f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13196f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber List<sp<Session> > sessionsToAdd; 13206f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 1321cfe302317c873001b0b35352d9f4f52c39f6f4b7Vishwath Mohan for (size_t i = mSessions.size(); res > 0 && i > 0;) { 1322cfe302317c873001b0b35352d9f4f52c39f6f4b7Vishwath Mohan i--; 13236f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber const sp<Session> &session = mSessions.valueAt(i); 13246f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13256f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int s = session->socket(); 13266f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13276f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (s < 0) { 13286f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber continue; 13296f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13306f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13316f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) { 13326f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber --res; 13336f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13346f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13356f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (FD_ISSET(s, &rs)) { 13367d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber if (session->isRTSPServer() || session->isTCPDatagramServer()) { 13376f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber struct sockaddr_in remoteAddr; 13386f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 13396f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13406f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber int clientSocket = accept( 13416f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 13426f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13436f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (clientSocket >= 0) { 13446f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = MakeSocketNonBlocking(clientSocket); 13456f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13466f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 13476f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGE("Unable to make client socket non blocking, " 13486f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber "failed w/ error %d (%s)", 13496f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber err, strerror(-err)); 13506f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13516f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber close(clientSocket); 13526f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber clientSocket = -1; 13536f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 13546f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber in_addr_t addr = ntohl(remoteAddr.sin_addr.s_addr); 13556f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13566f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGI("incoming connection from %d.%d.%d.%d:%d " 13576f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber "(socket %d)", 13586f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 24), 13596f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 16) & 0xff, 13606f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber (addr >> 8) & 0xff, 13616f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber addr & 0xff, 13626f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ntohs(remoteAddr.sin_port), 13636f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber clientSocket); 13646f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13656f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<Session> clientSession = 13666f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber new Session( 13676f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mNextSessionID++, 13686f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber Session::CONNECTED, 13696f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber clientSocket, 13706f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber session->getNotificationMessage()); 13716f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13728060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber clientSession->setMode( 13738060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber session->isRTSPServer() 13748060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber ? Session::MODE_RTSP 13758060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber : Session::MODE_DATAGRAM); 13767d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber 13776f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sessionsToAdd.push_back(clientSession); 13786f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13796f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 13806f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGE("accept returned error %d (%s)", 13816f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber errno, strerror(errno)); 13826f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13836f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } else { 13846f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = session->readMore(); 13856f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 1386a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber ALOGE("readMore on socket %d failed w/ error %d (%s)", 13876f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s, err, strerror(-err)); 13886f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13896f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13906f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13916f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 13926f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (FD_ISSET(s, &ws)) { 13936f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber status_t err = session->writeMore(); 13946f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber if (err != OK) { 1395a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber ALOGE("writeMore on socket %d failed w/ error %d (%s)", 13966f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber s, err, strerror(-err)); 13976f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13986f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 13996f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 14006f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 14016f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber while (!sessionsToAdd.empty()) { 14026f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sp<Session> session = *sessionsToAdd.begin(); 14036f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber sessionsToAdd.erase(sessionsToAdd.begin()); 14046f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 14056f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber mSessions.add(session->sessionID(), session); 14066f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 14076f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber ALOGI("added clientSession %d", session->sessionID()); 14086f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 14096f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber } 14106f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} 14116f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber 14126f9aebc2da485775c7e8df2d5ac0a4e07c9978bfAndreas Huber} // namespace android 1413