?? pshookswtask.cpp
字號:
//// Copyright (C) 2004, 2005 Pingtel Corp.// //// $$//////////////////////////////////////////////////////////////////////////////// SYSTEM INCLUDES#include <assert.h>// APPLICATION INCLUDES#include "os/OsEventMsg.h"#include "os/OsNotification.h"#include "os/OsQueuedEvent.h"#include "os/OsReadLock.h"#include "os/OsTimer.h"#include "os/OsWriteLock.h"#include "ps/PsHookswTask.h"#include "ps/PsPhoneTask.h"#include "tao/TaoPhoneComponentAdaptor.h"// EXTERNAL FUNCTIONS// EXTERNAL VARIABLES// Everything within the HOOKSW_TEMP_HACK defines should be removed when we// fully switch over to using the new style of hook switch handling#define HOOKSW_TEMP_HACK#ifdef HOOKSW_TEMP_HACKint oldStyleHooksw = 0; // 0 ==> optimized hooksw handling // 1 ==> old-style hooksw handling#endif// CONSTANTSconst int DEBOUNCE_TIMER_MSECS = 25; // 25 millisecondsconst int SHORT_DEBOUNCE_MSECS = 100; // 100 millisecondsconst int LONG_DEBOUNCE_MSECS = 400; // 400 milliseconds#ifdef HOOKSW_TEMP_HACKconst int DEBOUNCE_MSECS = 20; // 20 milliseconds#endif// STATIC VARIABLE INITIALIZATIONSPsHookswTask* PsHookswTask::spInstance = 0;OsBSem PsHookswTask::sLock(OsBSem::Q_PRIORITY, OsBSem::FULL);/* //////////////////////////// PUBLIC //////////////////////////////////// *//* ============================ CREATORS ================================== */// Return a pointer to the Hooksw task, creating it if necessaryPsHookswTask* PsHookswTask::getHookswTask(void){ UtlBoolean isStarted; // If the task object already exists, and the corresponding low-level task // has been started, then use it if (spInstance != NULL && spInstance->isStarted()) return spInstance; // If the task does not yet exist or hasn't been started, then acquire // the lock to ensure that only one instance of the task is started sLock.acquire(); if (spInstance == NULL) spInstance = new PsHookswTask(); isStarted = spInstance->isStarted(); if (!isStarted) { isStarted = spInstance->start(); assert(isStarted); } sLock.release(); return spInstance;}// DestructorPsHookswTask::~PsHookswTask(){ delete mpHookswDev; delete mpTimer; spInstance = NULL;}/* ============================ MANIPULATORS ============================== */// Create a hookswitch message and post it to the Hookswitch task.// Return the result of the message send operation.OsStatus PsHookswTask::postEvent(const int msg, void* source, const int hookswState, const OsTime& rTimeout){ PsMsg hookswMsg(msg, source, hookswState, 0); OsStatus res; res = postMessage(hookswMsg, rTimeout); return res;}/* ============================ ACCESSORS ================================= */// Return the hookswitch stateconst int PsHookswTask::getHookswitchState(void){ OsReadLock lock(mMutex); // acquire a read lock return mHookswState;}/* ============================ INQUIRY =================================== *//* //////////////////////////// PROTECTED ///////////////////////////////// */// Default constructor (called only indirectly via getHookswTask())PsHookswTask::PsHookswTask(): OsServerTask("PsHooksw"), mMutex(OsRWMutex::Q_PRIORITY), // create mutex for protecting data mHookswState(ON_HOOK), // initially, assume we are on hook mpHookswDev(NULL), // not yet initialized mDebounceState(WAIT_FOR_INTR), // initial debounce state mDebounceTicks(0), // initial debounce tick count mDebounceHookswState(ON_HOOK), // initial debounce hookswitch state mpTimer(NULL), // not yet initialized mpTimerEvent(NULL) // not yet initialized{ // create the object used to manage the hookswitch device mpHookswDev = PsHookswDev::getHookswDev(this); // enable hookswitch interrupts mpHookswDev->enableIntr(TRUE); // start by looking for offhook // create the timer that will be used to "debounce" the hookswitch mpTimer = new OsTimer(&mIncomingQ, 0); mpTimerEvent = (OsQueuedEvent*) mpTimer->getNotifier();}/* //////////////////////////// PRIVATE /////////////////////////////////// */// Handle an incoming message.// Return TRUE if the message was handled, otherwise FALSE.UtlBoolean PsHookswTask::handleMessage(OsMsg& rMsg){ UtlBoolean processed; OsWriteLock lock(mMutex); // acquire a write lock switch (rMsg.getMsgType()) { case OsMsg::OS_EVENT: processed = handleEventMessage((OsEventMsg&) rMsg); break; case OsMsg::PS_MSG: processed = handlePhoneMessage((PsMsg&) rMsg); break; default: assert(FALSE); processed = FALSE; // unexpected message type break; } return processed;}// Handle an incoming event message (timer expiration).// Return TRUE if the message was handled, otherwise FALSE.// A write lock should be acquired before calling this method.UtlBoolean PsHookswTask::handleEventMessage(const OsEventMsg& rMsg){ int debounceInterval; int hookswState; PsPhoneTask* pPhoneTask; UtlBoolean processed; OsTimer* pTimer; OsStatus res; processed = TRUE; switch(rMsg.getMsgSubType()) { case OsEventMsg::NOTIFY: rMsg.getEventData((int&) pTimer); // get timer object assert(pTimer == mpTimer); hookswState = readHwHookswState();// determine HW hook state#ifdef HOOKSW_TEMP_HACK if (oldStyleHooksw) { if (hookswState == mHookswState) { // no change since last time, if (mHookswState == ON_HOOK) // enable the hooksw interrupt mpHookswDev->enableIntr(TRUE); // look for off hook else mpHookswDev->enableIntr(FALSE); // look for on hook } else { mHookswState = hookswState; // update the hookswitch state // Send a hookswitch message to the phone set with the new state pPhoneTask = PsPhoneTask::getPhoneTask(); res = pPhoneTask->postEvent(PsMsg::HOOKSW_STATE, // msg type this, // source mHookswState, // hooksw state 0); // not used assert(res == OS_SUCCESS); startDebounceTimer(); // rearm the debounce timer } } else {#endif mDebounceTicks++; switch (mDebounceState) { case SHORT_DEBOUNCE: case LONG_DEBOUNCE: debounceInterval = ((mDebounceState == SHORT_DEBOUNCE) ? SHORT_DEBOUNCE_MSECS : LONG_DEBOUNCE_MSECS); if (mDebounceHookswState != hookswState) // is state still bouncing? { mDebounceHookswState = hookswState; // stay in the current mDebounceTicks = 0; // state } if ((mDebounceTicks * DEBOUNCE_TIMER_MSECS) >= debounceInterval) { if (mDebounceHookswState != mHookswState) { mHookswState = hookswState; // update the hookswitch state // Send a hookswitch message to the phone set with the new state pPhoneTask = PsPhoneTask::getPhoneTask(); res = pPhoneTask->postEvent(PsMsg::HOOKSW_STATE, // msg type this, // source mHookswState, // hooksw state 0); // not used assert(res == OS_SUCCESS); mDebounceState = ((mDebounceState == SHORT_DEBOUNCE) ? LONG_DEBOUNCE : WAIT_FOR_INTR); mDebounceTicks = 0; } else { mDebounceState = WAIT_FOR_INTR;// enable the hooksw interrupt mDebounceTicks = 0; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -