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

Commit f3d2bdf7 authored by Andreas Huber's avatar Andreas Huber
Browse files

Various fixes to improve resilience of the rtsp stack against spurious errors instead of asserting.

Change-Id: Idbec5996ed0675c70e911b9c0514961fea099fb4
parent 4d8f66bc
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -764,7 +764,11 @@ int64_t APacketSource::getQueueDurationUs(bool *eos) {
    int64_t lastTimeUs;
    CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));

    CHECK_GE(lastTimeUs, firstTimeUs);
    if (lastTimeUs < firstTimeUs) {
        LOG(ERROR) << "Huh? Time moving backwards? "
                   << firstTimeUs << " > " << lastTimeUs;
        return 0;
    }

    return lastTimeUs - firstTimeUs;
}
+37 −12
Original line number Diff line number Diff line
@@ -175,19 +175,38 @@ void ARTSPConnection::onConnect(const sp<AMessage> &msg) {

    mState = CONNECTING;

    mSocket = socket(AF_INET, SOCK_STREAM, 0);

    MakeSocketBlocking(mSocket, false);

    AString url;
    CHECK(msg->findString("url", &url));

    sp<AMessage> reply;
    CHECK(msg->findMessage("reply", &reply));

    AString host, path;
    unsigned port;
    CHECK(ParseURL(url.c_str(), &host, &port, &path));
    if (!ParseURL(url.c_str(), &host, &port, &path)) {
        LOG(ERROR) << "Malformed rtsp url " << url;

        reply->setInt32("result", ERROR_MALFORMED);
        reply->post();

        mState = DISCONNECTED;
        return;
    }

    struct hostent *ent = gethostbyname(host.c_str());
    CHECK(ent != NULL);
    if (ent == NULL) {
        LOG(ERROR) << "Unknown host " << host;

        reply->setInt32("result", -ENOENT);
        reply->post();

        mState = DISCONNECTED;
        return;
    }

    mSocket = socket(AF_INET, SOCK_STREAM, 0);

    MakeSocketBlocking(mSocket, false);

    struct sockaddr_in remote;
    memset(remote.sin_zero, 0, sizeof(remote.sin_zero));
@@ -198,9 +217,6 @@ void ARTSPConnection::onConnect(const sp<AMessage> &msg) {
    int err = ::connect(
            mSocket, (const struct sockaddr *)&remote, sizeof(remote));

    sp<AMessage> reply;
    CHECK(msg->findMessage("reply", &reply));

    reply->setInt32("server-ip", ntohl(remote.sin_addr.s_addr));

    if (err < 0) {
@@ -337,13 +353,20 @@ void ARTSPConnection::onSendRequest(const sp<AMessage> &msg) {

        if (n == 0) {
            // Server closed the connection.
            TRESPASS();
            LOG(ERROR) << "Server unexpectedly closed the connection.";

            reply->setInt32("result", ERROR_IO);
            reply->post();
            return;
        } else if (n < 0) {
            if (errno == EINTR) {
                continue;
            }

            TRESPASS();
            LOG(ERROR) << "Error sending rtsp request.";
            reply->setInt32("result", -errno);
            reply->post();
            return;
        }

        numBytesSent += (size_t)n;
@@ -415,13 +438,15 @@ status_t ARTSPConnection::receive(void *data, size_t size) {
        ssize_t n = recv(mSocket, (uint8_t *)data + offset, size - offset, 0);
        if (n == 0) {
            // Server closed the connection.
            LOG(ERROR) << "Server unexpectedly closed the connection.";
            return ERROR_IO;
        } else if (n < 0) {
            if (errno == EINTR) {
                continue;
            }

            TRESPASS();
            LOG(ERROR) << "Error reading rtsp response.";
            return -errno;
        }

        offset += (size_t)n;
+42 −23
Original line number Diff line number Diff line
@@ -209,8 +209,9 @@ struct MyHandler : public AHandler {
                                response->mContent->data(),
                                response->mContent->size());

                        CHECK(mSessionDesc->isValid());

                        if (!mSessionDesc->isValid()) {
                            result = ERROR_MALFORMED;
                        } else {
                            ssize_t i = response->mHeaders.indexOfKey("content-base");
                            if (i >= 0) {
                                mBaseURL = response->mHeaders.valueAt(i);
@@ -227,6 +228,7 @@ struct MyHandler : public AHandler {
                            setupTrack(1);
                        }
                    }
                }

                if (result != OK) {
                    sp<AMessage> reply = new AMessage('disc', id());
@@ -333,13 +335,17 @@ struct MyHandler : public AHandler {
                    sp<ARTSPResponse> response =
                        static_cast<ARTSPResponse *>(obj.get());

                    CHECK_EQ(response->mStatusCode, 200u);

                    if (response->mStatusCode != 200) {
                        result = UNKNOWN_ERROR;
                    } else {
                        parsePlayResponse(response);

                        sp<AMessage> timeout = new AMessage('tiou', id());
                        timeout->post(kStartupTimeoutUs);
                } else {
                    }
                }

                if (result != OK) {
                    sp<AMessage> reply = new AMessage('disc', id());
                    mConn->disconnect(reply);
                }
@@ -477,6 +483,11 @@ struct MyHandler : public AHandler {

                uint32_t seqNum = (uint32_t)accessUnit->int32Data();

                if (mSeekPending) {
                    LOG(INFO) << "we're seeking, dropping stale packet.";
                    break;
                }

                if (seqNum < track->mFirstSeqNumInSegment) {
                    LOG(INFO) << "dropping stale access-unit "
                              << "(" << seqNum << " < "
@@ -600,18 +611,26 @@ struct MyHandler : public AHandler {
                LOG(INFO) << "PLAY completed with result "
                     << result << " (" << strerror(-result) << ")";

                CHECK_EQ(result, (status_t)OK);

                if (result == OK) {
                    sp<RefBase> obj;
                    CHECK(msg->findObject("response", &obj));
                    sp<ARTSPResponse> response =
                        static_cast<ARTSPResponse *>(obj.get());

                CHECK_EQ(response->mStatusCode, 200u);

                    if (response->mStatusCode != 200) {
                        result = UNKNOWN_ERROR;
                    } else {
                        parsePlayResponse(response);

                        LOG(INFO) << "seek completed.";
                    }
                }

                if (result != OK) {
                    LOG(ERROR) << "seek failed, aborting.";
                    (new AMessage('abor', id()))->post();
                }

                mSeekPending = false;
                break;
            }