Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions src/ble/hal/blercu/bleservices/gatt/gatt_audioservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,22 @@ void GattAudioService::init()
// add all the states and the super state groupings
m_stateMachine.addState(IdleState, "Idle");
m_stateMachine.addState(ReadyState, "Ready");
m_stateMachine.addState(EnableNotificationsState, "EnableNotifications");

m_stateMachine.addState(StreamingSuperState, "StreamingSuperState");
m_stateMachine.addState(StreamingSuperState, EnableNotificationsState, "EnableNotifications");
m_stateMachine.addState(StreamingSuperState, StartStreamingState, "StartStreaming");
m_stateMachine.addState(StreamingSuperState, StreamingState, "Streaming");
m_stateMachine.addState(StreamingSuperState, StopStreamingState, "StopStreaming");


// add the transitions: From State -> Event -> To State
m_stateMachine.addTransition(IdleState, StartServiceRequestEvent, ReadyState);
m_stateMachine.addTransition(ReadyState, StopServiceRequestEvent, IdleState);
m_stateMachine.addTransition(ReadyState, StartStreamingRequestEvent, EnableNotificationsState);
m_stateMachine.addTransition(IdleState, StartServiceRequestEvent, EnableNotificationsState);
m_stateMachine.addTransition(EnableNotificationsState, RetryStartNotifyEvent, EnableNotificationsState);
m_stateMachine.addTransition(EnableNotificationsState, StopServiceRequestEvent, IdleState);
m_stateMachine.addTransition(EnableNotificationsState, NotificationsEnabledEvent, ReadyState);

Comment thread
egalla204 marked this conversation as resolved.
m_stateMachine.addTransition(EnableNotificationsState, NotificationsEnabledEvent, StartStreamingState);
m_stateMachine.addTransition(ReadyState, StopServiceRequestEvent, IdleState);
m_stateMachine.addTransition(ReadyState, StartStreamingRequestEvent, StartStreamingState);

m_stateMachine.addTransition(StartStreamingState, StreamingStartedEvent, StreamingState);

Expand Down Expand Up @@ -591,7 +593,8 @@ void GattAudioService::stopStreaming(uint32_t audioDuration, PendingReply<> &&re
{
// check the service is ready
if (m_stateMachine.state() != StreamingState) {
reply.setError("Service not currently streaming");
// Don't treat this as an error. The intent is to stop streaming, and if we're not streaming then the intent has been satisfied.
XLOGD_DEBUG("service not currently streaming");
reply.finish();
return;
}
Expand Down Expand Up @@ -738,6 +741,16 @@ void GattAudioService::stateMachinePostEvent(const Event::Type event)
m_stateMachine.postEvent(event);
}

void GattAudioService::stateMachinePostDelayedEvent(const Event::Type event, const int delay)
{
m_stateMachine.postDelayedEvent(event, delay);
}

void GattAudioService::stateMachineCancelDelayedEvents(const Event::Type eventType)
{
m_stateMachine.cancelDelayedEvents(eventType);
}

bool GattAudioService::stateMachineIsIdle()
{
return m_stateMachine.inState(IdleState);
Expand Down
17 changes: 11 additions & 6 deletions src/ble/hal/blercu/bleservices/gatt/gatt_audioservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class GattAudioService : public BleRcuAudioService
void updateFrameCountSupport(bool frameCountSupported);

void stateMachinePostEvent(const Event::Type event);
void stateMachinePostDelayedEvent(const Event::Type event, const int delay);
void stateMachineCancelDelayedEvents(const Event::Type eventType);

bool stateMachineIsIdle();

void setLastError(BleRcuAudioService::StreamingError error);
Expand Down Expand Up @@ -159,15 +162,17 @@ class GattAudioService : public BleRcuAudioService
static const Event::Type StopStreamingRequestEvent = Event::Type(Event::User + 4);

static const Event::Type NotificationsEnabledEvent = Event::Type(Event::User + 5);
static const Event::Type RetryStartNotifyEvent = Event::Type(Event::User + 6);

static const Event::Type StreamingStartedEvent = Event::Type(Event::User + 7);
static const Event::Type StreamingStoppedEvent = Event::Type(Event::User + 8);

static const Event::Type StreamingStartedEvent = Event::Type(Event::User + 6);
static const Event::Type StreamingStoppedEvent = Event::Type(Event::User + 7);
static const Event::Type GattErrorEvent = Event::Type(Event::User + 9);
static const Event::Type OutputPipeCloseEvent = Event::Type(Event::User + 10);

static const Event::Type GattErrorEvent = Event::Type(Event::User + 8);
static const Event::Type OutputPipeCloseEvent = Event::Type(Event::User + 9);
static const Event::Type AudioInfoTimeoutEvent = Event::Type(Event::User + 11);
static const Event::Type AudioLastFrameTimeoutEvent = Event::Type(Event::User + 12);

static const Event::Type AudioInfoTimeoutEvent = Event::Type(Event::User + 10);
static const Event::Type AudioLastFrameTimeoutEvent = Event::Type(Event::User + 11);
};

#endif // !defined(GATT_AUDIOSERVICE_H)
38 changes: 20 additions & 18 deletions src/ble/hal/blercu/bleservices/gatt/gatt_audioservice_rdk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ void GattAudioServiceRdk::stop()
}

