1bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber/* 2bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Copyright 2012, The Android Open Source Project 3bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 4bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * you may not use this file except in compliance with the License. 6bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * You may obtain a copy of the License at 7bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 8bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * 10bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Unless required by applicable law or agreed to in writing, software 11bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * See the License for the specific language governing permissions and 14bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * limitations under the License. 15bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber */ 16bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 17bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//#define LOG_NDEBUG 0 18bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#define LOG_TAG "NetworkSession" 19bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <utils/Log.h> 20bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 21bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include "ANetworkSession.h" 22bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include "ParsedMessage.h" 23bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 24bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <arpa/inet.h> 25bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <fcntl.h> 26bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <net/if.h> 27bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <netdb.h> 28bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <netinet/in.h> 29bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <sys/socket.h> 30bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 31bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 32bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ADebug.h> 33bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/AMessage.h> 34bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/hexdump.h> 35bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/Utils.h> 36bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 37bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubernamespace android { 38bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 39bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatic const size_t kMaxUDPSize = 1500; 40bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 41bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstruct ANetworkSession::NetworkThread : public Thread { 42bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber NetworkThread(ANetworkSession *session); 43bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 44bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberprotected: 45bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber virtual ~NetworkThread(); 46bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 47bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberprivate: 48bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ANetworkSession *mSession; 49bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 50bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber virtual bool threadLoop(); 51bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 52bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(NetworkThread); 53bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}; 54bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 55bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstruct ANetworkSession::Session : public RefBase { 56bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber enum State { 57bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CONNECTING, 58bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CONNECTED, 59bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber LISTENING_RTSP, 60bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber LISTENING_TCP_DGRAMS, 61bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber DATAGRAM, 62bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber }; 63bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 64bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Session(int32_t sessionID, 65bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber State state, 66bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s, 67bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<AMessage> ¬ify); 68bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 69bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t sessionID() const; 70bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int socket() const; 71bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> getNotificationMessage() const; 72bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 73bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber bool isRTSPServer() const; 74bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber bool isTCPDatagramServer() const; 75bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 76bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool wantsToRead(); 77bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool wantsToWrite(); 78bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 79bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t readMore(); 80bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t writeMore(); 81bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 82bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t sendRequest(const void *data, ssize_t size); 83bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 84bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber void setIsRTSPConnection(bool yesno); 85bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 86bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberprotected: 87bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber virtual ~Session(); 88bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 89bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberprivate: 90bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t mSessionID; 91bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber State mState; 92bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber bool mIsRTSPConnection; 93bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int mSocket; 94bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> mNotify; 95bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool mSawReceiveFailure, mSawSendFailure; 96bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 9790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // for TCP / stream data 98bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString mOutBuffer; 9990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 10090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // for UDP / datagrams 10190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber List<sp<ABuffer> > mOutDatagrams; 102bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 103bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString mInBuffer; 104bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 105bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber void notifyError(bool send, status_t err, const char *detail); 106bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber void notify(NotificationReason reason); 107bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 108bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(Session); 109bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}; 110bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//////////////////////////////////////////////////////////////////////////////// 111bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 112bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::NetworkThread::NetworkThread(ANetworkSession *session) 113bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber : mSession(session) { 114bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 115bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 116bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::NetworkThread::~NetworkThread() { 117bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 118bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 119bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ANetworkSession::NetworkThread::threadLoop() { 120bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSession->threadLoop(); 121bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 122bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return true; 123bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 124bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 125bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//////////////////////////////////////////////////////////////////////////////// 126bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 127bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::Session::Session( 128bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t sessionID, 129bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber State state, 130bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s, 131bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<AMessage> ¬ify) 132bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber : mSessionID(sessionID), 133bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mState(state), 134bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mIsRTSPConnection(false), 135bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSocket(s), 136bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNotify(notify), 137bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawReceiveFailure(false), 138bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure(false) { 139bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mState == CONNECTED) { 140bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in localAddr; 141bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t localAddrLen = sizeof(localAddr); 142bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 143bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = getsockname( 144bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSocket, (struct sockaddr *)&localAddr, &localAddrLen); 145bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_GE(res, 0); 146bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 147bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 148bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 149bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 150bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = getpeername( 151bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSocket, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 152bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_GE(res, 0); 153bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 154bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber in_addr_t addr = ntohl(localAddr.sin_addr.s_addr); 155bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString localAddrString = StringPrintf( 156bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "%d.%d.%d.%d", 157bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 24), 158bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 16) & 0xff, 159bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 8) & 0xff, 160bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr & 0xff); 161bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 162bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr = ntohl(remoteAddr.sin_addr.s_addr); 163bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AString remoteAddrString = StringPrintf( 164bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "%d.%d.%d.%d", 165bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 24), 166bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 16) & 0xff, 167bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 8) & 0xff, 168bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr & 0xff); 169bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 170bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> msg = mNotify->dup(); 171bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("sessionID", mSessionID); 172bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("reason", kWhatClientConnected); 173bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setString("server-ip", localAddrString.c_str()); 174bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("server-port", ntohs(localAddr.sin_port)); 175bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setString("client-ip", remoteAddrString.c_str()); 176bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("client-port", ntohs(remoteAddr.sin_port)); 177bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->post(); 178bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 179bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 180bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 181bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::Session::~Session() { 18296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("Session %d gone", mSessionID); 183bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 184bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mSocket); 185bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSocket = -1; 186bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 187bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 188bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberint32_t ANetworkSession::Session::sessionID() const { 189bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mSessionID; 190bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 191bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 192bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberint ANetworkSession::Session::socket() const { 193bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mSocket; 194bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 195bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 196bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Hubervoid ANetworkSession::Session::setIsRTSPConnection(bool yesno) { 197bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mIsRTSPConnection = yesno; 198bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 199bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 200bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubersp<AMessage> ANetworkSession::Session::getNotificationMessage() const { 201bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return mNotify; 202bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 203bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 204bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberbool ANetworkSession::Session::isRTSPServer() const { 205bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mState == LISTENING_RTSP; 206bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 207bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 208bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberbool ANetworkSession::Session::isTCPDatagramServer() const { 209bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mState == LISTENING_TCP_DGRAMS; 210bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 211bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 212bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ANetworkSession::Session::wantsToRead() { 213bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return !mSawReceiveFailure && mState != CONNECTING; 214bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 215bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 216bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbool ANetworkSession::Session::wantsToWrite() { 217bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return !mSawSendFailure 218bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber && (mState == CONNECTING 21990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber || (mState == CONNECTED && !mOutBuffer.empty()) 22090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber || (mState == DATAGRAM && !mOutDatagrams.empty())); 221bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 222bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 223bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::Session::readMore() { 224bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mState == DATAGRAM) { 225bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err; 226bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 227bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<ABuffer> buf = new ABuffer(kMaxUDPSize); 228bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 229bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 230bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 231bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 232bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 233bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 234bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = recvfrom( 235bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSocket, buf->data(), buf->capacity(), 0, 236bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (struct sockaddr *)&remoteAddr, &remoteAddrLen); 237bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 238bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 239bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = OK; 240bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n < 0) { 241bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 242bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n == 0) { 243bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -ECONNRESET; 244bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 245bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber buf->setRange(0, n); 246bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 247bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 248bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber buf->meta()->setInt64("arrivalTimeUs", nowUs); 249bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 250bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> notify = mNotify->dup(); 251bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->setInt32("sessionID", mSessionID); 252bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->setInt32("reason", kWhatDatagram); 253bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 254bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber uint32_t ip = ntohl(remoteAddr.sin_addr.s_addr); 255bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->setString( 256bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "fromAddr", 257bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber StringPrintf( 258bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "%u.%u.%u.%u", 259bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ip >> 24, 260bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (ip >> 16) & 0xff, 261bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (ip >> 8) & 0xff, 262bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ip & 0xff).c_str()); 263bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 264bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->setInt32("fromPort", ntohs(remoteAddr.sin_port)); 265bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 266bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->setBuffer("data", buf); 267bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->post(); 268bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 269bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (err == OK); 270bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 271bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err == -EAGAIN) { 272bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = OK; 273bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 274bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 275bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 276bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(false /* send */, err, "Recvfrom failed."); 277bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawReceiveFailure = true; 278bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 279bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 280bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 281bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 282bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 283bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber char tmp[512]; 284bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 285bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 286bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = recv(mSocket, tmp, sizeof(tmp), 0); 287bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 288bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 289bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 290bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 291bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n > 0) { 292bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mInBuffer.append(tmp, n); 293bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 294bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#if 0 295bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("in:"); 296bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber hexdump(tmp, n); 297bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#endif 298bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n < 0) { 299bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 300bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 301bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -ECONNRESET; 302bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 303bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 304bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (!mIsRTSPConnection) { 305bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // TCP stream carrying 16-bit length-prefixed datagrams. 306bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 307bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber while (mInBuffer.size() >= 2) { 308bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber size_t packetSize = U16_AT((const uint8_t *)mInBuffer.c_str()); 309bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 310bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mInBuffer.size() < packetSize + 2) { 311bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 312bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 313bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 314bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<ABuffer> packet = new ABuffer(packetSize); 315bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber memcpy(packet->data(), mInBuffer.c_str() + 2, packetSize); 316bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 317bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> notify = mNotify->dup(); 318bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify->setInt32("sessionID", mSessionID); 319bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("reason", kWhatDatagram); 320bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setBuffer("data", packet); 321bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 322bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 323bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInBuffer.erase(0, packetSize + 2); 324bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 325bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 326bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber for (;;) { 327bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber size_t length; 328bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 329bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mInBuffer.size() > 0 && mInBuffer.c_str()[0] == '$') { 330bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mInBuffer.size() < 4) { 331bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 332bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 333bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 334bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber length = U16_AT((const uint8_t *)mInBuffer.c_str() + 2); 335bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 336bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mInBuffer.size() < 4 + length) { 337bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 338bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 339bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 340bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> notify = mNotify->dup(); 341bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("sessionID", mSessionID); 342bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("reason", kWhatBinaryData); 343bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("channel", mInBuffer.c_str()[1]); 344bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 345bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<ABuffer> data = new ABuffer(length); 346bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber memcpy(data->data(), mInBuffer.c_str() + 4, length); 347bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 348bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 349bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber data->meta()->setInt64("arrivalTimeUs", nowUs); 350bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 351bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setBuffer("data", data); 352bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 353bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInBuffer.erase(0, 4 + length); 355bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber continue; 356bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 357bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 358bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<ParsedMessage> msg = 359bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ParsedMessage::Parse( 360bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInBuffer.c_str(), mInBuffer.size(), err != OK, &length); 361bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 362bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (msg == NULL) { 363bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 364bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 365bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 366bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> notify = mNotify->dup(); 367bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("sessionID", mSessionID); 368bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("reason", kWhatData); 369bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setObject("data", msg); 370bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 371bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 372bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#if 1 373bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // XXX The (old) dongle sends the wrong content length header on a 374bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // SET_PARAMETER request that signals a "wfd_idr_request". 375bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // (17 instead of 19). 376bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const char *content = msg->getContent(); 377bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (content 378bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && !memcmp(content, "wfd_idr_request\r\n", 17) 379bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && length >= 19 380bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && mInBuffer.c_str()[length] == '\r' 381bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && mInBuffer.c_str()[length + 1] == '\n') { 382bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber length += 2; 383bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 384bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#endif 385bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 386bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInBuffer.erase(0, length); 387bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 388bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (err != OK) { 389bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 390bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 391bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 392bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 393bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 394bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 395bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(false /* send */, err, "Recv failed."); 396bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawReceiveFailure = true; 397bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 398bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 399bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 400bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 401bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 402bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::Session::writeMore() { 403bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mState == DATAGRAM) { 40490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(!mOutDatagrams.empty()); 405bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 406bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err; 407bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 40890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const sp<ABuffer> &datagram = *mOutDatagrams.begin(); 409bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 410bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int n; 411bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 41290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber n = send(mSocket, datagram->data(), datagram->size(), 0); 413bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 414bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 415bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = OK; 416bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 417bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n > 0) { 41890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mOutDatagrams.erase(mOutDatagrams.begin()); 419bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n < 0) { 420bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 421bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n == 0) { 422bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -ECONNRESET; 423bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 42490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } while (err == OK && !mOutDatagrams.empty()); 425bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 426bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err == -EAGAIN) { 427bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = OK; 428bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 429bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 430bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 431bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(true /* send */, err, "Send datagram failed."); 432bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure = true; 433bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 434bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 435bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 436bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 437bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 438bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mState == CONNECTING) { 439bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int err; 440bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t optionLen = sizeof(err); 441bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0); 442bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(optionLen, (socklen_t)sizeof(err)); 443bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 444bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != 0) { 445bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(kWhatError, -err, "Connection failed"); 446bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure = true; 447bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 448bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return -err; 449bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 450bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 451bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mState = CONNECTED; 452bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify(kWhatConnected); 453bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 454bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 455bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 456bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 457bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(mState, CONNECTED); 458bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(!mOutBuffer.empty()); 459bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 460bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 461bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 462bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = send(mSocket, mOutBuffer.c_str(), mOutBuffer.size(), 0); 463bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 464bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 465bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 466bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 467bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n > 0) { 46872f6aea5afba3ff8ab7e8eab49552d65ee3bb97bAndreas Huber#if 0 469bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("out:"); 470bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber hexdump(mOutBuffer.c_str(), n); 47172f6aea5afba3ff8ab7e8eab49552d65ee3bb97bAndreas Huber#endif 472bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 473bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mOutBuffer.erase(0, n); 474bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n < 0) { 475bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 476bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n == 0) { 477bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -ECONNRESET; 478bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 479bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 480bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 481bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(true /* send */, err, "Send failed."); 482bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure = true; 483bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 484bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 485bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 486bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 487bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 488bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::Session::sendRequest(const void *data, ssize_t size) { 489bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mState == CONNECTED || mState == DATAGRAM); 490bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 49190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (mState == DATAGRAM) { 49290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_GE(size, 0); 49390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 49490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> datagram = new ABuffer(size); 49590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber memcpy(datagram->data(), data, size); 49690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 49790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mOutDatagrams.push_back(datagram); 49890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return OK; 49990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 50090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 501bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mState == CONNECTED && !mIsRTSPConnection) { 502bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK_LE(size, 65535); 503bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 504bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber uint8_t prefix[2]; 505bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber prefix[0] = size >> 8; 506bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber prefix[1] = size & 0xff; 507bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 508bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mOutBuffer.append((const char *)prefix, sizeof(prefix)); 509bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 510bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 511bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mOutBuffer.append( 512bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const char *)data, 513bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (size >= 0) ? size : strlen((const char *)data)); 514bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 515bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 516bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 517bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 518bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::Session::notifyError( 519bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool send, status_t err, const char *detail) { 520bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> msg = mNotify->dup(); 521bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("sessionID", mSessionID); 522bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("reason", kWhatError); 523bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("send", send); 524bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("err", err); 525bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setString("detail", detail); 526bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->post(); 527bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 528bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 529bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::Session::notify(NotificationReason reason) { 530bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> msg = mNotify->dup(); 531bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("sessionID", mSessionID); 532bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("reason", reason); 533bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->post(); 534bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 535bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 536bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//////////////////////////////////////////////////////////////////////////////// 537bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 538bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::ANetworkSession() 539bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber : mNextSessionID(1) { 540bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 541bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 542bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 543bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::~ANetworkSession() { 544bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber stop(); 545bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 546bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 547bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::start() { 548bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mThread != NULL) { 549bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return INVALID_OPERATION; 550bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 551bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 552bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = pipe(mPipeFd); 553bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res != 0) { 554bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 555bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -errno; 556bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 557bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 558bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread = new NetworkThread(this); 559bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 560bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = mThread->run("ANetworkSession", ANDROID_PRIORITY_AUDIO); 561bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 562bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 563bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread.clear(); 564bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 565bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mPipeFd[0]); 566bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mPipeFd[1]); 567bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 568bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 569bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 570bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 571bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 572bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 573bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 574bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 575bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::stop() { 576bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mThread == NULL) { 577bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return INVALID_OPERATION; 578bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 579bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 580bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread->requestExit(); 581bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 582bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread->requestExitAndWait(); 583bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 584bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread.clear(); 585bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 586bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mPipeFd[0]); 587bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mPipeFd[1]); 588bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 589bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 590bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 591bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 592bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 593bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createRTSPClient( 594bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *host, unsigned port, const sp<AMessage> ¬ify, 595bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t *sessionID) { 596bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createClientOrServer( 597bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kModeCreateRTSPClient, 598bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber NULL /* addr */, 599bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0 /* port */, 600bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber host, 601bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber port, 602bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify, 603bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionID); 604bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 605bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 606bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createRTSPServer( 607bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber const struct in_addr &addr, unsigned port, 608bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber const sp<AMessage> ¬ify, int32_t *sessionID) { 609bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createClientOrServer( 610bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kModeCreateRTSPServer, 611bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber &addr, 612bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber port, 613bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber NULL /* remoteHost */, 614bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0 /* remotePort */, 615bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify, 616bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionID); 617bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 618bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 619bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createUDPSession( 620bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned localPort, const sp<AMessage> ¬ify, int32_t *sessionID) { 621bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createUDPSession(localPort, NULL, 0, notify, sessionID); 622bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 623bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 624bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createUDPSession( 625bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned localPort, 626bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *remoteHost, 627bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned remotePort, 628bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<AMessage> ¬ify, 629bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t *sessionID) { 630bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createClientOrServer( 631bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kModeCreateUDPSession, 632bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber NULL /* addr */, 633bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber localPort, 634bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteHost, 635bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remotePort, 636bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify, 637bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionID); 638bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 639bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 640bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t ANetworkSession::createTCPDatagramSession( 641bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const struct in_addr &addr, unsigned port, 642bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const sp<AMessage> ¬ify, int32_t *sessionID) { 643bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return createClientOrServer( 644bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber kModeCreateTCPDatagramSessionPassive, 645bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber &addr, 646bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber port, 647bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber NULL /* remoteHost */, 648bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 0 /* remotePort */, 649bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify, 650bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sessionID); 651bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 652bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 653bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t ANetworkSession::createTCPDatagramSession( 654bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber unsigned localPort, 655bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const char *remoteHost, 656bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber unsigned remotePort, 657bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const sp<AMessage> ¬ify, 658bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t *sessionID) { 659bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return createClientOrServer( 660bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber kModeCreateTCPDatagramSessionActive, 661bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber NULL /* addr */, 662bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber localPort, 663bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber remoteHost, 664bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber remotePort, 665bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify, 666bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sessionID); 667bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 668bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 669bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::destroySession(int32_t sessionID) { 670bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 671bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 672bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 673bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 674bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 675bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -ENOENT; 676bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 677bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 678bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSessions.removeItemsAt(index); 679bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 680bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 681bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 682bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 683bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 684bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 685bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 686bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::MakeSocketNonBlocking(int s) { 687bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int flags = fcntl(s, F_GETFL, 0); 688bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (flags < 0) { 689bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber flags = 0; 690bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 691bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 692bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = fcntl(s, F_SETFL, flags | O_NONBLOCK); 693bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 694bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -errno; 695bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 696bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 697bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 698bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 699bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 700bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createClientOrServer( 701bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mode mode, 702bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber const struct in_addr *localAddr, 703bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned port, 704bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *remoteHost, 705bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned remotePort, 706bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<AMessage> ¬ify, 707bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t *sessionID) { 708bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 709bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 710bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *sessionID = 0; 711bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 712bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s, res; 713bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<Session> session; 714bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 715bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s = socket( 716bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AF_INET, 717bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (mode == kModeCreateUDPSession) ? SOCK_DGRAM : SOCK_STREAM, 718bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0); 719bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 720bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s < 0) { 721bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 722bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail; 723bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 724bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 725bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPServer 726bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionPassive) { 727bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const int yes = 1; 728bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); 729bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 730bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 731bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 732bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 733bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 734bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 735bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 736bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mode == kModeCreateUDPSession) { 737bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int size = 256 * 1024; 738bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 739bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); 740bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 741bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 742bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 743bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 744bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 745bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 746bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); 747bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 748bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 749bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 750bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 751bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 752bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 753bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 754bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = MakeSocketNonBlocking(s); 755bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 756bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 757bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 758bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 759bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 760bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in addr; 761bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 762bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_family = AF_INET; 763bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 764bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPClient 765bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionActive) { 766bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct hostent *ent= gethostbyname(remoteHost); 767bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (ent == NULL) { 768bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -h_errno; 769bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 770bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 771bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 772bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 773bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_port = htons(remotePort); 774bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber } else if (localAddr != NULL) { 775bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber addr.sin_addr = *localAddr; 776bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber addr.sin_port = htons(port); 777bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 778bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber addr.sin_addr.s_addr = htonl(INADDR_ANY); 779bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_port = htons(port); 780bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 781bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 782bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPClient 783bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionActive) { 784bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber in_addr_t x = ntohl(addr.sin_addr.s_addr); 785bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("connecting socket %d to %d.%d.%d.%d:%d", 786bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber s, 787bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (x >> 24), 788bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (x >> 16) & 0xff, 789bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (x >> 8) & 0xff, 790bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber x & 0xff, 791bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ntohs(addr.sin_port)); 792bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 793bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = connect(s, (const struct sockaddr *)&addr, sizeof(addr)); 794bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 795bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_LT(res, 0); 796bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (errno == EINPROGRESS) { 797bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = 0; 798bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 799bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 800bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = bind(s, (const struct sockaddr *)&addr, sizeof(addr)); 801bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 802bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res == 0) { 803bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPServer 804bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionPassive) { 805bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = listen(s, 4); 806bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 807bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(mode, kModeCreateUDPSession); 808bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 809bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (remoteHost != NULL) { 810bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 811bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero)); 812bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_family = AF_INET; 813bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_port = htons(remotePort); 814bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 815bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct hostent *ent= gethostbyname(remoteHost); 816bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (ent == NULL) { 817bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -h_errno; 818bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 819bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 820bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 821bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 822bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 823bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = connect( 824bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, 825bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const struct sockaddr *)&remoteAddr, 826bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sizeof(remoteAddr)); 827bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 828bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 829bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 830bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 831bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 832bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 833bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 834bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 835bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 836bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 837bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Session::State state; 838bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber switch (mode) { 839bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber case kModeCreateRTSPClient: 840bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber state = Session::CONNECTING; 841bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 842bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 843bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kModeCreateTCPDatagramSessionActive: 844bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber state = Session::CONNECTING; 845bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 846bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 847bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kModeCreateTCPDatagramSessionPassive: 848bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber state = Session::LISTENING_TCP_DGRAMS; 849bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 850bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 851bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber case kModeCreateRTSPServer: 852bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber state = Session::LISTENING_RTSP; 853bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 854bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 855bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber default: 856bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(mode, kModeCreateUDPSession); 857bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber state = Session::DATAGRAM; 858bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 859bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 860bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 861bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber session = new Session( 862bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNextSessionID++, 863bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber state, 864bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, 865bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify); 866bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 867bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateTCPDatagramSessionActive) { 868bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber session->setIsRTSPConnection(false); 869bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else if (mode == kModeCreateRTSPClient) { 870bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber session->setIsRTSPConnection(true); 871bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 872bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 873bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSessions.add(session->sessionID(), session); 874bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 875bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 876bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 877bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *sessionID = session->sessionID(); 878bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 879bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail; 880bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 881bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbail2: 882bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(s); 883bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s = -1; 884bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 885bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbail: 886bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 887bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 888bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 889bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::connectUDPSession( 890bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t sessionID, const char *remoteHost, unsigned remotePort) { 891bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 892bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 893bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 894bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 895bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 896bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -ENOENT; 897bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 898bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 899bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> session = mSessions.valueAt(index); 900bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s = session->socket(); 901bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 902bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 903bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero)); 904bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_family = AF_INET; 905bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_port = htons(remotePort); 906bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 907bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 908bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber struct hostent *ent = gethostbyname(remoteHost); 909bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (ent == NULL) { 910bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -h_errno; 911bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 912bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 913bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 914bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = connect( 915bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, 916bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const struct sockaddr *)&remoteAddr, 917bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sizeof(remoteAddr)); 918bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 919bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 920bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 921bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 922bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 923bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 924bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 925bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 926bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 927bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::sendRequest( 928bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t sessionID, const void *data, ssize_t size) { 929bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 930bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 931bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 932bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 933bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 934bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -ENOENT; 935bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 936bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 937bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> session = mSessions.valueAt(index); 938bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 939bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = session->sendRequest(data, size); 940bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 941bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 942bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 943bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 944bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 945bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 946bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::interrupt() { 947bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber static const char dummy = 0; 948bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 949bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 950bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 951bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = write(mPipeFd[1], &dummy, 1); 952bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 953bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 954bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n < 0) { 955bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGW("Error writing to pipe (%s)", strerror(errno)); 956bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 957bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 958bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 959bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::threadLoop() { 960bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber fd_set rs, ws; 961bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_ZERO(&rs); 962bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_ZERO(&ws); 963bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 964bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_SET(mPipeFd[0], &rs); 965bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int maxFd = mPipeFd[0]; 966bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 967bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber { 968bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 969bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 970bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = 0; i < mSessions.size(); ++i) { 971bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> &session = mSessions.valueAt(i); 972bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 973bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s = session->socket(); 974bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 975bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s < 0) { 976bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 977bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 978bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 979bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (session->wantsToRead()) { 980bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_SET(s, &rs); 981bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s > maxFd) { 982bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber maxFd = s; 983bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 984bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 985bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 986bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (session->wantsToWrite()) { 987bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_SET(s, &ws); 988bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s > maxFd) { 989bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber maxFd = s; 990bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 991bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 992bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 993bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 994bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 995bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = select(maxFd + 1, &rs, &ws, NULL, NULL /* tv */); 996bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 997bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res == 0) { 998bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 999bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1000bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1001bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 1002bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (errno == EINTR) { 1003bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 1004bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1005bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1006bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGE("select failed w/ error %d (%s)", errno, strerror(errno)); 1007bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 1008bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1009bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1010bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(mPipeFd[0], &rs)) { 1011bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber char c; 1012bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 1013bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 1014bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = read(mPipeFd[0], &c, 1); 1015bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 1016bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1017bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n < 0) { 1018bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGW("Error reading from pipe (%s)", strerror(errno)); 1019bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1020bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1021bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber --res; 1022bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1023bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1024bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber { 1025bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 1026bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1027bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber List<sp<Session> > sessionsToAdd; 1028bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1029bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = mSessions.size(); res > 0 && i-- > 0;) { 1030bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> &session = mSessions.valueAt(i); 1031bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1032bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s = session->socket(); 1033bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1034bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s < 0) { 1035bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 1036bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1037bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1038bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) { 1039bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber --res; 1040bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1041bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1042bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(s, &rs)) { 1043bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (session->isRTSPServer() || session->isTCPDatagramServer()) { 1044bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 1045bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 1046bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1047bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int clientSocket = accept( 1048bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 1049bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1050bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (clientSocket >= 0) { 1051bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = MakeSocketNonBlocking(clientSocket); 1052bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1053bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 1054bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGE("Unable to make client socket non blocking, " 1055bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "failed w/ error %d (%s)", 1056bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err, strerror(-err)); 1057bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1058bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(clientSocket); 1059bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber clientSocket = -1; 1060bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 1061bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber in_addr_t addr = ntohl(remoteAddr.sin_addr.s_addr); 1062bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1063bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("incoming connection from %d.%d.%d.%d:%d " 1064bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "(socket %d)", 1065bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 24), 1066bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 16) & 0xff, 1067bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 8) & 0xff, 1068bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr & 0xff, 1069bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ntohs(remoteAddr.sin_port), 1070bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber clientSocket); 1071bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1072bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<Session> clientSession = 1073bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // using socket sd as sessionID 1074bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber new Session( 1075bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNextSessionID++, 1076bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Session::CONNECTED, 1077bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber clientSocket, 1078bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber session->getNotificationMessage()); 1079bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1080bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber clientSession->setIsRTSPConnection( 1081bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber session->isRTSPServer()); 1082bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 1083bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionsToAdd.push_back(clientSession); 1084bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1085bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 1086bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGE("accept returned error %d (%s)", 1087bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber errno, strerror(errno)); 1088bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1089bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 1090bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = session->readMore(); 1091bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 109296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGE("readMore on socket %d failed w/ error %d (%s)", 1093bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, err, strerror(-err)); 1094bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1095bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1096bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1097bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1098bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(s, &ws)) { 1099bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = session->writeMore(); 1100bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 110196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGE("writeMore on socket %d failed w/ error %d (%s)", 1102bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, err, strerror(-err)); 1103bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1104bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1105bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1106bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1107bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber while (!sessionsToAdd.empty()) { 1108bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<Session> session = *sessionsToAdd.begin(); 1109bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionsToAdd.erase(sessionsToAdd.begin()); 1110bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1111bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSessions.add(session->sessionID(), session); 1112bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1113bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("added clientSession %d", session->sessionID()); 1114bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1115bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1116bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 1117bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1118bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} // namespace android 1119bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1120