Home | History | Annotate | Download | only in source
      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