void GattAudioServiceRdk::onEnteredIdle() {
stateMachineCancelDelayedEvents(RetryStartNotifyEvent);
stateMachineCancelDelayedEvents(GattErrorEvent);

if (m_audioDataCharacteristic) {
XLOGD_INFO("Disabling notifications for m_audioDataCharacteristic");
m_audioDataCharacteristic->disableNotifications();
Expand Down Expand Up @@ -141,14 +144,11 @@ void GattAudioServiceRdk::onEnteredEnableNotificationsState()
auto replyHandlerData = [this](PendingReply<> *reply)
{
if (reply->isError()) {
// this is bad if this happens as we won't get updates, so we install a timer to
// retry enabling notifications in a couple of seconds time
XLOGD_ERROR("failed to enable audio data notifications due to <%s>",
reply->errorMessage().c_str());

setLastError(StreamingError::InternalError);
stateMachinePostEvent(GattErrorEvent);

XLOGD_ERROR("failed to enable audio data notifications due to <%s>", reply->errorMessage().c_str());

// notifications are required for audio streaming, so if this fails we need to retry in a couple of seconds
stateMachineCancelDelayedEvents(RetryStartNotifyEvent);
stateMachinePostDelayedEvent(RetryStartNotifyEvent, 2000);
Comment thread
egalla204 marked this conversation as resolved.
} else {
// notifications enabled so post an event to the state machine
stateMachinePostEvent(NotificationsEnabledEvent);
Expand Down Expand Up @@ -199,8 +199,7 @@ void GattAudioServiceRdk::onEnteredStartStreamingState()
auto replyHandler = [this](PendingReply<> *reply)
{
if (reply->isError()) {
XLOGD_ERROR("failed to write audio control characteristic due to <%s>",
reply->errorMessage().c_str());
XLOGD_ERROR("failed to write audio control characteristic due to <%s>", reply->errorMessage().c_str());

setLastError(StreamingError::InternalError);
stateMachinePostEvent(GattErrorEvent);
Expand All @@ -211,12 +210,16 @@ void GattAudioServiceRdk::onEnteredStartStreamingState()
};


// the first byte is the codec to use, the second byte is to enable voice
const vector<uint8_t> value({ 0x01, 0x01 });

// send a write request to write the control characteristic
m_audioCtrlCharacteristic->writeValueWithoutResponse(value, PendingReply<>(getIsAlivePtr(), replyHandler));

if (!m_audioDataCharacteristic->notificationsEnabled()) {
XLOGD_ERROR("audio data notifications not enabled, cannot continue with audio stream");
setLastError(StreamingError::InternalError);
stateMachineCancelDelayedEvents(GattErrorEvent);
stateMachinePostDelayedEvent(GattErrorEvent, 10); // needs to be delayed to avoid re-entrancy issues with the state machine
} else {
// the first byte is the codec to use, the second byte is to enable voice
const vector<uint8_t> value({ 0x01, 0x01 });
m_audioCtrlCharacteristic->writeValueWithoutResponse(value, PendingReply<>(getIsAlivePtr(), replyHandler));
}
GattAudioService::onEnteredStartStreamingState();
}

Expand All @@ -237,8 +240,7 @@ void GattAudioServiceRdk::onEnteredStopStreamingState()
{
// check for errors
if (reply->isError()) {
XLOGD_ERROR("failed to write audio control characteristic due to <%s>",
reply->errorMessage().c_str());
XLOGD_ERROR("failed to write audio control characteristic due to <%s>", reply->errorMessage().c_str());

setLastError(StreamingError::InternalError);
stateMachinePostEvent(GattErrorEvent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,10 @@ void GattRemoteControlService::onEnteredState(int state)
requestAdvConfig();
requestAdvConfigCustomList();
requestUnpairReason();
requestRebootReason();
requestRawBatteryVoltage();

// requestRebootReason() posts InitialValuesRetrievedEvent in its reply handler, so queue it last after the other initial reads.
requestRebootReason();
Comment thread
egalla204 marked this conversation as resolved.

m_readySlots.invoke();

Expand Down
Loading