// must be write-locked, SessionManager must be read-locked void CallManager::EndCall(Connection *sqlCon, unsigned int call_id) { Call *call = getCall(call_id); if (!call) return; call->lock(); //call->sendCallStatuses(); if (call->tarificate(sqlCon)) { log(LOG_FATAL, "Error tarficating call[%d].", call_id); } call->DBwrite(sqlCon); if (call->getState() == ACTIVE || call->getState() == END) { if (User::CheckNeedMark(sqlCon, call->getClient(), call->getTranslator())) { Session *cs = sManager->findSessionByUser(call->getClient()); if (cs) { struct timeval tv; gettimeofday(&tv, 0); unsigned long time = tv.tv_sec*1000 + tv.tv_usec/1000; cs->sendPacket_MarkRequest(call->getTranslator(), call->getTranslatorName(), time); } } } call->unlock(); log(LOG_VERBOSE, "EndCall[%d->%d]: accounted=%d cost=%d.", call->getClient(), call->getTranslator(), call->getAccountedTime(), call->getCost()); removeCall(call_id); delete call; }
int CallManager::currentCallNum() { int num = 0; for (int i=0; i<calls.size(); i++) { Call *call = calls[i]; if (call->getState() == ACTIVE) num++; } return num; }
// remove timeouted and unconfirmed calls // must be locked; void CallManager::MaintainCalls(Connection *sqlCon) { for (size_t i=0; i<calls.size(); i++) { Call *call = calls[i]; if (PhoneCall *pcall = dynamic_cast<PhoneCall *>(call)) if ((call->getState() == ACTIVE && call->getStartTime() + SessionManager::getOptions().Timeout_CallStatus < time(0)) || (pcall->getState() == AWAIT && pcall->getRequestTime() + SessionManager::getOptions().Timeout_CallRequest < time(0)) || (pcall->getState() == CONFIRMED && pcall->getConfirmTime() + SessionManager::getOptions().Timeout_CallConfirm < time(0))) { log(LOG_VERBOSE, "MaintainCalls: deleting call %d[%d->%d] with timeouted confirmation.", call->getID(), call->getClient(), call->getTranslator()); call->sendTimeouts(); EndCall(sqlCon, call->getID()); } } }