Ejemplo n.º 1
0
void stack::call::expired(void)
{
    linked_pointer<segment> sp;

    switch(state) {
    case TRANSFER:
    case HOLDING:   // hold-recall timer expired...

    case RINGING:   // re-generate ring event to origination...
                    // also controls call-forward no-answer timing...

            if(answering == 1 && forwarding) {
                forwarding = "na";
                cancelLocked();
                if(stack::forward(this)) {
                    arm(1000);
                    reply_source(SIP_CALL_IS_BEING_FORWARDED);
                    return;
                }
                disconnectLocked();
                break;
            }
            if(answering)
                --answering;
            arm(1000);
            reply_source(SIP_RINGING);
            return;
    case REDIRECT:  // FIXME: add refer select of next segment if list....

    case RINGBACK:
    case BUSY:      // invite expired
    case JOINED:    // active call session expired without re-invite
    case ANSWERED:
    case REORDER:
    case TRYING:
    case FAILED:
            disconnectLocked();
            break;
    case FINAL:     // session expired that expects to be recycled.
    case INITIAL:   // never used session recycled.
        // The call record is garbage collected
        shell::debug(4, "expiring call %08x:%u\n", source->sequence, source->cid);
        stack::destroy(this);
        return;
    default:
        break;
    }
}
Ejemplo n.º 2
0
void stack::call::bye(thread *thread, session *s)
{
    bool closing = false;

    Mutex::protect(this);
    s->tid = 0; // cleared already....

    switch(state) {
    case JOINED:
    case ANSWERED:
    case HOLDING:
        if(s == source || s == target) {
            s->state = session::CLOSED;
            terminateLocked();
        }
        break;
    case TRYING:
    case RINGING:
    case RINGBACK:
        if(s == source) {
            s->state = session::CLOSED;
            disconnectLocked();
        }
        else
            closing = true;
    default:
        break;
    }
    Mutex::release(this);
    if(closing)
        stack::close(s);
}
status_t Camera3Stream::tearDown() {
    ATRACE_CALL();
    Mutex::Autolock l(mLock);

    status_t res = OK;

    // This function should be only called when the stream is configured.
    if (mState != STATE_CONFIGURED) {
        ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
                "CONFIGURED state %d", __FUNCTION__, mId, mState);
        return INVALID_OPERATION;
    }

    // If any buffers have been handed to the HAL, the stream cannot be torn down.
    if (getHandoutOutputBufferCountLocked() > 0) {
        ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
                __FUNCTION__, mId);
        return INVALID_OPERATION;
    }

    // Free buffers by disconnecting and then reconnecting to the buffer queue
    // Only unused buffers will be dropped immediately; buffers that have been filled
    // and are waiting to be acquired by the consumer and buffers that are currently
    // acquired will be freed once they are released by the consumer.

    res = disconnectLocked();
    if (res != OK) {
        if (res == -ENOTCONN) {
            // queue has been disconnected, nothing left to do, so exit with success
            return OK;
        }
        ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
                __FUNCTION__, mId, strerror(-res), res);
        return res;
    }

    mState = STATE_IN_CONFIG;

    res = configureQueueLocked();
    if (res != OK) {
        ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
                __FUNCTION__, mId, strerror(-res), res);
        mState = STATE_ERROR;
        return res;
    }

    // Reset prepared state, since we've reconnected to the queue and can prepare again.
    mPrepared = false;
    mStreamUnpreparable = false;

    mState = STATE_CONFIGURED;

    return OK;
}
Ejemplo n.º 4
0
void stack::call::relay(thread *thread, session *s)
{
    assert(thread != NULL);
    assert(s != NULL);

    int status = thread->sevent->response->status_code;
    int tid = -1;
    voip::body_t body = NULL;
    voip::msg_t reply = NULL;
    voip::context_t ctx = stack::sip.out_context;

    Mutex::protect(this);
    if(s == source && target) {
        tid = target->tid;
        ctx = target->context;
    }
    else if(s == target) {
        tid = source->tid;
        ctx = source->context;
    }

    osip_message_get_body(thread->sevent->response, 0, &body);

    switch(s->state) {
    case session::REFER:
        if(status == SIP_ACCEPTED) {
            set(TRANSFER, 'x', "transfer");
            disconnectLocked();
            Mutex::release(this);
            return;
        }
        s->state = session::OPEN;
        break;
    case session::REINVITE:
        if(status != SIP_ACCEPTED)
            s->state = session::OPEN;
    default:
        break;
    }
    Mutex::release(this);
    if(tid < 1)
        return;

    if(voip::make_answer_response(ctx, tid, status, &reply)) {
        if(stack::sip_protocol == IPPROTO_UDP)
            voip::server_requires(reply, "100rel");
        voip::header(reply, "RSeq", "1");
        if(body && body->body) 
            voip::attach(reply, SDP_BODY, body->body); 
        voip::send_answer_response(ctx, tid, status, reply);
    }
}
status_t Camera3Stream::disconnect() {
    ATRACE_CALL();
    Mutex::Autolock l(mLock);
    ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
    status_t res = disconnectLocked();

    if (res == -ENOTCONN) {
        // "Already disconnected" -- not an error
        return OK;
    } else {
        return res;
    }
}
Ejemplo n.º 6
0
void stack::call::closingLocked(session *s)
{
    assert(s != NULL);

    if(invited)
        --invited;

    if(!invited) {
        if(!stack::forward(this))
            disconnectLocked();
        if(state == RINGING) {
            arm(1000);
            reply_source(SIP_CALL_IS_BEING_FORWARDED);
        }
    }
}
status_t Camera3IOStreamBase::configureQueueLocked() {
    status_t res;

    switch (mState) {
        case STATE_IN_RECONFIG:
            res = disconnectLocked();
            if (res != OK) {
                return res;
            }
            break;
        case STATE_IN_CONFIG:
            // OK
            break;
        default:
            ALOGE("%s: Bad state: %d", __FUNCTION__, mState);
            return INVALID_OPERATION;
    }

    return OK;
}
Camera3InputStream::~Camera3InputStream() {
    disconnectLocked();
}
Camera3IOStreamBase::~Camera3IOStreamBase() {
    disconnectLocked();
}
Ejemplo n.º 10
0
void stack::call::busy(thread *thread, session *s)
{
    assert(thread != NULL);

    Mutex::protect(this);
    switch(state) {
    case INITIAL:
        if(!s) {
            set(BUSY, 'b', "busy");
            disconnectLocked();
            Mutex::release(this);
            return;
        }
    case FINAL:
    case HOLDING:
    case JOINED:
    case ANSWERED:
    case FAILED:
        Mutex::release(this);
        return;
    default:
        break;
    }

    if(s && s != source) {
        if(s->state == session::RING)
            --ringing;
        if(s->state != session::BUSY) {
            ++ringbusy;
            s->state = session::BUSY;
        }
    }
    else if(!s)
        ++ringbusy;

    switch(state) {
    case INITIAL:
    case RINGING:
    case RINGBACK:
        // we goto busy in this special case, otherwise stack::close handles na
        if(!ringing && ringbusy && invited == 1 && s != source) {
            if(forwarding) {
                forwarding = "busy";
                if(s)
                    s->state = session::CLOSED;
                if(s && !s->closed) {
                    registry::decUse(s->reg, stats::OUTGOING);
                    s->closed = true;
                }
                ringbusy = invited = 0;
                if(stack::forward(this)) {
                    if(state == RINGING)
                        arm(1000);
                    Mutex::release(this);
                    if(state == RINGING)
                        reply_source(SIP_CALL_IS_BEING_FORWARDED);
                    return;
                }
            }
            set(BUSY, 'b', "busy");
            disconnectLocked();
        }
    default:
        break;
    }

    Mutex::release(this);
    if(s)
        stack::close(s);
    else
        stack::close(source);
}
Ejemplo n.º 11
0
void stack::call::terminateLocked(void)
{
    if(state != INITIAL)
        set(TERMINATE, 'q', "bye");
    disconnectLocked();
}