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; } }
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; }
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; } }
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(); }
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); }
void stack::call::terminateLocked(void) { if(state != INITIAL) set(TERMINATE, 'q', "bye"); disconnectLocked(); }