Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
openlcb::BLEHubPort Class Reference
Inheritance diagram for openlcb::BLEHubPort:
DirectHubPort< uint8_t[]> StateFlowBase openlcb::BLEProtocolEngine HubSource Destructable

Classes

class  InputFlow
 State flow that handles data arriving from this bluetooth connection. More...
 
struct  OutputDataEntry
 Holds the necessary information we need to keep in the queue about a single output entry. More...
 

Public Types

using SendFunction = std::function< void(const uint8_t *data, size_t len)>
 This function needs to be implemented by the application that has the specific BLE stack.
 

Public Member Functions

 BLEHubPort (DirectHubInterface< uint8_t[]> *hub, std::unique_ptr< MessageSegmenter > segmenter, Service *ble_write_service, SendFunction send_function, Notifiable *on_error=nullptr)
 Constructor.
 
void disconnect_and_delete () override
 Notifies the protocol engine that the connection has been terminated.
 
void ack ()
 Called by the BLE stack, when a send function is completed.
 
void nack ()
 Called by the BLE stack, when a send has failed.
 
void input_data (const uint8_t *data, size_t len)
 Called by the BLE stack when input data arrives from this remote endpoint.
 
void send (MessageAccessor< uint8_t[]> *msg) override
 Synchronous output routine called by the hub.
 
Action read_queue ()
 Entry point to the flow, when an outgoing message got into the queue and we are woken up.
 
Action do_write ()
 
Action shutdown_and_exit ()
 Invoked after pendingShutdown == true.
 
- Public Member Functions inherited from DirectHubPort< uint8_t[]>
virtual void send (MessageAccessor< uint8_t > *msg)=0
 Send some data out on this port.
 

Static Public Attributes

static constexpr size_t MAX_BYTES_PER_WRITE = 220
 How big can a single attribute write be? ESP's BLE implementation says 600 bytes.
 

Protected Types

typedef Buffer< OutputDataEntryBufferType
 Type of buffers we are enqueuing for output.
 
typedef Q QueueType
 Type of the queue used to keep the output buffer queue.
 

Protected Member Functions

void ack_helper ()
 
Atomiclock ()
 

Protected Attributes

bool pendingShutdown_: 1
 True if we have an error and we are trying to shut down.
 
bool notRunning_: 1
 1 if the state flow is paused, waiting for the notification.
 
bool waitingForAck_: 1
 true if the write flow is paused waiting for the BLE stack to ack the data.
 
QueueType pendingQueue_
 Contains buffers of OutputDataEntries to write.
 
OutputDataEntrypendingTail_ = nullptr
 Last tail pointer in the pendingQueue.
 
size_t totalPendingSize_ = 0
 Total number of bytes in the pendingQueue.
 
BufferPtr< OutputDataEntrycurrentHead_
 The buffer that is taken out of the queue while flushing.
 
SendFunction sendFunction_
 Function object used to send out actual data.
 
NotifiableonError_ = nullptr
 This notifiable will be called before exiting.
 
int sendPending_ {0}
 Number of in-flight messages sent but not acknowledged.
 
InputFlow input_
 

Additional Inherited Members

- Private Types inherited from StateFlowBase
typedef Action(StateFlowBase::* Callback) ()
 State Flow callback prototype.
 
- Private Member Functions inherited from StateFlowBase
void run () override
 Callback from the executor.
 
void notify () override
 Wakeup call arrived.
 
Serviceservice ()
 Return a pointer to the service I am bound to.
 
 StateFlowBase (Service *service)
 Constructor.
 
 ~StateFlowBase ()
 Destructor.
 
void reset_flow (Callback c)
 Resets the flow to the specified state.
 
bool is_state (Callback c)
 
bool is_terminated ()
 
void start_flow (Callback c)
 Resets the flow to the specified state and starts it.
 
Action again ()
 Call the current state again via call_immediately.
 
Action exit ()
 Terminate current StateFlow activity.
 
Action delete_this ()
 Terminates the flow and deletes *this.
 
Action set_terminated ()
 Sets the flow to terminated state.
 
Action call_immediately (Callback c)
 Imediately call the next state upon return.
 
Action wait ()
 Wait for an asynchronous call.
 
Action wait_and_call (Callback c)
 Wait for resource to become available before proceeding to next state.
 
template<class T >
Action allocate_and_call (FlowInterface< Buffer< T > > *target_flow, Callback c, Pool *pool=nullptr)
 Allocates a buffer from a pool and proceed to the next state when allocation is successful.
 
Action allocate_and_call (Callback c, QAsync *queue)
 Allocates an entry from an asynchronous queue, and transitions to a state once the allocation is complete.
 
