1761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman/*
2761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Copyright (C) 2011 The Android Open Source Project
3761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *
4761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Licensed under the Apache License, Version 2.0 (the "License");
5761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * you may not use this file except in compliance with the License.
6761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * You may obtain a copy of the License at
7761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *
8761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *      http://www.apache.org/licenses/LICENSE-2.0
9761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *
10761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Unless required by applicable law or agreed to in writing, software
11761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * distributed under the License is distributed on an "AS IS" BASIS,
12761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * See the License for the specific language governing permissions and
14761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * limitations under the License.
15761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman */
16761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
17761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#ifndef __AAH_TX_SENDER_H__
18761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#define __AAH_TX_SENDER_H__
19761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
20761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/foundation/ALooper.h>
21761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/foundation/AHandlerReflector.h>
22761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/RefBase.h>
23761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/threads.h>
24761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
25761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include "aah_tx_packet.h"
26761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include "pipe_event.h"
27761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
28761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmannamespace android {
29761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
30761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmantemplate <typename T> class CircularBuffer {
31761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman  public:
32761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    CircularBuffer(size_t capacity);
33761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    ~CircularBuffer();
34761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void push_back(const T& item);;
35761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void pop_front();
36761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    size_t size() const;
37761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    bool isFull() const;
38761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    bool isEmpty() const;
39761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    const T& itemAt(size_t index) const;
40761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    const T& operator[](size_t index) const;
41761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
42761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman  private:
43761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    T* mBuffer;
44761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    size_t mCapacity;
45761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    size_t mHead;
46761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    size_t mTail;
47761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    size_t mFillCount;
48761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
49761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    DISALLOW_EVIL_CONSTRUCTORS(CircularBuffer);
50761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman};
51761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
52761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanclass AAH_TXSender : public virtual RefBase {
53761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman  public:
54761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    ~AAH_TXSender();
55761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
56761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static sp<AAH_TXSender> GetInstance();
57761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
58761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    ALooper::handler_id handlerID() { return mReflector->id(); }
59761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
60761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    // an IP address and port
61761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    struct Endpoint {
62761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        Endpoint();
63761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        Endpoint(uint32_t a, uint16_t p);
64761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        bool operator<(const Endpoint& other) const;
65761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
66761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        uint32_t addr;
67761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        uint16_t port;
68761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    };
69761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
70761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    uint16_t registerEndpoint(const Endpoint& endpoint);
71761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void unregisterEndpoint(const Endpoint& endpoint);
72761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
73761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    enum {
74761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        kWhatSendPacket,
75761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        kWhatTrimRetryBuffers,
76761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        kWhatSendHeartbeats,
77761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    };
78761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
79761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    // fields for SendPacket messages
80761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const char* kSendPacketIPAddr;
81761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const char* kSendPacketPort;
82761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const char* kSendPacketTRTPPacket;
83761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
84761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman  private:
85761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    AAH_TXSender();
86761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
87761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static Mutex sLock;
88761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static wp<AAH_TXSender> sInstance;
89761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static uint32_t sNextEpoch;
90761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static bool sNextEpochValid;
91761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
92761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static uint32_t getNextEpoch();
93761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
94761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    typedef CircularBuffer<sp<TRTPPacket> > RetryBuffer;
95761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
96761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    // state maintained on a per-endpoint basis
97761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    struct EndpointState {
98761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        EndpointState(uint32_t epoch);
99761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        RetryBuffer retry;
100761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        int playerRefCount;
101761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        uint16_t trtpSeqNumber;
102761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        uint16_t nextProgramID;
103761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        uint32_t epoch;
104761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    };
105761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
106761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    friend class AHandlerReflector<AAH_TXSender>;
107761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void onMessageReceived(const sp<AMessage>& msg);
108761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void onSendPacket(const sp<AMessage>& msg);
109761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void doSendPacket_l(const sp<TRTPPacket>& packet,
110761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman                        const Endpoint& endpoint);
111761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void trimRetryBuffers();
112761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    void sendHeartbeats();
113761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    bool shouldSendHeartbeats_l();
114761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
115761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    sp<ALooper> mLooper;
116761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    sp<AHandlerReflector<AAH_TXSender> > mReflector;
117761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
118761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    int mSocket;
119761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    nsecs_t mLastSentPacketTime;
120761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
121761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    DefaultKeyedVector<Endpoint, EndpointState*> mEndpointMap;
122761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    Mutex mEndpointLock;
123761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
124761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const int kRetryTrimIntervalUs;
125761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const int kHeartbeatIntervalUs;
126761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const int kRetryBufferCapacity;
127761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    static const nsecs_t kHeartbeatTimeout;
128761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
129761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    class RetryReceiver : public Thread {
130761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman      private:
131761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        friend class AAH_TXSender;
132761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
133761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        RetryReceiver(AAH_TXSender* sender);
134761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        virtual ~RetryReceiver();
135761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        virtual bool threadLoop();
136761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        void handleRetryRequest();
137761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
138761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        static const int kMaxReceiverPacketLen;
139761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        static const uint32_t kRetryRequestID;
140761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        static const uint32_t kFastStartRequestID;
141761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        static const uint32_t kRetryNakID;
142761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
143761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        AAH_TXSender* mSender;
144761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman        PipeEvent mWakeupEvent;
145761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    };
146761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
147761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    sp<RetryReceiver> mRetryReceiver;
148761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
149761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    DISALLOW_EVIL_CONSTRUCTORS(AAH_TXSender);
150761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman};
151761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
152761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstruct RetryPacket {
153761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    uint32_t id;
154761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    uint32_t endpointIP;
155761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    uint16_t endpointPort;
156761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    uint16_t seqStart;
157761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    uint16_t seqEnd;
158761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} __attribute__((packed));
159761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
160761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman}  // namespace android
161761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
162761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#endif  // __AAH_TX_SENDER_H__
163