summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp97
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h10
2 files changed, 95 insertions, 12 deletions
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 35d4414..a998dcd 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -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;
}
@@ -154,7 +152,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
mNetSession->destroySession(sessionID);
- mClientIPs.removeItem(sessionID);
+ mClientInfos.removeItem(sessionID);
break;
}
@@ -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);
@@ -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();
}
@@ -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: "
@@ -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;
@@ -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;
@@ -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));
@@ -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);
@@ -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);
@@ -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);
@@ -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(
@@ -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;
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index cd9939b..f56347d 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -49,6 +49,7 @@ private:
kWhatStop,
kWhatReapDeadClients,
kWhatPlaybackSessionNotify,
+ kWhatKeepAlive,
};
struct ResponseID {
@@ -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;
@@ -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);
@@ -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);
@@ -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;