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 "ANetworkSession.h"
     22 
     23 #include <media/stagefright/foundation/AHandler.h>
     24 
     25 #include <netinet/in.h>
     26 
     27 namespace android {
     28 
     29 struct IHDCP;
     30 struct IRemoteDisplayClient;
     31 struct ParsedMessage;
     32 
     33 // Represents the RTSP server acting as a wifi display source.
     34 // Manages incoming connections, sets up Playback sessions as necessary.
     35 struct WifiDisplaySource : public AHandler {
     36     static const unsigned kWifiDisplayDefaultPort = 7236;
     37 
     38     WifiDisplaySource(
     39             const sp<ANetworkSession> &netSession,
     40             const sp<IRemoteDisplayClient> &client);
     41 
     42     status_t start(const char *iface);
     43     status_t stop();
     44 
     45 protected:
     46     virtual ~WifiDisplaySource();
     47     virtual void onMessageReceived(const sp<AMessage> &msg);
     48 
     49 private:
     50     struct PlaybackSession;
     51     struct HDCPObserver;
     52 
     53     enum State {
     54         INITIALIZED,
     55         AWAITING_CLIENT_CONNECTION,
     56         AWAITING_CLIENT_SETUP,
     57         AWAITING_CLIENT_PLAY,
     58         ABOUT_TO_PLAY,
     59         PLAYING,
     60         AWAITING_CLIENT_TEARDOWN,
     61         STOPPING,
     62         STOPPED,
     63     };
     64 
     65     enum {
     66         kWhatStart,
     67         kWhatRTSPNotify,
     68         kWhatStop,
     69         kWhatReapDeadClients,
     70         kWhatPlaybackSessionNotify,
     71         kWhatKeepAlive,
     72         kWhatHDCPNotify,
     73         kWhatFinishStop2,
     74         kWhatTeardownTriggerTimedOut,
     75     };
     76 
     77     struct ResponseID {
     78         int32_t mSessionID;
     79         int32_t mCSeq;
     80 
     81         bool operator<(const ResponseID &other) const {
     82             return mSessionID < other.mSessionID
     83                 || (mSessionID == other.mSessionID
     84                         && mCSeq < other.mCSeq);
     85         }
     86     };
     87 
     88     typedef status_t (WifiDisplaySource::*HandleRTSPResponseFunc)(
     89             int32_t sessionID, const sp<ParsedMessage> &msg);
     90 
     91     static const int64_t kReaperIntervalUs = 1000000ll;
     92 
     93     // We request that the dongle send us a "TEARDOWN" in order to
     94     // perform an orderly shutdown. We're willing to wait up to 2 secs
     95     // for this message to arrive, after that we'll force a disconnect
     96     // instead.
     97     static const int64_t kTeardownTriggerTimeouSecs = 2;
     98 
     99     static const int64_t kPlaybackSessionTimeoutSecs = 30;
    100 
    101     static const int64_t kPlaybackSessionTimeoutUs =
    102         kPlaybackSessionTimeoutSecs * 1000000ll;
    103 
    104     State mState;
    105     sp<ANetworkSession> mNetSession;
    106     sp<IRemoteDisplayClient> mClient;
    107     struct in_addr mInterfaceAddr;
    108     int32_t mSessionID;
    109 
    110     uint32_t mStopReplyID;
    111 
    112     int32_t mChosenRTPPort;  // extracted from "wfd_client_rtp_ports"
    113 
    114     bool mUsingPCMAudio;
    115     int32_t mClientSessionID;
    116 
    117     struct ClientInfo {
    118         AString mRemoteIP;
    119         AString mLocalIP;
    120         int32_t mLocalPort;
    121         int32_t mPlaybackSessionID;
    122         sp<PlaybackSession> mPlaybackSession;
    123     };
    124     ClientInfo mClientInfo;
    125 
    126     bool mReaperPending;
    127 
    128     int32_t mNextCSeq;
    129 
    130     KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
    131 
    132     // HDCP specific section >>>>
    133     bool mUsingHDCP;
    134     bool mIsHDCP2_0;
    135     int32_t mHDCPPort;
    136     sp<IHDCP> mHDCP;
    137     sp<HDCPObserver> mHDCPObserver;
    138 
    139     bool mHDCPInitializationComplete;
    140     bool mSetupTriggerDeferred;
    141 
    142     status_t makeHDCP();
    143     // <<<< HDCP specific section
    144 
    145     status_t sendM1(int32_t sessionID);
    146     status_t sendM3(int32_t sessionID);
    147     status_t sendM4(int32_t sessionID);
    148     status_t sendM5(int32_t sessionID, bool requestShutdown);
    149     status_t sendM16(int32_t sessionID);
    150 
    151     status_t onReceiveM1Response(
    152             int32_t sessionID, const sp<ParsedMessage> &msg);
    153 
    154     status_t onReceiveM3Response(
    155             int32_t sessionID, const sp<ParsedMessage> &msg);
    156 
    157     status_t onReceiveM4Response(
    158             int32_t sessionID, const sp<ParsedMessage> &msg);
    159 
    160     status_t onReceiveM5Response(
    161             int32_t sessionID, const sp<ParsedMessage> &msg);
    162 
    163     status_t onReceiveM16Response(
    164             int32_t sessionID, const sp<ParsedMessage> &msg);
    165 
    166     void registerResponseHandler(
    167             int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
    168 
    169     status_t onReceiveClientData(const sp<AMessage> &msg);
    170 
    171     status_t onOptionsRequest(
    172             int32_t sessionID,
    173             int32_t cseq,
    174             const sp<ParsedMessage> &data);
    175 
    176     status_t onSetupRequest(
    177             int32_t sessionID,
    178             int32_t cseq,
    179             const sp<ParsedMessage> &data);
    180 
    181     status_t onPlayRequest(
    182             int32_t sessionID,
    183             int32_t cseq,
    184             const sp<ParsedMessage> &data);
    185 
    186     status_t onPauseRequest(
    187             int32_t sessionID,
    188             int32_t cseq,
    189             const sp<ParsedMessage> &data);
    190 
    191     status_t onTeardownRequest(
    192             int32_t sessionID,
    193             int32_t cseq,
    194             const sp<ParsedMessage> &data);
    195 
    196     status_t onGetParameterRequest(
    197             int32_t sessionID,
    198             int32_t cseq,
    199             const sp<ParsedMessage> &data);
    200 
    201     status_t onSetParameterRequest(
    202             int32_t sessionID,
    203             int32_t cseq,
    204             const sp<ParsedMessage> &data);
    205 
    206     void sendErrorResponse(
    207             int32_t sessionID,
    208             const char *errorDetail,
    209             int32_t cseq);
    210 
    211     static void AppendCommonResponse(
    212             AString *response, int32_t cseq, int32_t playbackSessionID = -1ll);
    213 
    214     void scheduleReaper();
    215     void scheduleKeepAlive(int32_t sessionID);
    216 
    217     int32_t makeUniquePlaybackSessionID() const;
    218 
    219     sp<PlaybackSession> findPlaybackSession(
    220             const sp<ParsedMessage> &data, int32_t *playbackSessionID) const;
    221 
    222     void finishStop();
    223     void disconnectClientAsync();
    224     void disconnectClient2();
    225     void finishStopAfterDisconnectingClient();
    226     void finishStop2();
    227 
    228     DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource);
    229 };
    230 
    231 }  // namespace android
    232 
    233 #endif  // WIFI_DISPLAY_SOURCE_H_
    234