Main Page   Namespace List   Class Hierarchy   Data Structures   File List   Namespace Members   Data Fields   Globals   Related Pages  

SignalDev.cpp

Go to the documentation of this file.
00001 /*
00002  * SignalDev.cpp
00003  *
00004  * Copyright 2003, MobileSpear Inc. (www.mobilespear.com). All rights reserved.
00005  * Copyright 2003, David Resnick. All rights reserved.
00006  *
00007  * See the file doc\license.txt for the terms of usage and distribution.
00008  */
00009 
00010 #include <bogotel/Portability.h>
00011 #include <bogotel/SignalDev.h>
00012 #include <bogotel/VoiceDev.h>
00013 #include <bogotel/MsgTransport.h>
00014 #include <bogotel/BgtErrors.h>
00015 #include <bogotel/util.h>
00016 #include <bogotel/Timer.h>
00017 
00018 namespace bogotel {
00019 
00020     // 0 is not a valid CRN, start with 1
00021     long CSignalDev::m_lNextCrn = 1;
00022 
00023     const std::string CSignalDev::stateNames[10] = {
00024         "RESET",
00025         "NULL",
00026         "IDLE",
00027         "DIALING",
00028         "ALERTING",
00029         "OFFERED",
00030         "ACCEPTED",
00031         "CONNECTED",
00032         "DISCONNECTED",
00033         "DROPPED"
00034     };
00035 
00036     const std::string CSignalDev::eventNames[10] = {
00037         "UNBLOCKED",
00038         "OFFERED",
00039         "ALERTING",
00040         "ANSWERED",
00041         "ACCEPT",
00042         "CONNECTED",
00043         "DROPCALL",
00044         "DISCONNECTED",
00045         "RESETLINEDEV",
00046         "Unknown"
00047     };
00048 
00049     CSignalDev::CSignalDev(CBgtRt *pBgtRt) :
00050     CDevBase(pBgtRt),
00051     m_pUsrAttr(NULL),
00052     m_pVoiceDev(NULL),
00053     m_lSCbusTimeslot(-1),
00054     m_lHandle(-1),
00055     m_state(NS_RESET),
00056     m_bWaitCall(FALSE),
00057     m_bBlocked(TRUE),
00058     m_iGcResult(0)
00059     {
00060     }
00061 
00062     int CSignalDev::init(std::string strNetDev, std::string strProt, void *usrattr, long lHandle, long lTimeslot)
00063     {
00064         int rc;
00065         if ((rc = CDevBase::init()) != resultSUCCESS) {
00066             return rc;
00067         }
00068 
00069         m_strNetDev = strNetDev;
00070         m_strProt = strProt;
00071         m_pUsrAttr = usrattr;
00072         m_lHandle = lHandle;
00073         m_lSCbusTimeslot = lTimeslot;
00074 
00075         m_state = NS_NULL;
00076         m_bBlocked = FALSE;
00077 
00078         // add UNBLOCKED event to queue
00079         sendEvent(GCEV_UNBLOCKED, 0);
00080 
00081         return resultSUCCESS;
00082     }
00083 
00084     int CSignalDev::listen(CVoiceDev *pVD)
00085     {
00086         if (m_pVoiceDev != NULL) {
00087             return resultPOINTER;
00088         }
00089         m_pVoiceDev = pVD;
00090         
00091         log(9, "CSignalDev::listen() completed.");
00092 
00093         return resultSUCCESS;
00094     }
00095 
00096     int CSignalDev::waitCall()
00097     {
00098         m_bWaitCall = TRUE;
00099     //  m_state = NS_WAITING;
00100         log(9, "CSignalDev::waitCall() completed.");
00101         return resultSUCCESS;
00102     }
00103 
00104     int CSignalDev::makeCall(CRN *pCrn, char *szNumber, int iTimeout, char *szAni)
00105     {
00106         char _func[] = "CSignalDev::makeCall";
00107         (*pCrn) = m_lNextCrn;
00108         m_lNextCrn++;
00109 
00110         int rc;
00111         if ((rc = m_pBgtRt->registerCrn(this, (*pCrn))) != resultSUCCESS) {
00112             return rc;
00113         }
00114 
00115         m_pMsg->clear();
00116         m_pMsg->m_class = MC_SIGNAL;
00117         m_pMsg->m_type = MT_MAKE_CALL;
00118         m_pMsg->m_id = m_lHandle;
00119         m_pMsg->m_crn = (*pCrn);
00120         m_pMsg->addParam(PT_ANI, szAni? szAni : m_strAni);
00121         m_pMsg->addParam(PT_DNIS, szNumber);
00122 
00123         m_state = NS_DIALING;
00124 
00125         // ignore timeout if 0
00126         if (iTimeout != 0) {
00127             // schedule timer for timeout period
00128     //      m_pTimer->add(iTimeout * 1000, this);
00129         }
00130     
00131         if ((rc = sendMsg(m_pMsg)) != resultSUCCESS) {
00132             log(3, "sendMsg() failed in CSignalDev::makeCall(). rc is %d", rc);
00133             return rc;
00134         }
00135         log(7, "Dialing. ANI=%s. DNIS=%s", m_strAni.c_str(), szNumber);
00136         log(9, "CSignalDev::makeCall() completed.");
00137         return rc;
00138     }
00139 
00140     int CSignalDev::acceptCall(CRN crn)
00141     {
00142         m_pMsg->clear();
00143         m_pMsg->m_class = MC_SIGNAL;
00144         m_pMsg->m_type = MT_ACCEPT_CALL;
00145         m_pMsg->m_id = m_lHandle;
00146         m_pMsg->m_crn = crn;
00147 
00148         m_state = NS_ACCEPTED;
00149 
00150         int rc;
00151         if ((rc = sendMsg(m_pMsg)) != resultSUCCESS) {
00152             log(3, "sendMsg() failed in CSignalDev::acceptCall(). rc is %d", rc);
00153             return rc;
00154         }
00155         if ((rc = sendEvent(GCEV_ACCEPT, crn)) != resultSUCCESS) {
00156             log(3, "CSignalDev::acceptCall() sendEvent() failed. rc is %d", rc);
00157         }
00158 
00159         log(9, "CSignalDev::acceptCall() completed.");
00160         return rc;
00161     }
00162 
00163     int CSignalDev::answerCall(CRN crn)
00164     {
00165         m_pMsg->clear();
00166         m_pMsg->m_class = MC_SIGNAL;
00167         m_pMsg->m_type = MT_ANSWER_CALL;
00168         m_pMsg->m_id = m_lHandle;
00169         m_pMsg->m_crn = crn;
00170 
00171         m_state = NS_CONNECTED;
00172 
00173         int rc;
00174         if ((rc = sendMsg(m_pMsg)) != resultSUCCESS) {
00175             log(3, "sendMsg() failed in CSignalDev::answerCall(). rc is %d", rc);
00176             return rc;
00177         }
00178 
00179         if ((rc = sendEvent(GCEV_ANSWERED, crn)) != resultSUCCESS) {
00180             log(3, "CSignalDev::answerCall() sendEvent() failed. rc is %d", rc);
00181         }
00182 
00183         log(9, "CSignalDev::answerCall() completed.");
00184         return rc;
00185     }
00186 
00187     int CSignalDev::dropCall(CRN crn, int iCause)
00188     {
00189         m_pMsg->clear();
00190         m_pMsg->m_class = MC_SIGNAL;
00191         m_pMsg->m_id = m_lHandle;
00192         m_pMsg->m_crn = crn;
00193         m_pMsg->m_type = MT_DROPCALL;
00194 
00195         switch (m_state) {
00196         case NS_DIALING:
00197         case NS_ALERTING:
00198         case NS_OFFERED:
00199         case NS_ACCEPTED:
00200         case NS_CONNECTED:
00201             m_state = NS_DROPPING;
00202             break;
00203         case NS_DISCONNECTED: {
00204             int rc;
00205             m_state = NS_IDLE;
00206             if ((rc = sendEvent(GCEV_DROPCALL, crn)) != resultSUCCESS) {
00207                 log(3, "CSignalDev::receiveMsg() sendEvent() failed. rc is %d", rc);
00208             }
00209             break;
00210         }
00211         case NS_RESET:
00212         case NS_NULL:
00213         case NS_IDLE:
00214         default:
00215             log(3, "dropCall() called when in invalid state. state is %d", m_state);
00216             return resultUNEXPECTED;
00217         }
00218         int rc;
00219         if ((rc = sendMsg(m_pMsg)) != resultSUCCESS) {
00220             log(3, "sendMsg() failed in CSignalDev::answerCall(). rc is %d", rc);
00221             return rc;
00222         }
00223 
00224         log(9, "CSignalDev::dropCall() completed.");
00225         return rc;
00226     }
00227 
00228     int CSignalDev::resetLineDev()
00229     {
00230         // increase the current event ID so that if there are any
00231         // delayed events, their return will be ignored
00232         m_lId++;
00233 
00234         m_state = NS_NULL;
00235         m_bBlocked = FALSE;
00236 
00237         sendEvent(GCEV_RESETLINEDEV, 0);
00238         return resultSUCCESS;
00239     }
00240 
00241     int CSignalDev::releaseCall(CRN crn, unsigned long ulMode)
00242     {
00243         int rc;
00244 
00245         switch (m_state) {
00246         case NS_IDLE:
00247             m_state = NS_NULL;
00248 
00249             break;
00250         default:
00251             log(3, "releaseCall() called when in invalid state. state is %s", getStateName(m_state));
00252             m_pBgtRt->setGcResult(1);
00253             m_pBgtRt->setCcLibId(1);
00254             m_pBgtRt->setCcLibResult(1);
00255             return resultUNEXPECTED;
00256         }
00257 
00258         if ((rc = m_pBgtRt->deregisterCrn(crn)) != resultSUCCESS) {
00259             return rc;
00260         }
00261 
00262         if (ulMode == EV_ASYNC) {
00263             if ((rc = sendEvent(GCEV_RESETLINEDEV, 0)) != resultSUCCESS) {
00264                 log(3, "CSignalDev::releaseCall() sendEvent() failed. rc is %d", rc);
00265             }
00266         }
00267 
00268         log(7, "Circuit is disconnected.");
00269 
00270         log(9, "CSignalDev::releaseCall() completed.");
00271         return resultSUCCESS;
00272     }
00273 
00274     int CSignalDev::resultValue(METAEVENT *pMetaEvent, int *piGcResult, int *piCcLibId, long *plCcLibResult)
00275     {
00276         (*piGcResult)    = m_iGcResult;
00277         (*piCcLibId)     = 0;
00278         (*plCcLibResult) = 0;
00279         return resultSUCCESS;
00280     }
00281 
00282     int CSignalDev::getDnis(char *szDnis)
00283     {
00284         strcpy(szDnis, m_strDnis.c_str());
00285         log(9, "CSignalDev::getDnis() completed.");
00286         return resultSUCCESS;
00287     }
00288 
00289     int CSignalDev::getAni(char *szAni)
00290     {
00291         strcpy(szAni, m_strAni.c_str());
00292         log(9, "CSignalDev::getAni() completed.");
00293         return resultSUCCESS;
00294     }
00295 
00296     int CSignalDev::setAni(char *szAni)
00297     {
00298         m_strAni = szAni;
00299         log(9, "CSignalDev::setAni() completed.");
00300         return resultSUCCESS;
00301     }
00302 
00303     int CSignalDev::receiveMsg(CMsg *pMsg)
00304     {
00305         int rc = resultSUCCESS;
00306         CRN crn = pMsg->m_crn;
00307 
00308         char szType[30];
00309         pMsg->getMsgTypeString(szType, sizeof(szType));
00310         log(7, "CSignalDev::receiveMsg(): %s type", szType);
00311 
00312         switch(pMsg->m_type) {
00313         case MT_DROPCALL:
00314             switch (m_state) {
00315             case NS_DIALING:
00316             case NS_ALERTING:
00317             case NS_OFFERED:
00318             case NS_ACCEPTED:
00319             case NS_CONNECTED:
00320                 m_state = NS_DISCONNECTED;
00321                 m_iGcResult = GC_NORMAL_CLEARING;
00322                 if ((rc = sendEvent(GCEV_DISCONNECTED, crn)) != resultSUCCESS) {
00323                     log(3, "CSignalDev::receiveMsg() sendEvent() failed. rc is %d", rc);
00324                 }
00325                 break;
00326             case NS_DROPPING:
00327                 m_state = NS_IDLE;
00328                 if ((rc = sendEvent(GCEV_DROPCALL, crn)) != resultSUCCESS) {
00329                     log(3, "CSignalDev::receiveMsg() sendEvent() failed. rc is %d", rc);
00330                 }
00331                 // give up timeslice to other thread
00332                 ::Sleep(0);
00333                 break;
00334             case NS_RESET:
00335             case NS_NULL:
00336             case NS_DISCONNECTED:
00337             default:
00338                 rc = resultUNEXPECTED;
00339                 goto cleanup;
00340             }
00341             break;
00342 
00343         case MT_MAKE_CALL:
00344             // check that we can accept the message
00345             if (! (m_state == NS_NULL && m_bWaitCall)) {
00346                 rc = resultUNEXPECTED;
00347                 goto cleanup;
00348             }
00349             m_state = NS_OFFERED;
00350             m_strAni = pMsg->getParam(PT_ANI);
00351             m_strDnis = pMsg->getParam(PT_DNIS);
00352             if ((rc = m_pBgtRt->registerCrn(this, crn)) != resultSUCCESS) {
00353                 goto cleanup;
00354             }
00355             if ((rc = sendEvent(GCEV_OFFERED, crn)) != resultSUCCESS) {
00356                 log(3, "CSignalDev::receiveMsg() sendEvent() failed. rc is %d", rc);
00357             }
00358             break;
00359         case MT_ACCEPT_CALL:
00360             // check that we can accept the message
00361             if (m_state != NS_DIALING) {
00362                 rc = resultUNEXPECTED;
00363                 goto cleanup;
00364             }
00365             m_state = NS_ALERTING;
00366             if ((rc = sendEvent(GCEV_ALERTING, crn)) != resultSUCCESS) {
00367                 log(3, "CSignalDev::receiveMsg() sendEvent() failed. rc is %d", rc);
00368             }
00369             break;
00370         case MT_ANSWER_CALL:
00371             // check that we can accept the message
00372             if (m_state != NS_DIALING && m_state != NS_ALERTING) {
00373                 rc = resultUNEXPECTED;
00374                 goto cleanup;
00375             }
00376             // invalidate the timer so that it will be ignored when it expires
00377             m_lId++;
00378 
00379             m_state = NS_CONNECTED;
00380             if ((rc = sendEvent(GCEV_CONNECTED, crn)) != resultSUCCESS) {
00381                 log(3, "CSignalDev::receiveMsg() sendEvent() failed. rc is %d", rc);
00382             }
00383             log(7, "Circuit connected");
00384             break;
00385 
00386         default:
00387             log(3, "CSignalDev::receiveMsg(). Unknown message: type is %s. "
00388                 "state is %s, waitcall is %s", szType, getStateName(m_state),
00389                 m_bWaitCall? "TRUE":"FALSE");
00390             break;
00391         }
00392 
00393     cleanup:
00394         switch (rc) {
00395         case resultSUCCESS:
00396             log(9, "CSignalDev::receiveMsg() completed.");
00397             break;
00398         case resultUNEXPECTED:
00399             log(3, "CSignalDev::receiveMsg(). Invalid state for message \"%s\". "
00400                 "state is %s, waitcall is %s", szType, getStateName(m_state).c_str(),
00401                 m_bWaitCall? "TRUE":"FALSE");
00402             break;
00403         }
00404         return rc;
00405     }
00406 
00411     int CSignalDev::putEvt(unsigned long event_type, long len, void *pData, long err)
00412     {
00413         return sendEvent(event_type, 0);
00414     }
00415 
00416     int CSignalDev::sendEvent(long lType, long lCrn)
00417     {
00418         CEvt *pEvt = new CEvt();
00419 
00420         pEvt->m_pUsrAttr = m_pUsrAttr;
00421         pEvt->m_lLen = sizeof(void*);
00422         pEvt->m_lType = lType;
00423         pEvt->m_lVoiceDevHandle = m_pVoiceDev? m_pVoiceDev->getHandle() : CVoiceDev::invalidHandle;
00424         pEvt->m_lSignalDevHandle = m_lHandle;
00425         pEvt->m_ulFlags = GCME_GC_EVENT;
00426         pEvt->m_lCrn = lCrn;
00427         pEvt->m_iSysType = CEvt::SysType::DEVICE;
00428 
00429         int rc;
00430         if ((rc = m_pBgtRt->addEvent(pEvt)) != resultSUCCESS) {
00431             log(3, "m_pBgtRt->addEvent() failed.");
00432             return rc;
00433         }
00434         log(7, "CSignalDev::sendEvent(): %s type", getEventName(lType).c_str());
00435         return rc;
00436     }
00437 
00438     int CSignalDev::sendMsg(CMsg *pMsg)
00439     {
00440         char szType[30];
00441         pMsg->getMsgTypeString(szType, sizeof(szType));
00442         log(7, "CSignalDev::sendMsg(): %s type", szType);
00443         return m_pTransport->sendMsg(pMsg);
00444     }
00445 
00446     void CSignalDev::log(int iLevel, char *szFmt, ...)
00447     {
00448         va_list vl;
00449         char szTemp[2000];
00450 
00451         va_start(vl, szFmt);
00452         _vsnprintf(szTemp, sizeof(szTemp), szFmt, vl);
00453         va_end(vl);
00454 
00455         g_util->log(iLevel, m_lHandle, szTemp);
00456     }
00457 
00458     void CSignalDev::logF(char *szFunc, int iLevel, char *szFmt, ...)
00459     {
00460         char szFmtWFunc[2000];
00461         _snprintf(szFmtWFunc, sizeof(szFmtWFunc), "Error in %s(): %s", szFunc, szFmt);
00462 
00463         va_list vl;
00464         char szTemp[2000];
00465 
00466         va_start(vl, szFmt);
00467         _vsnprintf(szTemp, sizeof(szTemp), szFmtWFunc, vl);
00468         va_end(vl);
00469 
00470         g_util->log(iLevel, m_lHandle, szTemp);
00471     }
00472 
00473     const std::string& CSignalDev::getStateName(int state) {
00474         return stateNames[state];
00475     }
00476 
00477     const std::string& CSignalDev::getEventName(long lType)
00478     {
00479         switch(lType) {
00480         case GCEV_UNBLOCKED:    return eventNames[0];
00481         case GCEV_OFFERED:      return eventNames[1];
00482         case GCEV_ALERTING:     return eventNames[2];
00483         case GCEV_ANSWERED:     return eventNames[3];
00484         case GCEV_ACCEPT:       return eventNames[4];
00485         case GCEV_CONNECTED:    return eventNames[5];
00486         case GCEV_DROPCALL:     return eventNames[6];
00487         case GCEV_DISCONNECTED: return eventNames[7];
00488         case GCEV_RESETLINEDEV: return eventNames[8];
00489         default:                return eventNames[9];
00490         }
00491     }
00492 
00493 }
00494 

Generated on Tue Aug 12 12:41:30 2003 for bogotel by doxygen 1.3. Hosted by SourceForge.net Logo