📄 trunk.cpp
字号:
// Copyright (C) 2000 Open Source Telecom Corporation.// // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.#include <assert.h>#include <config.h>#include <debug.h>#include "server.h"#include "trunk.h"#include "session.h"Service::Service(Trunk *trk){ trunk = trk; device = trk->getDevice(); driver = trk->getDriver();}void Service::endService(void){ trunk->setExiting();}Trunk::Trunk(Runmap *map, char *scr, int dev, Session *s) : Trunkmap(map, scr), Mutex(){ char *cp; struct phone_capability *cap; setCurrent("STARTING..."); device = dev; endTimer(); session = s;#ifdef IXJ_DRIVER driver = ixj_driver;#else driver = generic_driver;#endif service = NULL; cap_count = ioctl(dev, PHONE_CAPABILITIES); debug(6, "read %d capabilities for port %d", cap_count, id); cap_list = new struct phone_capability[cap_count]; ioctl(dev, PHONE_CAPABILITIES_LIST, cap_list); cap = getCapability(vendor); if(cap) { syslog(LOG_INFO, "found %s on port %d", cap->desc, id); switch(cap->cap) {#ifdef IXJ_DRIVER case PHONE_VENDOR_IXJ: driver = ixj_driver; break;#endif } } else { syslog(LOG_NOTICE, "found generic phone device on port %d", id); driver = generic_driver; } cp = getkeylast(keyphone, "wink"); if(cp) ioctl(device, PHONE_WINK_DURATION, atoi(cp)); switch(driver) {#ifdef IXJ_DRIVER case ixj_driver: ioctl(device, IXJCTL_PORT, PORT_PSTN); setHandler((handler_t)&Trunk::Idle); if(!ioctl(device, IXJCTL_PSTN_LINETEST)) { syslog(LOG_WARNING, "PSTN failed for port %d", id); setHandler((handler_t)&Trunk::Busy); } break;#endif default: setHandler((handler_t)&Trunk::Idle); }}Trunk::~Trunk() { if(cap_list) delete cap_list; endTimer(); resetAudio(); resetThreads(); ioctl(device, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK); switch(driver) {#ifdef IXJ_DRIVER case ixj_driver: ioctl(device, IXJCTL_PORT, PORT_POTS); break;#endif } close(device);}void Trunk::resetThreads(void){ if(mailbox) { delete mailbox; mailbox = NULL; } if(service) { delete service; service = NULL; } if(waitpid) { kill(waitpid, SIGHUP); waitpid = 0; }}void Trunk::resetAudio(void){ switch(driver) {#ifdef IXJ_DRIVER case ixj_driver: ioctl(device, IXJCTL_AEC_STOP); break;#endif } ioctl(device, PHONE_PLAY_STOP); ioctl(device, PHONE_REC_STOP);}void Trunk::PostMessage(EventRecord *er){ switch(er->event) { case PH_EVENT_TIMER_EXPIRED: if(!porttimer.tv_usec && !porttimer.tv_sec) return; break; case PH_EVENT_DTMF_DIGIT: if(!dtmf) return; break; } (this->*handler)(er);}void Trunk::setHandler(handler_t h){ EventRecord e; e.event = UM_EVENT_ENTER_STATE; e.p1 = 0; e.p2 = 0; handler = h; //assert(0); PostMessage(&e);}void Trunk::exitModule(char *errmsg, int id){ EventRecord e; e.event = UM_EVENT_EXIT_MODULE; e.p1 = (long)errmsg; e.p2 = id; PostMessage(&e);}void Trunk::scrHangup(void){ if(trap && waitpid) waitpid = 0; trap = false; setHandler((handler_t)&Trunk::Idle);}void Trunk::scrStop(void){ EventRecord e; e.event = UM_EVENT_STOP_STATE; e.p1 = 0; e.p2 = 0; PostMessage(&e);} void Trunk::setDTMF(void){ if(dtmf) return; dtmf = true;// vpb_enable_event(hTrk, VPB_MDTMF); }void Trunk::endDTMF(void){ if(!dtmf) return; dtmf = false;// vpb_disable_event(hTrk, VPB_MDTMF);}void Trunk::setTimer(long timeout){ int secs = timeout / 1000; int usecs = (timeout % 1000) * 1000; gettimeofday(&porttimer, NULL); porttimer.tv_usec += usecs; if(porttimer.tv_usec > 1000000l) { ++porttimer.tv_sec; porttimer.tv_usec %= 1000000l; } porttimer.tv_sec += secs; session->Update(1);}long Trunk::getTimer(void){ struct timeval now; long diff; if(!porttimer.tv_sec && !porttimer.tv_usec) return -1l; gettimeofday(&now, NULL); diff = (porttimer.tv_sec - now.tv_sec) * 1000l; diff += (porttimer.tv_usec - now.tv_usec) / 1000l; if(diff < 0) return 0l; return diff;}void Trunk::endTimer(void){ porttimer.tv_usec = porttimer.tv_sec = 0l;}void Trunk::setExiting(void){ if(!session) return; session->Exiting(device); sleep(60);}struct phone_capability *Trunk::getCapability(phone_cap id, int sub){ int cap; for(cap = 0; cap < cap_count; ++cap) { if(cap_list[cap].captype != id) continue; if(sub == -1 || sub == cap_list[cap].cap) return &cap_list[cap]; } return NULL;}void SendMessage(Trunk *trk, EventRecord *er){ trk->EnterMutex(); trk->PostMessage(er); trk->LeaveMutex();};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -