Added preliminary tuner state queues.

This commit is contained in:
Rolf Ahrenberg 2014-11-23 22:22:38 +02:00
parent eea0aa33bd
commit 8415075de9
2 changed files with 84 additions and 45 deletions

99
tuner.c
View File

@ -30,7 +30,8 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
pidUpdateCacheM(), pidUpdateCacheM(),
sessionM(""), sessionM(""),
currentStateM(tsIdle), currentStateM(tsIdle),
nextStateM(tsIdle), internalStateM(),
externalStateM(),
timeoutM(eMinKeepAliveIntervalMs), timeoutM(eMinKeepAliveIntervalMs),
hasLockM(false), hasLockM(false),
signalStrengthM(-1), signalStrengthM(-1),
@ -65,14 +66,14 @@ cSatipTuner::~cSatipTuner()
{ {
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM); debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM);
currentStateM = tsIdle;
nextStateM = tsIdle;
// Stop thread // Stop thread
sleepM.Signal(); sleepM.Signal();
if (Running()) if (Running())
Cancel(3); Cancel(3);
Close(); Close();
currentStateM = tsIdle;
internalStateM.Clear();
externalStateM.Clear();
// Close the listening sockets // Close the listening sockets
cSatipPoller::GetInstance()->Unregister(rtcpM); cSatipPoller::GetInstance()->Unregister(rtcpM);
@ -87,12 +88,7 @@ void cSatipTuner::Action(void)
reConnectM.Set(eConnectTimeoutMs); reConnectM.Set(eConnectTimeoutMs);
// Do the thread loop // Do the thread loop
while (Running()) { while (Running()) {
mutexM.Lock(); UpdateCurrentState();
if (StateRequested()) {
debug("cSatipTuner::%s(): switching from %s to %s [device %d]", __FUNCTION__, TunerStateString(currentStateM), TunerStateString(nextStateM), deviceIdM);
currentStateM = nextStateM;
}
mutexM.Unlock();
switch (currentStateM) { switch (currentStateM) {
case tsIdle: case tsIdle:
//debug("cSatipTuner::%s(): tsIdle [device %d]", __FUNCTION__, deviceIdM); //debug("cSatipTuner::%s(): tsIdle [device %d]", __FUNCTION__, deviceIdM);
@ -100,19 +96,19 @@ void cSatipTuner::Action(void)
case tsRelease: case tsRelease:
//debug("cSatipTuner::%s(): tsRelease [device %d]", __FUNCTION__, deviceIdM); //debug("cSatipTuner::%s(): tsRelease [device %d]", __FUNCTION__, deviceIdM);
Disconnect(); Disconnect();
RequestState(tsIdle); RequestState(tsIdle, smInternal);
break; break;
case tsSet: case tsSet:
//debug("cSatipTuner::%s(): tsSet [device %d]", __FUNCTION__, deviceIdM); //debug("cSatipTuner::%s(): tsSet [device %d]", __FUNCTION__, deviceIdM);
reConnectM.Set(eConnectTimeoutMs); reConnectM.Set(eConnectTimeoutMs);
Disconnect(); Disconnect();
if (Connect()) { if (Connect()) {
RequestState(tsTuned); RequestState(tsTuned, smInternal);
UpdatePids(true); UpdatePids(true);
} }
else { else {
error("Tuning failed - re-tuning [device %d]", deviceIdM); error("Tuning failed - re-tuning [device %d]", deviceIdM);
RequestState(tsIdle); RequestState(tsIdle, smInternal);
} }
break; break;
case tsTuned: case tsTuned:
@ -127,24 +123,24 @@ void cSatipTuner::Action(void)
signalQualityM = eDefaultSignalQuality; signalQualityM = eDefaultSignalQuality;
} }
if (hasLockM) if (hasLockM)
RequestState(tsLocked); RequestState(tsLocked, smInternal);
} }
break; break;
case tsLocked: case tsLocked:
//debug("cSatipTuner::%s(): tsLocked [device %d]", __FUNCTION__, deviceIdM); //debug("cSatipTuner::%s(): tsLocked [device %d]", __FUNCTION__, deviceIdM);
if (!UpdatePids()) { if (!UpdatePids()) {
error("Pid update failed - re-tuning [device %d]", deviceIdM); error("Pid update failed - re-tuning [device %d]", deviceIdM);
RequestState(tsSet); RequestState(tsSet, smInternal);
break; break;
} }
if (!KeepAlive()) { if (!KeepAlive()) {
error("Keep-alive failed - re-tuning [device %d]", deviceIdM); error("Keep-alive failed - re-tuning [device %d]", deviceIdM);
RequestState(tsSet); RequestState(tsSet, smInternal);
break; break;
} }
if (reConnectM.TimedOut()) { if (reConnectM.TimedOut()) {
error("Connection timeout - re-tuning [device %d]", deviceIdM); error("Connection timeout - re-tuning [device %d]", deviceIdM);
RequestState(tsSet); RequestState(tsSet, smInternal);
break; break;
} }
break; break;
@ -163,7 +159,7 @@ bool cSatipTuner::Open(void)
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM); debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM);
RequestState(tsSet); RequestState(tsSet, smExternal);
// return always true // return always true
return true; return true;
@ -174,7 +170,7 @@ bool cSatipTuner::Close(void)
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM); debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM);
RequestState(tsRelease); RequestState(tsRelease, smExternal);
// return always true // return always true
return true; return true;
@ -229,8 +225,6 @@ bool cSatipTuner::Disconnect(void)
rtspM.Teardown(*uri); rtspM.Teardown(*uri);
streamIdM = -1; streamIdM = -1;
} }
//currentStateM = tsIdle;
//nextStateM = tsIdle;
// Reset signal parameters // Reset signal parameters
hasLockM = false; hasLockM = false;
@ -339,11 +333,12 @@ bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const
// Update stream address and parameter // Update stream address and parameter
streamAddrM = rtspM.RtspUnescapeString(nextServerM->Address()); streamAddrM = rtspM.RtspUnescapeString(nextServerM->Address());
streamParamM = rtspM.RtspUnescapeString(parameterP); streamParamM = rtspM.RtspUnescapeString(parameterP);
RequestState(tsSet);
} }
} }
else else {
RequestState(tsRelease); streamAddrM = "";
streamParamM = "";
}
return true; return true;
} }
@ -439,24 +434,47 @@ bool cSatipTuner::ReadReceptionStatus(bool forceP)
return false; return false;
} }
void cSatipTuner::UpdateCurrentState(void)
{
//debug("cSatipTuner::%s() [device %d]", __FUNCTION__, deviceIdM);
cMutexLock MutexLock(&mutexM);
eTunerState state = currentStateM;
if (internalStateM.Size()) {
state = internalStateM.At(0);
internalStateM.Remove(0);
}
else if (externalStateM.Size()) {
state = externalStateM.At(0);
externalStateM.Remove(0);
}
if (currentStateM != state) {
debug("cSatipTuner::%s(): switching from %s to %s [device %d]", __FUNCTION__, TunerStateString(currentStateM), TunerStateString(state), deviceIdM);
currentStateM = state;
}
}
bool cSatipTuner::StateRequested(void) bool cSatipTuner::StateRequested(void)
{ {
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
//debug("cSatipTuner::%s(%s <> %s) [device %d]", __FUNCTION__, TunerStateString(currentStateM), TunerStateString(nextStateM), deviceIdM); //debug("cSatipTuner::%s() current=%s internal=%d external=%d [device %d]", __FUNCTION__, TunerStateString(currentStateM), internalStateM.Size(), externalStateM.Size(), deviceIdM);
return (currentStateM != nextStateM); return (internalStateM.Size() || externalStateM.Size());
} }
bool cSatipTuner::RequestState(eTunerState stateP) bool cSatipTuner::RequestState(eTunerState stateP, eStateMode modeP)
{ {
cMutexLock MutexLock(&mutexM); cMutexLock MutexLock(&mutexM);
debug("cSatipTuner::%s(%s) current=%s next=%s [device %d]", __FUNCTION__, TunerStateString(stateP), TunerStateString(currentStateM), TunerStateString(nextStateM), deviceIdM); debug("cSatipTuner::%s(%s, %s) current=%s internal=%d external=%d [device %d]", __FUNCTION__, TunerStateString(stateP), StateModeString(modeP), TunerStateString(currentStateM), internalStateM.Size(), externalStateM.Size(), deviceIdM);
if (currentStateM != nextStateM) if (modeP == smExternal)
debug("cSatipTuner::%s() invalid state change attempt [device %d]", __FUNCTION__, deviceIdM); externalStateM.Append(stateP);
else if (modeP == smInternal) {
eTunerState state = internalStateM.Size() ? internalStateM.At(internalStateM.Size() - 1) : currentStateM;
// validate legal state changes // validate legal state changes
switch (currentStateM) { switch (state) {
case tsIdle: case tsIdle:
if (stateP == tsRelease) if (stateP == tsRelease)
return false; return false;
@ -468,11 +486,28 @@ bool cSatipTuner::RequestState(eTunerState stateP)
break; break;
} }
nextStateM = stateP; internalStateM.Append(stateP);
}
else
return false;
return true; return true;
} }
const char *cSatipTuner::StateModeString(eStateMode modeP)
{
switch (modeP) {
case smInternal:
return "smInternal";
case smExternal:
return "smExternal";
default:
break;
}
return "---";
}
const char *cSatipTuner::TunerStateString(eTunerState stateP) const char *cSatipTuner::TunerStateString(eTunerState stateP)
{ {
switch (stateP) { switch (stateP) {

View File

@ -59,6 +59,7 @@ private:
eMinKeepAliveIntervalMs = 30000 // in milliseconds eMinKeepAliveIntervalMs = 30000 // in milliseconds
}; };
enum eTunerState { tsIdle, tsRelease, tsSet, tsTuned, tsLocked }; enum eTunerState { tsIdle, tsRelease, tsSet, tsTuned, tsLocked };
enum eStateMode { smInternal, smExternal };
cCondWait sleepM; cCondWait sleepM;
cSatipDeviceIf* deviceM; cSatipDeviceIf* deviceM;
@ -77,7 +78,8 @@ private:
cTimeMs pidUpdateCacheM; cTimeMs pidUpdateCacheM;
cString sessionM; cString sessionM;
eTunerState currentStateM; eTunerState currentStateM;
eTunerState nextStateM; cVector<eTunerState> internalStateM;
cVector<eTunerState> externalStateM;
int timeoutM; int timeoutM;
bool hasLockM; bool hasLockM;
int signalStrengthM; int signalStrengthM;
@ -92,8 +94,10 @@ private:
bool KeepAlive(bool forceP = false); bool KeepAlive(bool forceP = false);
bool ReadReceptionStatus(bool forceP = false); bool ReadReceptionStatus(bool forceP = false);
bool UpdatePids(bool forceP = false); bool UpdatePids(bool forceP = false);
void UpdateCurrentState(void);
bool StateRequested(void); bool StateRequested(void);
bool RequestState(eTunerState stateP); bool RequestState(eTunerState stateP, eStateMode modeP);
const char *StateModeString(eStateMode modeP);
const char *TunerStateString(eTunerState stateP); const char *TunerStateString(eTunerState stateP);
protected: protected: