Loading media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +86 −11 Original line number Diff line number Diff line Loading @@ -116,8 +116,6 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { err = mNetSession->createRTSPServer( addr, port, notify, &mSessionID); ALOGI("createRTSPServer returned err %d", err); } else { err = -EINVAL; } Loading Loading @@ -154,7 +152,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { mNetSession->destroySession(sessionID); mClientIPs.removeItem(sessionID); mClientInfos.removeItem(sessionID); break; } Loading @@ -167,10 +165,11 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { CHECK(msg->findString("client-ip", &info.mRemoteIP)); CHECK(msg->findString("server-ip", &info.mLocalIP)); CHECK(msg->findInt32("server-port", &info.mLocalPort)); info.mPlaybackSessionID = -1; ALOGI("We now have a client (%d) connected.", sessionID); mClientIPs.add(sessionID, info); mClientInfos.add(sessionID, info); status_t err = sendM1(sessionID); CHECK_EQ(err, (status_t)OK); Loading Loading @@ -284,6 +283,20 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatKeepAlive: { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); if (mClientInfos.indexOfKey(sessionID) < 0) { // Obsolete event, client is already gone. break; } sendM16(sessionID); break; } default: TRESPASS(); } Loading Loading @@ -366,7 +379,7 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) { // max-hres (none or 2 byte) // max-vres (none or 2 byte) const ClientInfo &info = mClientIPs.valueFor(sessionID); const ClientInfo &info = mClientInfos.valueFor(sessionID); AString body = StringPrintf( "wfd_video_formats: " Loading Loading @@ -425,6 +438,31 @@ status_t WifiDisplaySource::sendM5(int32_t sessionID) { return OK; } status_t WifiDisplaySource::sendM16(int32_t sessionID) { AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); const ClientInfo &info = mClientInfos.valueFor(sessionID); request.append(StringPrintf("Session: %d\r\n", info.mPlaybackSessionID)); request.append("Content-Length: 0\r\n"); request.append("\r\n"); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM16Response); ++mNextCSeq; return OK; } status_t WifiDisplaySource::onReceiveM1Response( int32_t sessionID, const sp<ParsedMessage> &msg) { int32_t statusCode; Loading Loading @@ -481,6 +519,22 @@ status_t WifiDisplaySource::onReceiveM5Response( return OK; } status_t WifiDisplaySource::onReceiveM16Response( int32_t sessionID, const sp<ParsedMessage> &msg) { // If only the response was required to include a "Session:" header... const ClientInfo &info = mClientInfos.valueFor(sessionID); ssize_t index = mPlaybackSessions.indexOfKey(info.mPlaybackSessionID); if (index >= 0) { mPlaybackSessions.valueAt(index)->updateLiveness(); scheduleKeepAlive(sessionID); } return OK; } void WifiDisplaySource::scheduleReaper() { if (mReaperPending) { return; Loading @@ -490,6 +544,16 @@ void WifiDisplaySource::scheduleReaper() { (new AMessage(kWhatReapDeadClients, id()))->post(kReaperIntervalUs); } void WifiDisplaySource::scheduleKeepAlive(int32_t sessionID) { // We need to send updates at least 5 secs before the timeout is set to // expire, make sure the timeout is greater than 5 secs to begin with. CHECK_GT(kPlaybackSessionTimeoutUs, 5000000ll); sp<AMessage> msg = new AMessage(kWhatKeepAlive, id()); msg->setInt32("sessionID", sessionID); msg->post(kPlaybackSessionTimeoutUs - 5000000ll); } void WifiDisplaySource::onReceiveClientData(const sp<AMessage> &msg) { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); Loading Loading @@ -637,6 +701,14 @@ void WifiDisplaySource::onSetupRequest( int32_t sessionID, int32_t cseq, const sp<ParsedMessage> &data) { ClientInfo *info = &mClientInfos.editValueFor(sessionID); if (info->mPlaybackSessionID != -1) { // We only support a single playback session per client. // This is due to the reversed keep-alive design in the wfd specs... sendErrorResponse(sessionID, "400 Bad Request", cseq); return; } AString transport; if (!data->findString("transport", &transport)) { sendErrorResponse(sessionID, "400 Bad Request", cseq); Loading Loading @@ -713,10 +785,8 @@ void WifiDisplaySource::onSetupRequest( return; } const ClientInfo &info = mClientIPs.valueFor(sessionID); status_t err = playbackSession->init( info.mRemoteIP.c_str(), info->mRemoteIP.c_str(), clientRtp, clientRtcp, useInterleavedTCP); Loading @@ -739,6 +809,8 @@ void WifiDisplaySource::onSetupRequest( mPlaybackSessions.add(playbackSessionID, playbackSession); info->mPlaybackSessionID = playbackSessionID; AString response = "RTSP/1.0 200 OK\r\n"; AppendCommonResponse(&response, cseq, playbackSessionID); Loading Loading @@ -770,10 +842,8 @@ void WifiDisplaySource::onSetupRequest( err = mNetSession->sendRequest(sessionID, response.c_str()); CHECK_EQ(err, (status_t)OK); #if 0 // XXX the dongle does not currently send keep-alives. scheduleReaper(); #endif scheduleKeepAlive(sessionID); } void WifiDisplaySource::onPlayRequest( Loading Loading @@ -949,6 +1019,11 @@ int32_t WifiDisplaySource::makeUniquePlaybackSessionID() const { for (;;) { int32_t playbackSessionID = rand(); if (playbackSessionID == -1) { // reserved. continue; } for (size_t i = 0; i < mPlaybackSessions.size(); ++i) { if (mPlaybackSessions.keyAt(i) == playbackSessionID) { continue; Loading media/libstagefright/wifi-display/source/WifiDisplaySource.h +9 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ private: kWhatStop, kWhatReapDeadClients, kWhatPlaybackSessionNotify, kWhatKeepAlive, }; struct ResponseID { Loading Loading @@ -79,8 +80,10 @@ private: AString mRemoteIP; AString mLocalIP; int32_t mLocalPort; int32_t mPlaybackSessionID; }; KeyedVector<int32_t, ClientInfo> mClientIPs; // by sessionID. KeyedVector<int32_t, ClientInfo> mClientInfos; bool mReaperPending; Loading @@ -94,6 +97,7 @@ private: status_t sendM3(int32_t sessionID); status_t sendM4(int32_t sessionID); status_t sendM5(int32_t sessionID); status_t sendM16(int32_t sessionID); status_t onReceiveM1Response( int32_t sessionID, const sp<ParsedMessage> &msg); Loading @@ -107,6 +111,9 @@ private: status_t onReceiveM5Response( int32_t sessionID, const sp<ParsedMessage> &msg); status_t onReceiveM16Response( int32_t sessionID, const sp<ParsedMessage> &msg); void registerResponseHandler( int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func); Loading Loading @@ -161,6 +168,7 @@ private: AString *response, int32_t cseq, int32_t playbackSessionID = -1ll); void scheduleReaper(); void scheduleKeepAlive(int32_t sessionID); int32_t makeUniquePlaybackSessionID() const; Loading Loading
media/libstagefright/wifi-display/source/WifiDisplaySource.cpp +86 −11 Original line number Diff line number Diff line Loading @@ -116,8 +116,6 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { err = mNetSession->createRTSPServer( addr, port, notify, &mSessionID); ALOGI("createRTSPServer returned err %d", err); } else { err = -EINVAL; } Loading Loading @@ -154,7 +152,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { mNetSession->destroySession(sessionID); mClientIPs.removeItem(sessionID); mClientInfos.removeItem(sessionID); break; } Loading @@ -167,10 +165,11 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { CHECK(msg->findString("client-ip", &info.mRemoteIP)); CHECK(msg->findString("server-ip", &info.mLocalIP)); CHECK(msg->findInt32("server-port", &info.mLocalPort)); info.mPlaybackSessionID = -1; ALOGI("We now have a client (%d) connected.", sessionID); mClientIPs.add(sessionID, info); mClientInfos.add(sessionID, info); status_t err = sendM1(sessionID); CHECK_EQ(err, (status_t)OK); Loading Loading @@ -284,6 +283,20 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatKeepAlive: { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); if (mClientInfos.indexOfKey(sessionID) < 0) { // Obsolete event, client is already gone. break; } sendM16(sessionID); break; } default: TRESPASS(); } Loading Loading @@ -366,7 +379,7 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) { // max-hres (none or 2 byte) // max-vres (none or 2 byte) const ClientInfo &info = mClientIPs.valueFor(sessionID); const ClientInfo &info = mClientInfos.valueFor(sessionID); AString body = StringPrintf( "wfd_video_formats: " Loading Loading @@ -425,6 +438,31 @@ status_t WifiDisplaySource::sendM5(int32_t sessionID) { return OK; } status_t WifiDisplaySource::sendM16(int32_t sessionID) { AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); const ClientInfo &info = mClientInfos.valueFor(sessionID); request.append(StringPrintf("Session: %d\r\n", info.mPlaybackSessionID)); request.append("Content-Length: 0\r\n"); request.append("\r\n"); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM16Response); ++mNextCSeq; return OK; } status_t WifiDisplaySource::onReceiveM1Response( int32_t sessionID, const sp<ParsedMessage> &msg) { int32_t statusCode; Loading Loading @@ -481,6 +519,22 @@ status_t WifiDisplaySource::onReceiveM5Response( return OK; } status_t WifiDisplaySource::onReceiveM16Response( int32_t sessionID, const sp<ParsedMessage> &msg) { // If only the response was required to include a "Session:" header... const ClientInfo &info = mClientInfos.valueFor(sessionID); ssize_t index = mPlaybackSessions.indexOfKey(info.mPlaybackSessionID); if (index >= 0) { mPlaybackSessions.valueAt(index)->updateLiveness(); scheduleKeepAlive(sessionID); } return OK; } void WifiDisplaySource::scheduleReaper() { if (mReaperPending) { return; Loading @@ -490,6 +544,16 @@ void WifiDisplaySource::scheduleReaper() { (new AMessage(kWhatReapDeadClients, id()))->post(kReaperIntervalUs); } void WifiDisplaySource::scheduleKeepAlive(int32_t sessionID) { // We need to send updates at least 5 secs before the timeout is set to // expire, make sure the timeout is greater than 5 secs to begin with. CHECK_GT(kPlaybackSessionTimeoutUs, 5000000ll); sp<AMessage> msg = new AMessage(kWhatKeepAlive, id()); msg->setInt32("sessionID", sessionID); msg->post(kPlaybackSessionTimeoutUs - 5000000ll); } void WifiDisplaySource::onReceiveClientData(const sp<AMessage> &msg) { int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); Loading Loading @@ -637,6 +701,14 @@ void WifiDisplaySource::onSetupRequest( int32_t sessionID, int32_t cseq, const sp<ParsedMessage> &data) { ClientInfo *info = &mClientInfos.editValueFor(sessionID); if (info->mPlaybackSessionID != -1) { // We only support a single playback session per client. // This is due to the reversed keep-alive design in the wfd specs... sendErrorResponse(sessionID, "400 Bad Request", cseq); return; } AString transport; if (!data->findString("transport", &transport)) { sendErrorResponse(sessionID, "400 Bad Request", cseq); Loading Loading @@ -713,10 +785,8 @@ void WifiDisplaySource::onSetupRequest( return; } const ClientInfo &info = mClientIPs.valueFor(sessionID); status_t err = playbackSession->init( info.mRemoteIP.c_str(), info->mRemoteIP.c_str(), clientRtp, clientRtcp, useInterleavedTCP); Loading @@ -739,6 +809,8 @@ void WifiDisplaySource::onSetupRequest( mPlaybackSessions.add(playbackSessionID, playbackSession); info->mPlaybackSessionID = playbackSessionID; AString response = "RTSP/1.0 200 OK\r\n"; AppendCommonResponse(&response, cseq, playbackSessionID); Loading Loading @@ -770,10 +842,8 @@ void WifiDisplaySource::onSetupRequest( err = mNetSession->sendRequest(sessionID, response.c_str()); CHECK_EQ(err, (status_t)OK); #if 0 // XXX the dongle does not currently send keep-alives. scheduleReaper(); #endif scheduleKeepAlive(sessionID); } void WifiDisplaySource::onPlayRequest( Loading Loading @@ -949,6 +1019,11 @@ int32_t WifiDisplaySource::makeUniquePlaybackSessionID() const { for (;;) { int32_t playbackSessionID = rand(); if (playbackSessionID == -1) { // reserved. continue; } for (size_t i = 0; i < mPlaybackSessions.size(); ++i) { if (mPlaybackSessions.keyAt(i) == playbackSessionID) { continue; Loading
media/libstagefright/wifi-display/source/WifiDisplaySource.h +9 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ private: kWhatStop, kWhatReapDeadClients, kWhatPlaybackSessionNotify, kWhatKeepAlive, }; struct ResponseID { Loading Loading @@ -79,8 +80,10 @@ private: AString mRemoteIP; AString mLocalIP; int32_t mLocalPort; int32_t mPlaybackSessionID; }; KeyedVector<int32_t, ClientInfo> mClientIPs; // by sessionID. KeyedVector<int32_t, ClientInfo> mClientInfos; bool mReaperPending; Loading @@ -94,6 +97,7 @@ private: status_t sendM3(int32_t sessionID); status_t sendM4(int32_t sessionID); status_t sendM5(int32_t sessionID); status_t sendM16(int32_t sessionID); status_t onReceiveM1Response( int32_t sessionID, const sp<ParsedMessage> &msg); Loading @@ -107,6 +111,9 @@ private: status_t onReceiveM5Response( int32_t sessionID, const sp<ParsedMessage> &msg); status_t onReceiveM16Response( int32_t sessionID, const sp<ParsedMessage> &msg); void registerResponseHandler( int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func); Loading Loading @@ -161,6 +168,7 @@ private: AString *response, int32_t cseq, int32_t playbackSessionID = -1ll); void scheduleReaper(); void scheduleKeepAlive(int32_t sessionID); int32_t makeUniquePlaybackSessionID() const; Loading