template<class T >
Buffer< T > * full_allocation_result (FlowInterface< Buffer< T > > *target_flow)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
T * full_allocation_result (TypedQAsync< T > *queue)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
void cast_allocation_result (T **member)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
Buffer< T > * get_allocation_result (FlowInterface< Buffer< T > > *target_flow)
 Takes the result of the asynchronous allocation.
 
Action yield_and_call (Callback c)
 Place the current flow to the back of the executor, and transition to a new state after we get the CPU again.
 
Action yield ()
 Place the current flow to the back of the executor, and re-try the current state after we get the CPU again.
 
Action sleep_and_call (::Timer *timer, long long timeout_nsec, Callback c)
 Suspends execution of this control flow for a specified time.
 
template<class T , typename... Args>
Action invoke_subflow_and_wait (FlowInterface< Buffer< T > > *target_flow, Callback c, Args &&... args)
 Calls a helper flow to perform some actions.
 
Action read_repeated (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Blocks until size bytes are read and then invokes the next state.
 
Action read_single (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Attempts to read at most size_t bytes, and blocks the caller until at least one byte is read.
 
Action read_nonblocking (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Attempts to read at most size bytes, and then invokes the next state, even if only zero bytes are available right now.
 
Action read_repeated_with_timeout (StateFlowTimedSelectHelper *helper, long long timeout_nsec, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Blocks until size bytes are read, or a timeout expires.
 
Action internal_try_read ()
 Implementation state that gets repeatedly called upon every wakeup and tries to make progress on reading.
 
Action write_repeated (StateFlowSelectHelper *helper, int fd, const void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Writes some data into a file descriptor, repeating the operation as necessary until all bytes are written.
 
Action internal_try_write ()
 Implementation state that gets repeatedly called upon every wakeup and tries to make progress on writing.
 
- Private Member Functions inherited from Executable
void test_deletion ()
 
- Private Member Functions inherited from QMember
void init ()
 Initiailize a QMember, in place of a public placement construction.
 
 QMember ()
 Constructor.
 
 ~QMember ()
 Destructor.
 
- Static Private Member Functions inherited from StateFlowBase
template<class T , typename... Args>
static void invoke_subflow_and_ignore_result (FlowInterface< Buffer< T > > *target_flow, Args &&... args)
 Calls a helper flow to perform some actions.
 
- Private Attributes inherited from QMember
QMembernext
 pointer to the next member in the queue
 

Detailed Description

Definition at line 50 of file BLEHubPort.hxx.

Member Typedef Documentation

◆ BufferType

Type of buffers we are enqueuing for output.

Definition at line 512 of file BLEHubPort.hxx.

◆ QueueType

typedef Q openlcb::BLEHubPort::QueueType
protected

Type of the queue used to keep the output buffer queue.

Definition at line 514 of file BLEHubPort.hxx.

◆ SendFunction

using openlcb::BLEHubPort::SendFunction = std::function<void(const uint8_t *data, size_t len)>

This function needs to be implemented by the application that has the specific BLE stack.

Performs the actual send. Synchronous, with the expectation being that once this function returns, the data is copied away from the buffer and is sent or will eventually be sent.

Parameters
datadata payload to send
lennumber of bytes to send

Definition at line 63 of file BLEHubPort.hxx.

Constructor & Destructor Documentation

◆ BLEHubPort()

openlcb::BLEHubPort::BLEHubPort ( DirectHubInterface< uint8_t[]> *  hub,
std::unique_ptr< MessageSegmenter segmenter,
Service ble_write_service,
SendFunction  send_function,
Notifiable on_error = nullptr 
)
inline

Constructor.

Parameters
hubpointer to the direct hub instance. Externally owned.
segmenterSegments incoming data into messages. Ownership will be taken. Typically created using creat_gc_message_segmenter().
ble_write_serviceThread on which the send_function will be invoked.
send_functionFunction that performs the actual send. See {} on_error Will be notified upon disconnect.

Definition at line 80 of file BLEHubPort.hxx.

Member Function Documentation

◆ ack()

void openlcb::BLEHubPort::ack ( )
inline

Called by the BLE stack, when a send function is completed.

Definition at line 123 of file BLEHubPort.hxx.

◆ ack_helper()

void openlcb::BLEHubPort::ack_helper ( )
inlineprotected

Definition at line 306 of file BLEHubPort.hxx.

◆ disconnect_and_delete()

void openlcb::BLEHubPort::disconnect_and_delete ( )
inlineoverridevirtual

Notifies the protocol engine that the connection has been terminated.

The implementation must (eventually) call delete this.

Implements openlcb::BLEProtocolEngine.

Definition at line 98 of file BLEHubPort.hxx.

◆ do_write()

Action openlcb::BLEHubPort::do_write ( )
inline

Definition at line 234 of file BLEHubPort.hxx.

◆ input_data()

void openlcb::BLEHubPort::input_data ( const uint8_t *  data,
size_t  len 
)
inline

Called by the BLE stack when input data arrives from this remote endpoint.

Parameters
datapayload that arrived. The data will be copied inline, and does not need to exist beyond when this function returns.
lennumber of bytes in the data payload.

Definition at line 143 of file BLEHubPort.hxx.

◆ lock()

Atomic * openlcb::BLEHubPort::lock ( )
inlineprotected
Returns
lock usable for the write flow and the port altogether.

Definition at line 517 of file BLEHubPort.hxx.

◆ nack()

void openlcb::BLEHubPort::nack ( )
inline

Called by the BLE stack, when a send has failed.

Definition at line 130 of file BLEHubPort.hxx.

◆ read_queue()

Action openlcb::BLEHubPort::read_queue ( )
inline

Entry point to the flow, when an outgoing message got into the queue and we are woken up.

Definition at line 207 of file BLEHubPort.hxx.

◆ send()

void openlcb::BLEHubPort::send ( MessageAccessor< uint8_t[]> *  msg)
inlineoverride

Synchronous output routine called by the hub.

Todo:
we should try to collect the bytes into a buffer first before enqueueing them.

Definition at line 149 of file BLEHubPort.hxx.

◆ shutdown_and_exit()

Action openlcb::BLEHubPort::shutdown_and_exit ( )
inline

Invoked after pendingShutdown == true.

At this point nothing gets added to the pending queue.

Definition at line 288 of file BLEHubPort.hxx.

Member Data Documentation

◆ currentHead_

BufferPtr<OutputDataEntry> openlcb::BLEHubPort::currentHead_
protected

The buffer that is taken out of the queue while flushing.

This variable is not locked, because it is owned by the state flow states.

Definition at line 544 of file BLEHubPort.hxx.

◆ input_

InputFlow openlcb::BLEHubPort::input_
protected

Definition at line 556 of file BLEHubPort.hxx.

◆ MAX_BYTES_PER_WRITE

constexpr size_t openlcb::BLEHubPort::MAX_BYTES_PER_WRITE = 220
staticconstexpr

How big can a single attribute write be? ESP's BLE implementation says 600 bytes.

We keep some buffer.

Definition at line 67 of file BLEHubPort.hxx.

◆ notRunning_

bool openlcb::BLEHubPort::notRunning_
protected

1 if the state flow is paused, waiting for the notification.

Definition at line 526 of file BLEHubPort.hxx.

◆ onError_

Notifiable* openlcb::BLEHubPort::onError_ = nullptr
protected

This notifiable will be called before exiting.

Definition at line 551 of file BLEHubPort.hxx.

◆ pendingQueue_

QueueType openlcb::BLEHubPort::pendingQueue_
protected

Contains buffers of OutputDataEntries to write.

lock() is the internal lock of this object.

Definition at line 534 of file BLEHubPort.hxx.

◆ pendingShutdown_

bool openlcb::BLEHubPort::pendingShutdown_
protected

True if we have an error and we are trying to shut down.

Causes all outgoing data to be thrown away.

Definition at line 524 of file BLEHubPort.hxx.

◆ pendingTail_

OutputDataEntry* openlcb::BLEHubPort::pendingTail_ = nullptr
protected

Last tail pointer in the pendingQueue.

If queue is empty, nullptr. Protected by pendingQueue_.lock().

Definition at line 537 of file BLEHubPort.hxx.

◆ sendFunction_

SendFunction openlcb::BLEHubPort::sendFunction_
protected

Function object used to send out actual data.

This is synchronously operating, meaning it makes a copy of the data to the stack for sending it out.

Definition at line 549 of file BLEHubPort.hxx.

◆ sendPending_

int openlcb::BLEHubPort::sendPending_ {0}
protected

Number of in-flight messages sent but not acknowledged.

Definition at line 554 of file BLEHubPort.hxx.

◆ totalPendingSize_

size_t openlcb::BLEHubPort::totalPendingSize_ = 0
protected

Total number of bytes in the pendingQueue.

This does not include data that is in currentHead_. Protected by lock().

Definition at line 540 of file BLEHubPort.hxx.

◆ waitingForAck_

bool openlcb::BLEHubPort::waitingForAck_
protected

true if the write flow is paused waiting for the BLE stack to ack the data.

Should be notified when the acknowledgements make sendPending_ <=

Definition at line 530 of file BLEHubPort.hxx.


The documentation for this class was generated from the following file: