CallInfo* CallList::find(const CallEndpoint* call) { ObjList* l = m_calls.skipNull(); for (; l; l = l->skipNext()) { CallInfo* info = static_cast<CallInfo*>(l->get()); if (info->call() == call) return info; } return 0; }
bool MultiRouter::msgDisconnected(Message& msg, CallInfo& info) { info.copyParams(msg,true,"reason","error",0); Message* m = buildExecute(info,msg.getBoolValue("reroute")); if (m) { m->userData(info.call()); Engine::enqueue(m); return true; } return false; }
bool MultiRouter::received(Message& msg, int id) { CallEndpoint* call = static_cast<CallEndpoint*>(msg.userObject(YATOM("CallEndpoint"))); bool first = false; CallInfo* info = 0; String chanid(msg.getValue("id")); Lock lock(this); if (call) info = m_list.find(call); if (info) { if (*info != chanid) { Debug(DebugGoOn,"Channel mismatch! call=%p id='%s' stored='%s'", call,chanid.c_str(),info->c_str()); return false; } } else info = m_list.find(chanid); if (info) { if (!call) call = info->call(); else if (!info->call()) info->setCall(call); else if (info->call() != call) { Debug(DebugGoOn,"Channel mismatch! id='%s' call=%p stored=%p", chanid.c_str(),call,info->call()); return false; } } else if ((id == Route) || (id == Execute)) { info = new CallInfo(chanid,call); info->copyParams(msg,false,"module","address","billid","caller","called","callername",0); m_list.append(info); first = true; DDebug(DebugInfo,"MultiRouter built '%s' @ %p for %p", chanid.c_str(),info,call); } else return false; DDebug(DebugAll,"MultiRouter::received '%s' for '%s' info=%p call=%p", msg.c_str(),chanid.c_str(),info,call); switch (id) { case Route: return msgRoute(msg,*info,first); case Execute: if (!call) return false; return msgExecute(msg,*info,first); case Disconnected: return msgDisconnected(msg,*info); case Hangup: info->clearCall(); msgHangup(msg,*info); m_list.remove(info); DDebug(DebugInfo,"MultiRouter destroyed '%s' @ %p",info->c_str(),info); info->destruct(); break; default: Debug(DebugFail,"Invalid id %d in MultiRouter::received()",id); } return false; }