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 4100224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber uint8_t *data = datagram->data(); 4110224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber if (data[0] == 0x80 && (data[1] & 0x7f) == 33) { 4120224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 4130224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 4140224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber uint32_t prevRtpTime = U32_AT(&data[4]); 4150224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 4160224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber // 90kHz time scale 4170224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber uint32_t rtpTime = (nowUs * 9ll) / 100ll; 4180224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber int32_t diffTime = (int32_t)rtpTime - (int32_t)prevRtpTime; 4190224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 4200224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber ALOGV("correcting rtpTime by %.0f ms", diffTime / 90.0); 4210224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 4220224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[4] = rtpTime >> 24; 4230224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 4240224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 4250224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[7] = rtpTime & 0xff; 4260224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } 4270224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 428bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int n; 429bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 43090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber n = send(mSocket, datagram->data(), datagram->size(), 0); 431bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 432bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 433bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = OK; 434bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 435bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n > 0) { 43690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mOutDatagrams.erase(mOutDatagrams.begin()); 437bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n < 0) { 438bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 439bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n == 0) { 440bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -ECONNRESET; 441bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 44290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } while (err == OK && !mOutDatagrams.empty()); 443bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 444bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err == -EAGAIN) { 4450224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber if (!mOutDatagrams.empty()) { 4460224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber ALOGI("%d datagrams remain queued.", mOutDatagrams.size()); 4470224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } 448bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = OK; 449bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 450bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 451bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 452bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(true /* send */, err, "Send datagram failed."); 453bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure = true; 454bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 455bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 456bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 457bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 458bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 459bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mState == CONNECTING) { 460bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int err; 461bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t optionLen = sizeof(err); 462bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0); 463bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(optionLen, (socklen_t)sizeof(err)); 464bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 465bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != 0) { 466bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(kWhatError, -err, "Connection failed"); 467bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure = true; 468bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 469bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return -err; 470bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 471bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 472bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mState = CONNECTED; 473bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify(kWhatConnected); 474bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 475bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 476bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 477bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 478bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(mState, CONNECTED); 479bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(!mOutBuffer.empty()); 480bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 481bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 482bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 483bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = send(mSocket, mOutBuffer.c_str(), mOutBuffer.size(), 0); 484bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 485bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 486bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 487bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 488bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n > 0) { 48972f6aea5afba3ff8ab7e8eab49552d65ee3bb97bAndreas Huber#if 0 490bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("out:"); 491bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber hexdump(mOutBuffer.c_str(), n); 49272f6aea5afba3ff8ab7e8eab49552d65ee3bb97bAndreas Huber#endif 493bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 494bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mOutBuffer.erase(0, n); 495bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n < 0) { 496bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 497bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else if (n == 0) { 498bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -ECONNRESET; 499bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 500bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 501bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 502bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notifyError(true /* send */, err, "Send failed."); 503bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSawSendFailure = true; 504bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 505bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 506bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 507bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 508bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 509bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::Session::sendRequest(const void *data, ssize_t size) { 510bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK(mState == CONNECTED || mState == DATAGRAM); 511bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 51290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (mState == DATAGRAM) { 51390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_GE(size, 0); 51490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 51590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> datagram = new ABuffer(size); 51690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber memcpy(datagram->data(), data, size); 51790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 51890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mOutDatagrams.push_back(datagram); 51990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return OK; 52090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 52190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 522bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mState == CONNECTED && !mIsRTSPConnection) { 523bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK_LE(size, 65535); 524bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 525bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber uint8_t prefix[2]; 526bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber prefix[0] = size >> 8; 527bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber prefix[1] = size & 0xff; 528bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 529bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mOutBuffer.append((const char *)prefix, sizeof(prefix)); 530bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 531bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 532bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mOutBuffer.append( 533bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const char *)data, 534bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (size >= 0) ? size : strlen((const char *)data)); 535bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 536bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 537bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 538bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 539bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::Session::notifyError( 540bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber bool send, status_t err, const char *detail) { 541bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> msg = mNotify->dup(); 542bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("sessionID", mSessionID); 543bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("reason", kWhatError); 544bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("send", send); 545bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("err", err); 546bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setString("detail", detail); 547bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->post(); 548bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 549bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 550bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::Session::notify(NotificationReason reason) { 551bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<AMessage> msg = mNotify->dup(); 552bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("sessionID", mSessionID); 553bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->setInt32("reason", reason); 554bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber msg->post(); 555bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 556bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 557bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//////////////////////////////////////////////////////////////////////////////// 558bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 559bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::ANetworkSession() 560bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber : mNextSessionID(1) { 561bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 562bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 563bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 564bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberANetworkSession::~ANetworkSession() { 565bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber stop(); 566bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 567bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 568bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::start() { 569bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mThread != NULL) { 570bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return INVALID_OPERATION; 571bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 572bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 573bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = pipe(mPipeFd); 574bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res != 0) { 575bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 576bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -errno; 577bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 578bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 579bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread = new NetworkThread(this); 580bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 581bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = mThread->run("ANetworkSession", ANDROID_PRIORITY_AUDIO); 582bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 583bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 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 err; 591bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 592bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 593bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 594bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 595bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 596bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::stop() { 597bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mThread == NULL) { 598bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return INVALID_OPERATION; 599bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 600bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 601bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread->requestExit(); 602bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 603bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread->requestExitAndWait(); 604bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 605bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mThread.clear(); 606bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 607bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mPipeFd[0]); 608bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(mPipeFd[1]); 609bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mPipeFd[0] = mPipeFd[1] = -1; 610bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 611bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 612bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 613bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 614bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createRTSPClient( 615bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *host, unsigned port, const sp<AMessage> ¬ify, 616bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t *sessionID) { 617bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createClientOrServer( 618bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kModeCreateRTSPClient, 619bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber NULL /* addr */, 620bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0 /* port */, 621bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber host, 622bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber port, 623bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify, 624bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionID); 625bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 626bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 627bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createRTSPServer( 628bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber const struct in_addr &addr, unsigned port, 629bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber const sp<AMessage> ¬ify, int32_t *sessionID) { 630bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createClientOrServer( 631bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kModeCreateRTSPServer, 632bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber &addr, 633bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber port, 634bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber NULL /* remoteHost */, 635bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0 /* remotePort */, 636bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify, 637bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionID); 638bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 639bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 640bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createUDPSession( 641bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned localPort, const sp<AMessage> ¬ify, int32_t *sessionID) { 642bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createUDPSession(localPort, NULL, 0, notify, sessionID); 643bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 644bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 645bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createUDPSession( 646bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned localPort, 647bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *remoteHost, 648bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned remotePort, 649bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<AMessage> ¬ify, 650bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t *sessionID) { 651bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return createClientOrServer( 652bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber kModeCreateUDPSession, 653bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber NULL /* addr */, 654bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber localPort, 655bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteHost, 656bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remotePort, 657bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify, 658bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionID); 659bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 660bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 661bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t ANetworkSession::createTCPDatagramSession( 662bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const struct in_addr &addr, unsigned port, 663bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const sp<AMessage> ¬ify, int32_t *sessionID) { 664bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return createClientOrServer( 665bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber kModeCreateTCPDatagramSessionPassive, 666bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber &addr, 667bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber port, 668bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber NULL /* remoteHost */, 669bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 0 /* remotePort */, 670bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify, 671bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sessionID); 672bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 673bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 674bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t ANetworkSession::createTCPDatagramSession( 675bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber unsigned localPort, 676bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const char *remoteHost, 677bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber unsigned remotePort, 678bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const sp<AMessage> ¬ify, 679bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t *sessionID) { 680bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return createClientOrServer( 681bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber kModeCreateTCPDatagramSessionActive, 682bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber NULL /* addr */, 683bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber localPort, 684bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber remoteHost, 685bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber remotePort, 686bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify, 687bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sessionID); 688bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 689bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 690bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::destroySession(int32_t sessionID) { 691bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 692bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 693bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 694bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 695bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 696bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -ENOENT; 697bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 698bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 699bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSessions.removeItemsAt(index); 700bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 701bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 702bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 703bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 704bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 705bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 706bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber// static 707bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::MakeSocketNonBlocking(int s) { 708bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int flags = fcntl(s, F_GETFL, 0); 709bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (flags < 0) { 710bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber flags = 0; 711bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 712bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 713bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = fcntl(s, F_SETFL, flags | O_NONBLOCK); 714bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 715bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -errno; 716bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 717bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 718bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return OK; 719bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 720bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 721bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::createClientOrServer( 722bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mode mode, 723bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber const struct in_addr *localAddr, 724bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned port, 725bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const char *remoteHost, 726bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber unsigned remotePort, 727bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<AMessage> ¬ify, 728bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t *sessionID) { 729bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 730bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 731bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *sessionID = 0; 732bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 733bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s, res; 734bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<Session> session; 735bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 736bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s = socket( 737bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber AF_INET, 738bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (mode == kModeCreateUDPSession) ? SOCK_DGRAM : SOCK_STREAM, 739bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 0); 740bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 741bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s < 0) { 742bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 743bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail; 744bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 745bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 746bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPServer 747bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionPassive) { 748bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const int yes = 1; 749bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); 750bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 751bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 752bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 753bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 754bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 755bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 756bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 757bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (mode == kModeCreateUDPSession) { 758bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int size = 256 * 1024; 759bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 760bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); 761bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 762bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 763bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 764bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 765bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 766bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 767bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); 768bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 769bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 770bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 771bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 772bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 773bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 774bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 775bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = MakeSocketNonBlocking(s); 776bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 777bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 778bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 779bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 780bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 781bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in addr; 782bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 783bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_family = AF_INET; 784bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 785bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPClient 786bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionActive) { 787bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct hostent *ent= gethostbyname(remoteHost); 788bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (ent == NULL) { 789bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -h_errno; 790bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 791bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 792bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 793bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 794bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_port = htons(remotePort); 795bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber } else if (localAddr != NULL) { 796bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber addr.sin_addr = *localAddr; 797bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber addr.sin_port = htons(port); 798bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 799bcf09f8c995221e75c7cd328f25c7cc6d2b5f7c9Andreas Huber addr.sin_addr.s_addr = htonl(INADDR_ANY); 800bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr.sin_port = htons(port); 801bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 802bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 803bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPClient 804bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionActive) { 805bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber in_addr_t x = ntohl(addr.sin_addr.s_addr); 806bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("connecting socket %d to %d.%d.%d.%d:%d", 807bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber s, 808bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (x >> 24), 809bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (x >> 16) & 0xff, 810bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (x >> 8) & 0xff, 811bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber x & 0xff, 812bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ntohs(addr.sin_port)); 813bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 814bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = connect(s, (const struct sockaddr *)&addr, sizeof(addr)); 815bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 816bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_LT(res, 0); 817bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (errno == EINPROGRESS) { 818bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = 0; 819bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 820bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 821bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = bind(s, (const struct sockaddr *)&addr, sizeof(addr)); 822bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 823bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res == 0) { 824bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateRTSPServer 825bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber || mode == kModeCreateTCPDatagramSessionPassive) { 826bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = listen(s, 4); 827bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 828bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(mode, kModeCreateUDPSession); 829bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 830bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (remoteHost != NULL) { 831bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 832bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero)); 833bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_family = AF_INET; 834bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_port = htons(remotePort); 835bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 836bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct hostent *ent= gethostbyname(remoteHost); 837bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (ent == NULL) { 838bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -h_errno; 839bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 840bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 841bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 842bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 843bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 844bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber res = connect( 845bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, 846bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const struct sockaddr *)&remoteAddr, 847bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sizeof(remoteAddr)); 848bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 849bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 850bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 851bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 852bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 853bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 854bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 855bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail2; 856bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 857bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 858bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Session::State state; 859bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber switch (mode) { 860bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber case kModeCreateRTSPClient: 861bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber state = Session::CONNECTING; 862bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 863bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 864bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kModeCreateTCPDatagramSessionActive: 865bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber state = Session::CONNECTING; 866bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 867bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 868bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kModeCreateTCPDatagramSessionPassive: 869bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber state = Session::LISTENING_TCP_DGRAMS; 870bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 871bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 872bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber case kModeCreateRTSPServer: 873bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber state = Session::LISTENING_RTSP; 874bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 875bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 876bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber default: 877bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber CHECK_EQ(mode, kModeCreateUDPSession); 878bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber state = Session::DATAGRAM; 879bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber break; 880bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 881bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 882bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber session = new Session( 883bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNextSessionID++, 884bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber state, 885bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, 886bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber notify); 887bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 888bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mode == kModeCreateTCPDatagramSessionActive) { 889bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber session->setIsRTSPConnection(false); 890bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else if (mode == kModeCreateRTSPClient) { 891bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber session->setIsRTSPConnection(true); 892bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 893bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 894bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSessions.add(session->sessionID(), session); 895bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 896bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 897bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 898bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *sessionID = session->sessionID(); 899bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 900bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber goto bail; 901bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 902bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbail2: 903bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(s); 904bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s = -1; 905bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 906bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberbail: 907bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 908bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 909bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 910bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::connectUDPSession( 911bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t sessionID, const char *remoteHost, unsigned remotePort) { 912bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 913bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 914bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 915bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 916bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 917bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -ENOENT; 918bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 919bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 920bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> session = mSessions.valueAt(index); 921bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s = session->socket(); 922bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 923bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 924bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber memset(remoteAddr.sin_zero, 0, sizeof(remoteAddr.sin_zero)); 925bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_family = AF_INET; 926bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_port = htons(remotePort); 927bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 928bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = OK; 929bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber struct hostent *ent = gethostbyname(remoteHost); 930bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (ent == NULL) { 931bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -h_errno; 932bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 933bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber remoteAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr; 934bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 935bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = connect( 936bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, 937bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (const struct sockaddr *)&remoteAddr, 938bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sizeof(remoteAddr)); 939bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 940bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 941bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err = -errno; 942bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 943bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 944bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 945bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 946bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 947bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 948bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatus_t ANetworkSession::sendRequest( 949bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int32_t sessionID, const void *data, ssize_t size) { 950bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 951bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 952bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t index = mSessions.indexOfKey(sessionID); 953bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 954bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (index < 0) { 955bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return -ENOENT; 956bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 957bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 958bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> session = mSessions.valueAt(index); 959bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 960bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = session->sendRequest(data, size); 961bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 962bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber interrupt(); 963bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 964bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return err; 965bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 966bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 967bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::interrupt() { 968bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber static const char dummy = 0; 969bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 970bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 971bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 972bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = write(mPipeFd[1], &dummy, 1); 973bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 974bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 975bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n < 0) { 976bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGW("Error writing to pipe (%s)", strerror(errno)); 977bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 978bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 979bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 980bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid ANetworkSession::threadLoop() { 981bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber fd_set rs, ws; 982bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_ZERO(&rs); 983bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_ZERO(&ws); 984bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 985bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_SET(mPipeFd[0], &rs); 986bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int maxFd = mPipeFd[0]; 987bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 988bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber { 989bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 990bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 991bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = 0; i < mSessions.size(); ++i) { 992bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> &session = mSessions.valueAt(i); 993bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 994bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s = session->socket(); 995bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 996bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s < 0) { 997bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 998bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 999bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1000bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (session->wantsToRead()) { 1001bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_SET(s, &rs); 1002bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s > maxFd) { 1003bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber maxFd = s; 1004bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1005bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1006bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1007bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (session->wantsToWrite()) { 1008bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber FD_SET(s, &ws); 1009bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s > maxFd) { 1010bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber maxFd = s; 1011bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1012bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1013bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1014bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1015bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1016bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int res = select(maxFd + 1, &rs, &ws, NULL, NULL /* tv */); 1017bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1018bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res == 0) { 1019bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 1020bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1021bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1022bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (res < 0) { 1023bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (errno == EINTR) { 1024bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 1025bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1026bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1027bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGE("select failed w/ error %d (%s)", errno, strerror(errno)); 1028bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber return; 1029bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1030bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1031bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(mPipeFd[0], &rs)) { 1032bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber char c; 1033bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ssize_t n; 1034bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber do { 1035bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber n = read(mPipeFd[0], &c, 1); 1036bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } while (n < 0 && errno == EINTR); 1037bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1038bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (n < 0) { 1039bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGW("Error reading from pipe (%s)", strerror(errno)); 1040bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1041bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1042bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber --res; 1043bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1044bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1045bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber { 1046bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Mutex::Autolock autoLock(mLock); 1047bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1048bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber List<sp<Session> > sessionsToAdd; 1049bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1050bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber for (size_t i = mSessions.size(); res > 0 && i-- > 0;) { 1051bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber const sp<Session> &session = mSessions.valueAt(i); 1052bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1053bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int s = session->socket(); 1054bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1055bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (s < 0) { 1056bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber continue; 1057bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1058bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1059bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) { 1060bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber --res; 1061bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1062bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1063bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(s, &rs)) { 1064bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (session->isRTSPServer() || session->isTCPDatagramServer()) { 1065bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber struct sockaddr_in remoteAddr; 1066bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber socklen_t remoteAddrLen = sizeof(remoteAddr); 1067bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1068bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber int clientSocket = accept( 1069bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 1070bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1071bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (clientSocket >= 0) { 1072bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = MakeSocketNonBlocking(clientSocket); 1073bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1074bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 1075bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGE("Unable to make client socket non blocking, " 1076bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "failed w/ error %d (%s)", 1077bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber err, strerror(-err)); 1078bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1079bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber close(clientSocket); 1080bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber clientSocket = -1; 1081bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 1082bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber in_addr_t addr = ntohl(remoteAddr.sin_addr.s_addr); 1083bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1084bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("incoming connection from %d.%d.%d.%d:%d " 1085bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber "(socket %d)", 1086bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 24), 1087bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 16) & 0xff, 1088bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber (addr >> 8) & 0xff, 1089bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber addr & 0xff, 1090bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ntohs(remoteAddr.sin_port), 1091bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber clientSocket); 1092bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1093bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<Session> clientSession = 1094bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber // using socket sd as sessionID 1095bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber new Session( 1096bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mNextSessionID++, 1097bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber Session::CONNECTED, 1098bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber clientSocket, 1099bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber session->getNotificationMessage()); 1100bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1101bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber clientSession->setIsRTSPConnection( 1102bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber session->isRTSPServer()); 1103bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 1104bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionsToAdd.push_back(clientSession); 1105bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1106bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 1107bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGE("accept returned error %d (%s)", 1108bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber errno, strerror(errno)); 1109bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1110bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } else { 1111bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = session->readMore(); 1112bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 111396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGE("readMore on socket %d failed w/ error %d (%s)", 1114bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, err, strerror(-err)); 1115bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1116bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1117bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1118bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1119bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (FD_ISSET(s, &ws)) { 1120bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber status_t err = session->writeMore(); 1121bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber if (err != OK) { 112296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGE("writeMore on socket %d failed w/ error %d (%s)", 1123bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber s, err, strerror(-err)); 1124bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1125bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1126bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1127bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1128bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber while (!sessionsToAdd.empty()) { 1129bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sp<Session> session = *sessionsToAdd.begin(); 1130bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber sessionsToAdd.erase(sessionsToAdd.begin()); 1131bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1132bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber mSessions.add(session->sessionID(), session); 1133bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1134bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber ALOGI("added clientSession %d", session->sessionID()); 1135bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1136bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber } 1137bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} 1138bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1139bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber} // namespace android 1140bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber 1141