Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2921612d authored by John Grossman's avatar John Grossman
Browse files

LibAAH_RTP: Add unicast mode support to the RXPlayer



Add support for unicast mode to the AAH RXPlayer.  At the API level,
things should be pretty simple.  To use unicast mode, instead of
passing the multicast address and port in the data source URL, just
pass the unicast address and port of the transmitters command and
control port.  For example, instead of

aahRX://224.128.60.5:8867

one might instead pass

aahRX://192.168.63.5:55476

Change-Id: I7b40716983d7a91def86dcf40f093dda4255aae3
Signed-off-by: default avatarJohn Grossman <johngro@google.com>
parent 06938878
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ AAH_RXPlayer::AAH_RXPlayer()

    is_playing_          = false;
    multicast_joined_    = false;
    multicast_mode_      = false;
    transmitter_known_   = false;
    current_epoch_known_ = false;
    data_source_set_     = false;
@@ -46,7 +47,7 @@ AAH_RXPlayer::AAH_RXPlayer()

    substreams_.setCapacity(4);

    memset(&listen_addr_,      0, sizeof(listen_addr_));
    memset(&data_source_addr_, 0, sizeof(data_source_addr_));
    memset(&transmitter_addr_, 0, sizeof(transmitter_addr_));

    fetchAudioFlinger();
