00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <bogotel/portability.h>
00011 #include <bogotel/PlayOp.h>
00012 #include <bogotel/TermParms.h>
00013
00014 #include <sys/stat.h>
00015 #include <sys/types.h>
00016
00017 #include <bogotel/BgtErrors.h>
00018
00019 namespace bogotel {
00020
00021 const char *CPlayOp::s_szName = "CPlayOp";
00022
00023 CPlayOp::CPlayOp(CVoiceDev* pVD, const DX_IOTT* pIOTT, const DV_TPT* pTPT) throw (std::invalid_argument) :
00024 CIOOp(pVD),
00025 m_pIott(pIOTT),
00026 m_bWasWavPlayed(false),
00027 m_pTermParms(NULL)
00028 {
00029 char method[] = "CPlayOp::CPlayOp";
00030 if (pTPT != NULL) {
00031 try {
00032 m_pTermParms = new CTermParms(pVD, this, pTPT);
00033 } catch (std::invalid_argument& except) {
00034 log(3, "%s: new CTermParms threw exception", method, except.what());
00035 throw;
00036 }
00037 }
00038 processIottEntry();
00039 }
00040
00041 CPlayOp::~CPlayOp()
00042 {
00043 delete m_pTermParms;
00044 CIOOp::~CIOOp();
00045 }
00046
00047 void CPlayOp::start()
00048 {
00049 if (m_pTermParms) {
00050 m_pTermParms->start();
00051 }
00052 }
00053
00054 std::string CPlayOp::toString()
00055 {
00056 return CTimerTarget::toString() + " " + s_szName;
00057 }
00058
00059 long CPlayOp::terminationEvent()
00060 {
00061 return TDX_PLAY;
00062 }
00063
00064
00065
00066 void CPlayOp::_timerExpired(int timerType, int stateId)
00067 {
00068 char method[] = "CPlayOp::_timerExpired";
00069 switch (timerType) {
00070 case timerType::singleWav:
00071 processIottEntry();
00072 break;
00073 case CTermParms::timerType::MaxSil:
00074 case CTermParms::timerType::MaxTime:
00075 case CTermParms::timerType::IddTime:
00076 m_pTermParms->timerExpired(timerType, stateId);
00077 break;
00078 default:
00079 log(3, "%s: Invalid timerType", method, timerType);
00080 break;
00081 }
00082 }
00083
00084 void CPlayOp::processIottEntry() throw (std::invalid_argument)
00085 {
00086 char method[] = "CPlayOp::processIottEntry";
00087
00088 if (m_pIott == NULL) {
00089
00090 if (m_bWasWavPlayed) {
00091 m_pVD->sendPlayFinishedMsg();
00092 }
00093 terminate(TM_NORMTERM);
00094 return;
00095 }
00096
00097 std::string strFilename;
00098 long lDuration;
00099
00100
00101 MAP_INT2STR::iterator it;
00102 int hFile(m_pIott->io_fhandle);
00103 it = CVoiceDev::s_mapHandle2Filename.find(hFile);
00104 if (it == CVoiceDev::s_mapHandle2Filename.end()) {
00105 log(3, "%s: file handle not stored in map", method);
00106 throw std::invalid_argument(std::string(method) + ": file handle not stored in map");
00107 }
00108 strFilename = it->second;
00109
00110 int rc;
00111 if ((rc = getWavDuration(hFile, &lDuration)) != resultSUCCESS) {
00112 log(3, "%s: getWavDuration() failed. filename is %s, rc is %d",
00113 method, strFilename.c_str(), rc);
00114 throw std::invalid_argument(std::string(method) + ": getWavDuration() failed");
00115 }
00116
00117 m_pVD->sendPlayMsg(strFilename);
00118 m_bWasWavPlayed = true;
00119
00120
00121 setTimer(lDuration, timerType::singleWav);
00122
00123
00124 switch (m_pIott->io_type) {
00125 case IO_CONT:
00126 m_pIott++;
00127 break;
00128 case IO_LINK:
00129 m_pIott = m_pIott->io_nextp;
00130 break;
00131 case IO_EOT:
00132 m_pIott = NULL;
00133 break;
00134 }
00135 }
00136
00141 int CPlayOp::getWavDuration(int hFile, long *plDuration)
00142 {
00143 struct _stat buf;
00144 if (_fstat(hFile, &buf) != 0) {
00145 (*plDuration) = 1000;
00146 log(3, "CPlayOp::getWavDuration(): _fstat() failed. errno is %d", errno);
00147 return resultIOERROR;
00148 }
00149
00150
00151
00152
00153
00155 (*plDuration) = static_cast<long>((buf.st_size / 11025.0) * 1000);
00156
00157 return resultSUCCESS;
00158 }
00159 }