1 /* 2 * Copyright 2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WIFI_DISPLAY_SOURCE_H_ 18 19 #define WIFI_DISPLAY_SOURCE_H_ 20 21 #include "VideoFormats.h" 22 23 #include <media/stagefright/foundation/AHandler.h> 24 #include <media/stagefright/foundation/ANetworkSession.h> 25 26 #include <netinet/in.h> 27 28 namespace android { 29 30 struct IHDCP; 31 struct IRemoteDisplayClient; 32 struct ParsedMessage; 33 34 // Represents the RTSP server acting as a wifi display source. 35 // Manages incoming connections, sets up Playback sessions as necessary. 36 struct WifiDisplaySource : public AHandler { 37 static const unsigned kWifiDisplayDefaultPort = 7236; 38 39 WifiDisplaySource( 40 const sp<ANetworkSession> &netSession, 41 const sp<IRemoteDisplayClient> &client, 42 const char *path = NULL); 43 44 status_t start(const char *iface); 45 status_t stop(); 46 47 status_t pause(); 48 status_t resume(); 49 50 protected: 51 virtual ~WifiDisplaySource(); 52 virtual void onMessageReceived(const sp<AMessage> &msg); 53 54 private: 55 struct PlaybackSession; 56 struct HDCPObserver; 57 58 enum State { 59 INITIALIZED, 60 AWAITING_CLIENT_CONNECTION, 61 AWAITING_CLIENT_SETUP, 62 AWAITING_CLIENT_PLAY, 63 ABOUT_TO_PLAY, 64 PLAYING, 65 PLAYING_TO_PAUSED, 66 PAUSED, 67 PAUSED_TO_PLAYING, 68 AWAITING_CLIENT_TEARDOWN, 69 STOPPING, 70 STOPPED, 71 }; 72 73 enum { 74 kWhatStart, 75 kWhatRTSPNotify, 76 kWhatStop, 77 kWhatPause, 78 kWhatResume, 79 kWhatReapDeadClients, 80 kWhatPlaybackSessionNotify, 81 kWhatKeepAlive, 82 kWhatHDCPNotify, 83 kWhatFinishStop2, 84 kWhatTeardownTriggerTimedOut, 85 }; 86 87 struct ResponseID { 88 int32_t mSessionID; 89 int32_t mCSeq; 90 91 bool operator<(const ResponseID &other) const { 92 return mSessionID < other.mSessionID 93 || (mSessionID == other.mSessionID 94 && mCSeq < other.mCSeq); 95 } 96 }; 97 98 typedef status_t (WifiDisplaySource::*HandleRTSPResponseFunc)( 99 int32_t sessionID, const sp<ParsedMessage> &msg); 100 101 static const int64_t kReaperIntervalUs = 1000000ll; 102 103 // We request that the dongle send us a "TEARDOWN" in order to 104 // perform an orderly shutdown. We're willing to wait up to 2 secs 105 // for this message to arrive, after that we'll force a disconnect 106 // instead. 107 static const int64_t kTeardownTriggerTimeouSecs = 2; 108 109 static const int64_t kPlaybackSessionTimeoutSecs = 30; 110 111 static const int64_t kPlaybackSessionTimeoutUs = 112 kPlaybackSessionTimeoutSecs * 1000000ll; 113 114 static const AString sUserAgent; 115 116 State mState; 117 VideoFormats mSupportedSourceVideoFormats; 118 sp<ANetworkSession> mNetSession; 119 sp<IRemoteDisplayClient> mClient; 120 AString mMediaPath; 121 struct in_addr mInterfaceAddr; 122 int32_t mSessionID; 123 124 uint32_t mStopReplyID; 125 126 AString mWfdClientRtpPorts; 127 int32_t mChosenRTPPort; // extracted from "wfd_client_rtp_ports" 128 129 bool mSinkSupportsVideo; 130 VideoFormats mSupportedSinkVideoFormats; 131 132 VideoFormats::ResolutionType mChosenVideoResolutionType; 133 size_t mChosenVideoResolutionIndex; 134 VideoFormats::ProfileType mChosenVideoProfile; 135 VideoFormats::LevelType mChosenVideoLevel; 136 137 bool mSinkSupportsAudio; 138 139 bool mUsingPCMAudio; 140 int32_t mClientSessionID; 141 142 struct ClientInfo { 143 AString mRemoteIP; 144 AString mLocalIP; 145 int32_t mLocalPort; 146 int32_t mPlaybackSessionID; 147 sp<PlaybackSession> mPlaybackSession; 148 }; 149 ClientInfo mClientInfo; 150 151 bool mReaperPending; 152 153 int32_t mNextCSeq; 154 155 KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers; 156 157 // HDCP specific section >>>> 158 bool mUsingHDCP; 159 bool mIsHDCP2_0; 160 int32_t mHDCPPort; 161 sp<IHDCP> mHDCP; 162 sp<HDCPObserver> mHDCPObserver; 163 164 bool mHDCPInitializationComplete; 165 bool mSetupTriggerDeferred; 166 167 bool mPlaybackSessionEstablished; 168 169 status_t makeHDCP(); 170 // <<<< HDCP specific section 171 172 status_t sendM1(int32_t sessionID); 173 status_t sendM3(int32_t sessionID); 174 status_t sendM4(int32_t sessionID); 175 176 enum TriggerType { 177 TRIGGER_SETUP, 178 TRIGGER_TEARDOWN, 179 TRIGGER_PAUSE, 180 TRIGGER_PLAY, 181 }; 182 183 // M5 184 status_t sendTrigger(int32_t sessionID, TriggerType triggerType); 185 186 status_t sendM16(int32_t sessionID); 187 188 status_t onReceiveM1Response( 189 int32_t sessionID, const sp<ParsedMessage> &msg); 190 191 status_t onReceiveM3Response( 192 int32_t sessionID, const sp<ParsedMessage> &msg); 193 194 status_t onReceiveM4Response( 195 int32_t sessionID, const sp<ParsedMessage> &msg); 196 197 status_t onReceiveM5Response( 198 int32_t sessionID, const sp<ParsedMessage> &msg); 199 200 status_t onReceiveM16Response( 201 int32_t sessionID, const sp<ParsedMessage> &msg); 202 203 void registerResponseHandler( 204 int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func); 205 206 status_t onReceiveClientData(const sp<AMessage> &msg); 207 208 status_t onOptionsRequest( 209 int32_t sessionID, 210 int32_t cseq, 211 const sp<ParsedMessage> &data); 212 213 status_t onSetupRequest( 214 int32_t sessionID, 215 int32_t cseq, 216 const sp<ParsedMessage> &data); 217 218 status_t onPlayRequest( 219 int32_t sessionID, 220 int32_t cseq, 221 const sp<ParsedMessage> &data); 222 223 status_t onPauseRequest( 224 int32_t sessionID, 225 int32_t cseq, 226 const sp<ParsedMessage> &data); 227 228 status_t onTeardownRequest( 229 int32_t sessionID, 230 int32_t cseq, 231 const sp<ParsedMessage> &data); 232 233 status_t onGetParameterRequest( 234 int32_t sessionID, 235 int32_t cseq, 236 const sp<ParsedMessage> &data); 237 238 status_t onSetParameterRequest( 239 int32_t sessionID, 240 int32_t cseq, 241 const sp<ParsedMessage> &data); 242 243 void sendErrorResponse( 244 int32_t sessionID, 245 const char *errorDetail, 246 int32_t cseq); 247 248 static void AppendCommonResponse( 249 AString *response, int32_t cseq, int32_t playbackSessionID = -1ll); 250 251 void scheduleReaper(); 252 void scheduleKeepAlive(int32_t sessionID); 253 254 int32_t makeUniquePlaybackSessionID() const; 255 256 sp<PlaybackSession> findPlaybackSession( 257 const sp<ParsedMessage> &data, int32_t *playbackSessionID) const; 258 259 void finishStop(); 260 void disconnectClientAsync(); 261 void disconnectClient2(); 262 void finishStopAfterDisconnectingClient(); 263 void finishStop2(); 264 265 void finishPlay(); 266 267 DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource); 268 }; 269 270 } // namespace android 271 272 #endif // WIFI_DISPLAY_SOURCE_H_ 273