@@ -112,10 +113,10 @@ status_t AAH_RXPlayer::setDataSource(

    a = (a << 24) | (b << 16) | (c <<  8) | d;

    memset(&listen_addr_, 0, sizeof(listen_addr_));
    listen_addr_.sin_family      = AF_INET;
    listen_addr_.sin_port        = htons(port);
    listen_addr_.sin_addr.s_addr = htonl(a);
    memset(&data_source_addr_, 0, sizeof(data_source_addr_));
    data_source_addr_.sin_family      = AF_INET;
    data_source_addr_.sin_port        = htons(port);
    data_source_addr_.sin_addr.s_addr = htonl(a);
    data_source_set_ = true;

    return OK;
@@ -202,9 +203,9 @@ void AAH_RXPlayer::reset_l() {
    CHECK(sock_fd_ < 0);
    CHECK(!multicast_joined_);
    is_playing_ = false;
    data_source_set_ = false;
    transmitter_known_ = false;
    memset(&listen_addr_, 0, sizeof(listen_addr_));
    memset(&data_source_addr_, 0, sizeof(data_source_addr_));
    data_source_set_ = false;
}

status_t AAH_RXPlayer::setLooping(int loop) {
+11 −6
Original line number Diff line number Diff line
@@ -266,19 +266,23 @@ class AAH_RXPlayer : public MediaPlayerInterface {
    void                processRingBuffer();
    void                processCommandPacket(PacketBuffer* pb);
    bool                processGaps();
    bool                processRetransmitNAK(const uint8_t* data, size_t amt);
    void                setGapStatus(GapStatus status);
    void                cleanoutExpiredSubstreams();
    void                sendUnicastGroupJoin();
    void                sendUnicastGroupLeave();
    void                fetchAudioFlinger();

    PipeEvent           wakeup_work_thread_evt_;
    sp<ThreadWrapper>   thread_wrapper_;
    Mutex               api_lock_;
    bool                is_playing_;
    bool                data_source_set_;

    struct sockaddr_in  listen_addr_;
    int                 sock_fd_;
    struct sockaddr_in  data_source_addr_;
    bool                data_source_set_;
    bool                multicast_mode_;
    bool                multicast_joined_;
    int                 sock_fd_;

    struct sockaddr_in  transmitter_addr_;
    bool                transmitter_known_;
@@ -291,6 +295,7 @@ class AAH_RXPlayer : public MediaPlayerInterface {
    Timeout             next_retrans_req_timeout_;

    Timeout             ss_cleanout_timeout_;
    Timeout             unicast_group_report_timeout_;

    RXRingBuffer        ring_buffer_;
    SubstreamVec        substreams_;
@@ -301,13 +306,13 @@ class AAH_RXPlayer : public MediaPlayerInterface {
    sp<IAudioFlinger>   audio_flinger_;

    static const uint32_t kRTPRingBufferSize;
    static const uint32_t kRetransRequestMagic;
    static const uint32_t kFastStartRequestMagic;
    static const uint32_t kRetransNAKMagic;

    static const uint32_t kGapRerequestTimeoutMsec;
    static const uint32_t kFastStartTimeoutMsec;
    static const uint32_t kRTPActivityTimeoutMsec;
    static const uint32_t kSSCleanoutTimeoutMsec;
    static const uint32_t kGrpMemberSlowReportIntervalMsec;
    static const uint32_t kGrpMemberFastReportIntervalMsec;

    static const uint32_t INVOKE_GET_MASTER_VOLUME = 3;
    static const uint32_t INVOKE_SET_MASTER_VOLUME = 4;
+173 −65
Original line number Diff line number Diff line
@@ -28,19 +28,16 @@

#include "aah_rx_player.h"
#include "aah_tx_packet.h"
#include "utils.h"

namespace android {

const uint32_t AAH_RXPlayer::kRetransRequestMagic =
    FOURCC('T','r','e','q');
const uint32_t AAH_RXPlayer::kRetransNAKMagic =
    FOURCC('T','n','a','k');
const uint32_t AAH_RXPlayer::kFastStartRequestMagic =
    FOURCC('T','f','s','t');
const uint32_t AAH_RXPlayer::kGapRerequestTimeoutMsec = 75;
const uint32_t AAH_RXPlayer::kFastStartTimeoutMsec = 800;
const uint32_t AAH_RXPlayer::kRTPActivityTimeoutMsec = 10000;
const uint32_t AAH_RXPlayer::kSSCleanoutTimeoutMsec = 1000;
const uint32_t AAH_RXPlayer::kGrpMemberSlowReportIntervalMsec = 900;
const uint32_t AAH_RXPlayer::kGrpMemberFastReportIntervalMsec = 200;

static inline int16_t fetchInt16(uint8_t* data) {
    return static_cast<int16_t>(U16_AT(data));
@@ -82,10 +79,23 @@ void AAH_RXPlayer::stopWorkThread() {

void AAH_RXPlayer::cleanupSocket() {
    if (sock_fd_ >= 0) {
        // If we are in unicast mode, send a pair of leave requests spaced by a
        // short delay.  We send a pair to increase the probability that at
        // least one gets through.  If both get dropped, the transmitter will
        // figure it out eventually via the timeout, but we'd rather not rely on
        // that if we can avoid it.
        if (!multicast_mode_) {
            sendUnicastGroupLeave();
            usleep(20000);  // 20mSec
            sendUnicastGroupLeave();
        }

        // If we had joined a multicast group, make sure we leave it properly
        // before closing our socket.
        if (multicast_joined_) {
            int res;
            struct ip_mreq mreq;
            mreq.imr_multiaddr = listen_addr_.sin_addr;
            mreq.imr_multiaddr = data_source_addr_.sin_addr;
            mreq.imr_interface.s_addr = htonl(INADDR_ANY);
            res = setsockopt(sock_fd_,
                             IPPROTO_IP,
@@ -101,6 +111,7 @@ void AAH_RXPlayer::cleanupSocket() {
        sock_fd_ = -1;
    }

    multicast_mode_ = false;
    resetPipeline();
}

@@ -123,10 +134,27 @@ bool AAH_RXPlayer::setupSocket() {
    long flags;
    int  res, buf_size;
    socklen_t opt_size;
    uint32_t addr = ntohl(data_source_addr_.sin_addr.s_addr);
    uint16_t port = ntohs(data_source_addr_.sin_port);

    cleanupSocket();
    CHECK(sock_fd_ < 0);

    // Make sure we have a valid data source before proceeding.
    if (!data_source_set_) {
        LOGE("setupSocket called with no data source set.");
        goto bailout;
    }

    if ((addr == INADDR_ANY) || !port) {
        LOGE("setupSocket called with invalid data source (%d.%d.%d.%d:%hu)",
             IP_PRINTF_HELPER(addr), port);
        goto bailout;
    }

    // Check to see if we are in multicast RX mode or not.
    multicast_mode_ = isMulticastSockaddr(&data_source_addr_);

    // Make the socket
    sock_fd_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock_fd_ < 0) {
@@ -143,12 +171,14 @@ bool AAH_RXPlayer::setupSocket() {
        goto bailout;
    }

    // Bind to our port
    // Bind to our port.  If we are in multicast mode, we need to bind to the
    // port on which the multicast traffic will be arriving.  If we are in
    // unicast mode, then just bind to an ephemeral port.
    struct sockaddr_in bind_addr;
    memset(&bind_addr, 0, sizeof(bind_addr));
    bind_addr.sin_family = AF_INET;
    bind_addr.sin_addr.s_addr = INADDR_ANY;
    bind_addr.sin_port = listen_addr_.sin_port;
    bind_addr.sin_port = multicast_mode_ ? data_source_addr_.sin_port : 0;
    res = bind(sock_fd_,
               reinterpret_cast<const sockaddr*>(&bind_addr),
               sizeof(bind_addr));
@@ -156,17 +186,12 @@ bool AAH_RXPlayer::setupSocket() {
        uint32_t a = ntohl(bind_addr.sin_addr.s_addr);
        uint16_t p = ntohs(bind_addr.sin_port);
        LOGE("Failed to bind socket (%d) to %d.%d.%d.%d:%hu. (errno %d)",
             sock_fd_,
             (a >> 24) & 0xFF,
             (a >> 16) & 0xFF,
             (a >>  8) & 0xFF,
             (a      ) & 0xFF,
             p,
             errno);
             sock_fd_, IP_PRINTF_HELPER(a), p, errno);

        goto bailout;
    }

    // Increase our socket buffer RX size
    buf_size = 1 << 16;   // 64k
    res = setsockopt(sock_fd_,
                     SOL_SOCKET, SO_RCVBUF,
@@ -188,10 +213,12 @@ bool AAH_RXPlayer::setupSocket() {
        LOGD("RX socket buffer size is now %d bytes",  buf_size);
    }

    if (listen_addr_.sin_addr.s_addr) {
    // If we are in multicast mode, join our socket to the multicast group on
    // which we expect to receive traffic.
    if (multicast_mode_) {
        // Join the multicast group and we should be good to go.
        struct ip_mreq mreq;
        mreq.imr_multiaddr = listen_addr_.sin_addr;
        mreq.imr_multiaddr = data_source_addr_.sin_addr;
        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
        res = setsockopt(sock_fd_,
                         IPPROTO_IP,
@@ -201,6 +228,7 @@ bool AAH_RXPlayer::setupSocket() {
            LOGE("Failed to join multicast group. (errno %d)", errno);
            goto bailout;
        }

        multicast_joined_ = true;
    }

@@ -220,27 +248,46 @@ bool AAH_RXPlayer::threadLoop() {
        goto bailout;
    }

    // If we are not in multicast mode, send our first group membership report
    // right now.  Otherwise, make sure that the timeout has been canceled so we
    // don't accidentally end up sending reports when we should not.
    if (!multicast_mode_) {
        sendUnicastGroupJoin();
    } else {
        unicast_group_report_timeout_.setTimeout(-1);
    }

    while (!thread_wrapper_->exitPending()) {
        // Step 1: Wait until there is something to do.
        int gap_timeout = next_retrans_req_timeout_.msecTillTimeout();
        int ring_timeout = ring_buffer_.computeInactivityTimeout();
        int ss_cleanout_timeout = ss_cleanout_timeout_.msecTillTimeout();
        int timeout = -1;
        int tmp;

        // Time to report unicast group membership?
        if (!(tmp = unicast_group_report_timeout_.msecTillTimeout())) {
            sendUnicastGroupJoin();
            continue;
        }
        timeout = minTimeout(tmp, timeout);

        if (!ring_timeout) {
        // Ring buffer timed out?
        if (!(tmp = ring_buffer_.computeInactivityTimeout())) {
            LOGW("RTP inactivity timeout reached, resetting pipeline.");
            resetPipeline();
            continue;
        }
        timeout = minTimeout(tmp, timeout);

        if (!ss_cleanout_timeout) {
        // Time to check for expired substreams?
        if (!(tmp = ss_cleanout_timeout_.msecTillTimeout())) {
            cleanoutExpiredSubstreams();
            continue;
        }
        timeout = minTimeout(tmp, timeout);

        timeout = minTimeout(gap_timeout, timeout);
        timeout = minTimeout(ring_timeout, timeout);
        timeout = minTimeout(ss_cleanout_timeout, timeout);
        // Finally, take the next retransmit request timeout into account and
        // proceed.
        tmp = next_retrans_req_timeout_.msecTillTimeout();
        timeout = minTimeout(tmp, timeout);

        if ((0 != timeout) && (!process_more_right_now)) {
            // Set up the events to wait on.  Start with the wakeup pipe.
@@ -252,7 +299,7 @@ bool AAH_RXPlayer::threadLoop() {
            poll_fds[1].fd     = sock_fd_;
            poll_fds[1].events = POLLIN;

            // Wait for something interesing to happen.
            // Wait for something interesting to happen.
            int poll_res = poll(poll_fds, NELEM(poll_fds), timeout);
            if (poll_res < 0) {
                LOGE("Fatal error (%d,%d) while waiting on events",
@@ -325,12 +372,7 @@ bool AAH_RXPlayer::threadLoop() {
                        uint32_t a = ntohl(from.sin_addr.s_addr);
                        uint16_t p = ntohs(from.sin_port);
                        LOGV("Dropping packet from unknown transmitter"
                             " %u.%u.%u.%u:%hu",
                             ((a >> 24) & 0xFF),
                             ((a >> 16) & 0xFF),
                             ((a >>  8) & 0xFF),
                             ( a        & 0xFF),
                             p);
                             " %d.%d.%d.%d:%hu", IP_PRINTK_HELPER(a), p);

                        drop_packet = true;
                    } else {
@@ -408,36 +450,39 @@ bool AAH_RXPlayer::processRX(PacketBuffer* pb) {
    uint32_t nak_magic;
    uint16_t seq_no;
    uint32_t epoch;

    // Every packet either starts with an RTP header which is at least 12 bytes
    // long or is a retry NAK which is 14 bytes long.  If there are fewer than
    // 12 bytes here, this cannot be a proper RTP packet.
    if (amt < 12) {
        LOGV("Dropping packet, too short to contain RTP header (%u bytes)",
    bool     ret_val = true;

    // Every packet should be either a C&C NAK packet, or a TRTP packet.  The
    // shortest possible packet is a group membership NAK, which is only 4 bytes
    // long.  If our RXed packet is not at least 4 bytes long, then this is junk
    // and should be tossed.
    if (amt < 4) {
        LOGV("Dropping packet, too short to contain any valid data (%u bytes)",
             static_cast<uint32_t>(amt));
        goto drop_packet;
    }

    // Check to see if this is the special case of a NAK packet.
    // Check to see if this is a special C&C NAK packet.
    nak_magic = ntohl(*(reinterpret_cast<uint32_t*>(data)));
    if (nak_magic == kRetransNAKMagic) {
        // Looks like a NAK packet; make sure its long enough.

        if (amt < static_cast<ssize_t>(sizeof(RetransRequest))) {
            LOGV("Dropping packet, too short to contain NAK payload (%u bytes)",
                 static_cast<uint32_t>(amt));
    switch (nak_magic) {
        case TRTPPacket::kCNC_NakRetryRequestID:
            ret_val = processRetransmitNAK(data, amt);
            goto drop_packet;
        }

        SeqNoGap gap;
        RetransRequest* rtr = reinterpret_cast<RetransRequest*>(data);
        gap.start_seq_ = ntohs(rtr->start_seq_);
        gap.end_seq_   = ntohs(rtr->end_seq_);

        LOGV("Process NAK for gap at [%hu, %hu]", gap.start_seq_, gap.end_seq_);
        ring_buffer_.processNAK(&gap);
        case TRTPPacket::kCNC_NakJoinGroupID:
            LOGI("Received group join NAK; signalling error and shutting down");
            ret_val = false;
            goto drop_packet;
    }

        return true;
    // Every non C&C packet starts with an RTP header which is at least 12 bytes
    // If there are fewer than 12 bytes here, this cannot be a proper RTP
    // packet.
    if (amt < 12) {
        LOGV("Dropping packet, too short to contain RTP header (%u bytes)",
             static_cast<uint32_t>(amt));
        goto drop_packet;
    }

    // According to the TRTP spec, version should be 2, padding should be 0,
@@ -476,7 +521,7 @@ bool AAH_RXPlayer::processRX(PacketBuffer* pb) {

drop_packet:
    PacketBuffer::destroy(pb);
    return true;
    return ret_val;
}

void AAH_RXPlayer::processRingBuffer() {
@@ -790,23 +835,19 @@ bool AAH_RXPlayer::processGaps() {
        // Send the request.
        RetransRequest req;
        uint32_t magic  = (kGS_FastStartGap == gap_status)
                        ? kFastStartRequestMagic
                        : kRetransRequestMagic;
                        ? TRTPPacket::kCNC_FastStartRequestID
                        : TRTPPacket::kCNC_RetryRequestID;
        req.magic_      = htonl(magic);
        req.mcast_ip_   = listen_addr_.sin_addr.s_addr;
        req.mcast_port_ = listen_addr_.sin_port;
        req.mcast_ip_   = data_source_addr_.sin_addr.s_addr;
        req.mcast_port_ = data_source_addr_.sin_port;
        req.start_seq_  = htons(gap.start_seq_);
        req.end_seq_    = htons(gap.end_seq_);

        {
            uint32_t a = ntohl(transmitter_addr_.sin_addr.s_addr);
            uint16_t p = ntohs(transmitter_addr_.sin_port);
            LOGV("Sending to transmitter %u.%u.%u.%u:%hu",
                    ((a >> 24) & 0xFF),
                    ((a >> 16) & 0xFF),
                    ((a >>  8) & 0xFF),
                    ( a        & 0xFF),
                    p);
            LOGV("Sending to transmitter %d.%d.%d.%d:%hu",
                 IP_PRINTF_HELPER(a), p);
        }

        int res = sendto(sock_fd_, &req, sizeof(req), 0,
@@ -828,6 +869,24 @@ bool AAH_RXPlayer::processGaps() {
    return false;
}

bool AAH_RXPlayer::processRetransmitNAK(const uint8_t* data, size_t amt) {
    if (amt < static_cast<ssize_t>(sizeof(RetransRequest))) {
        LOGV("Dropping packet, too short to contain NAK payload (%u bytes)",
             static_cast<uint32_t>(amt));
        return true;
    }

    SeqNoGap gap;
    const RetransRequest* rtr = reinterpret_cast<const RetransRequest*>(data);
    gap.start_seq_ = ntohs(rtr->start_seq_);
    gap.end_seq_   = ntohs(rtr->end_seq_);

    LOGI("Process NAK for gap at [%hu, %hu]", gap.start_seq_, gap.end_seq_);
    ring_buffer_.processNAK(&gap);

    return true;
}

void AAH_RXPlayer::setGapStatus(GapStatus status) {
    current_gap_status_ = status;

@@ -871,4 +930,53 @@ void AAH_RXPlayer::cleanoutExpiredSubstreams() {
    ss_cleanout_timeout_.setTimeout(kSSCleanoutTimeoutMsec);
}

void AAH_RXPlayer::sendUnicastGroupJoin() {
    if (!multicast_mode_ && (sock_fd_ >= 0)) {
        uint32_t tag = htonl(TRTPPacket::kCNC_JoinGroupID);
        uint32_t a = ntohl(data_source_addr_.sin_addr.s_addr);
        uint16_t p = ntohs(data_source_addr_.sin_port);

        LOGV("Sending group join to transmitter %d.%d.%d.%d:%hu",
             IP_PRINTF_HELPER(a), p);

        int res = sendto(sock_fd_, &tag, sizeof(tag), 0,
                         reinterpret_cast<struct sockaddr*>(&data_source_addr_),
                         sizeof(data_source_addr_));
        if (res < 0) {
            LOGW("Error sending group join to transmitter %d.%d.%d.%d:%hu"
                 " (errno %d)", IP_PRINTF_HELPER(a), p, errno);
        }

        // Reset the membership report timeout.  Use our fast timeout until we
        // have heard back from our transmitter at least once.
        unicast_group_report_timeout_.setTimeout(transmitter_known_
                ?  kGrpMemberSlowReportIntervalMsec
                :  kGrpMemberFastReportIntervalMsec);
    } else {
        LOGE("Attempted to send unicast group membership report while"
             " multicast_mode = %s and sock_fd = %d",
             multicast_mode_ ? "true" : "false", sock_fd_);
        unicast_group_report_timeout_.setTimeout(-1);
    }
}

void AAH_RXPlayer::sendUnicastGroupLeave() {
    if (!multicast_mode_ && (sock_fd_ >= 0)) {
        uint32_t tag = htonl(TRTPPacket::kCNC_LeaveGroupID);
        uint32_t a = ntohl(data_source_addr_.sin_addr.s_addr);
        uint16_t p = ntohs(data_source_addr_.sin_port);

        LOGI("Sending group leave to transmitter %d.%d.%d.%d:%hu",
             IP_PRINTF_HELPER(a), p);

        int res = sendto(sock_fd_, &tag, sizeof(tag), 0,
                         reinterpret_cast<struct sockaddr*>(&data_source_addr_),
                         sizeof(data_source_addr_));
        if (res < 0) {
            LOGW("Error sending group leave to transmitter %d.%d.%d.%d:%hu"
                 " (errno %d)", IP_PRINTF_HELPER(a), p, errno);
        }
    }
}

}  // namespace android
+14 −21
Original line number Diff line number Diff line
@@ -114,13 +114,6 @@ const size_t AAH_TXGroup::kInitialActiveTXGroupsCapacity = 4;
const size_t AAH_TXGroup::kMaxAllowedPlayerClients = 4;
const size_t AAH_TXGroup::kInitialPlayerClientCapacity = 2;

const uint32_t AAH_TXGroup::kCNC_RetryRequestID     = 'Treq';
const uint32_t AAH_TXGroup::kCNC_FastStartRequestID = 'Tfst';
const uint32_t AAH_TXGroup::kCNC_NakRetryRequestID  = 'Tnak';
const uint32_t AAH_TXGroup::kCNC_JoinGroupID        = 'Tjgp';
const uint32_t AAH_TXGroup::kCNC_LeaveGroupID       = 'Tlgp';
const uint32_t AAH_TXGroup::kCNC_NakJoinGroupID     = 'Tngp';

Mutex                               AAH_TXGroup::sLock;
Vector < sp<AAH_TXGroup> >          AAH_TXGroup::sActiveTXGroups;
sp<AAH_TXGroup::CmdAndControlRXer>  AAH_TXGroup::mCmdAndControlRXer;
@@ -687,12 +680,12 @@ void AAH_TXGroup::handleRequests() {
        uint32_t id = U32_AT(request);
        size_t minSize = 0;
        switch(id) {
            case kCNC_RetryRequestID:
            case kCNC_FastStartRequestID:
            case TRTPPacket::kCNC_RetryRequestID:
            case TRTPPacket::kCNC_FastStartRequestID:
                minSize = sizeof(RetryPacket);
                break;
            case kCNC_JoinGroupID:
            case kCNC_LeaveGroupID:
            case TRTPPacket::kCNC_JoinGroupID:
            case TRTPPacket::kCNC_LeaveGroupID:
                minSize = sizeof(uint32_t);
                break;
        }
@@ -705,19 +698,19 @@ void AAH_TXGroup::handleRequests() {
        }

        switch(id) {
            case kCNC_RetryRequestID:
            case TRTPPacket::kCNC_RetryRequestID:
                handleRetryRequest(request, &srcAddr, false);
                break;

            case kCNC_FastStartRequestID:
            case TRTPPacket::kCNC_FastStartRequestID:
                handleRetryRequest(request, &srcAddr, true);
                break;

            case kCNC_JoinGroupID:
            case TRTPPacket::kCNC_JoinGroupID:
                handleJoinGroup(&srcAddr);
                break;

            case kCNC_LeaveGroupID:
            case TRTPPacket::kCNC_LeaveGroupID:
                handleLeaveGroup(&srcAddr);
                break;

@@ -755,7 +748,7 @@ void AAH_TXGroup::handleRetryRequest(const uint8_t* req,
        // we have an empty retry buffer for this group, so NAK the entire
        // request
        RetryPacket nak = *req_overlay;
        nak.id = htonl(kCNC_NakRetryRequestID);
        nak.id = htonl(TRTPPacket::kCNC_NakRetryRequestID);

        if (sendto(mSocket, &nak, sizeof(nak), 0,
                   src, sizeof(*src_addr)) < 0) {
@@ -796,7 +789,7 @@ void AAH_TXGroup::handleRetryRequest(const uint8_t* req,
    if (startIndex == -1 && endIndex == -1) {
        // no part of the request range is found in the retry buffer
        RetryPacket nak = *req_overlay;
        nak.id = htonl(kCNC_NakRetryRequestID);
        nak.id = htonl(TRTPPacket::kCNC_NakRetryRequestID);

        if (sendto(mSocket, &nak, sizeof(nak), 0,
                   src, sizeof(*src_addr)) < 0) {
@@ -810,7 +803,7 @@ void AAH_TXGroup::handleRetryRequest(const uint8_t* req,
    if (startIndex == -1) {
        // NAK a subrange at the front of the request range
        RetryPacket nak = *req_overlay;
        nak.id = htonl(kCNC_NakRetryRequestID);
        nak.id = htonl(TRTPPacket::kCNC_NakRetryRequestID);
        nak.seqEnd = htons(retryFirstSeq - 1);

        if (sendto(mSocket, &nak, sizeof(nak), 0,
@@ -824,7 +817,7 @@ void AAH_TXGroup::handleRetryRequest(const uint8_t* req,
    } else if (endIndex == -1) {
        // NAK a subrange at the back of the request range
        RetryPacket nak = *req_overlay;
        nak.id = htonl(kCNC_NakRetryRequestID);
        nak.id = htonl(TRTPPacket::kCNC_NakRetryRequestID);
        nak.seqStart = htons(retryLastSeq + 1);

        if (sendto(mSocket, &nak, sizeof(nak), 0,
@@ -879,7 +872,7 @@ void AAH_TXGroup::handleJoinGroup(const struct sockaddr_in* src_addr) {
    // before proceeding.  If not, send a NAK back so it knows to signal an
    // error to its application level.
    if (mUnicastTargets.size() >= kMaxAllowedUnicastTargets) {
        uint32_t nak_payload = htonl(kCNC_NakJoinGroupID);
        uint32_t nak_payload = htonl(TRTPPacket::kCNC_NakJoinGroupID);

        if (sendto(mSocket, &nak_payload, sizeof(nak_payload),
                   0, src, sizeof(*src_addr)) < 0) {
@@ -898,7 +891,7 @@ void AAH_TXGroup::handleJoinGroup(const struct sockaddr_in* src_addr) {
    // application level.
    sp<UnicastTarget> ut = new UnicastTarget(*src_addr);
    if ((ut == NULL) || (mUnicastTargets.add(ut) < 0)) {
        uint32_t nak_payload = htonl(kCNC_NakJoinGroupID);
        uint32_t nak_payload = htonl(TRTPPacket::kCNC_NakJoinGroupID);

        if (sendto(mSocket, &nak_payload, sizeof(nak_payload),
                   0, src, sizeof(*src_addr)) < 0) {
+0 −10
Original line number Diff line number Diff line
@@ -28,9 +28,6 @@
#include "aah_tx_packet.h"
#include "utils.h"

#define IP_PRINTF_HELPER(a) ((a >> 24) & 0xFF), ((a >> 16) & 0xFF), \
                            ((a >>  8) & 0xFF),  (a        & 0xFF)

namespace android {

class AAH_TXPlayer;
@@ -318,13 +315,6 @@ class AAH_TXGroup : public virtual RefBase {
    static const size_t kMaxAllowedPlayerClients;
    static const size_t kInitialPlayerClientCapacity;

    static const uint32_t kCNC_RetryRequestID;
    static const uint32_t kCNC_FastStartRequestID;
    static const uint32_t kCNC_NakRetryRequestID;
    static const uint32_t kCNC_JoinGroupID;
    static const uint32_t kCNC_LeaveGroupID;
    static const uint32_t kCNC_NakJoinGroupID;

    DISALLOW_EVIL_CONSTRUCTORS(AAH_TXGroup);
};

Loading