35#ifndef _OPENLCB_BLEHUBPORT_HXX_
36#define _OPENLCB_BLEHUBPORT_HXX_
63 using SendFunction = std::function<void(
const uint8_t *data,
size_t len)>;
81 std::unique_ptr<MessageSegmenter> segmenter,
Service *ble_write_service,
88 , input_(this, hub, std::move(segmenter))
95 hub->register_port(
this);
171 b->
data()->buf_.reset(msg->buf_);
174 b->
set_done(msg->done_->new_child());
241 const uint8_t *read_ptr;
244 read_ptr = b.data_read_pointer(&num_bytes);
255 b.data_read_advance(num_bytes);
324 std::unique_ptr<MessageSegmenter> segmenter)
346 uint8_t *dst =
nullptr;
351 g_direct_hub_data_pool.
alloc(&p);
359 memcpy(dst, data, free);
399 ssize_t segment_size =
segmenter_->segment_message(ptr, len);
DynamicPool * mainBufferPool
main buffer pool instance
AutoReleaseBuffer< T > BufferPtr
Smart pointer for buffers.
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
See OSMutexLock in os/OS.hxx.
Lightweight locking class for protecting small critical sections.
void set_done(BarrierNotifiable *done)
Specifies that a given BarrierNotifiable must be called when the Buffer is deallocated (unreffed to z...
Base class for all QMember types that hold data in an expandable format.
void unref()
Decrement count.
T * data()
get a pointer to the start of the data.
Proxy Pool that can allocate DataBuffer objects of a certain size.
void alloc(DataBuffer **result)
Get a free item out of the pool with untyped data of the size specified in the constructor.
Specialization of the Buffer class that is designed for storing untyped data arrays.
Interface for a the central part of a hub.
virtual MessageAccessor< T > * mutable_message()=0
Accessor to fill in the message payload.
virtual void enqueue_send(Executable *caller)=0
Signals that the caller wants to send a message to the hub.
virtual void unregister_port(DirectHubPort< T > *port)=0
Synchronously removes a port from this hub.
virtual void do_send()=0
Sends a message to the hub.
Interface for a downstream port of a hub (aka a target to send data to).
void sync_run(std::function< void()> fn)
Synchronously runs a closure on this executor.
A class that keeps ownership of a chain of linked DataBuffer references.
bool try_append_from(const LinkedDataBufferPtr &o, bool add_link=false)
Attempt to combine *this with o into a single LinkedDataBufferPtr this.
uint8_t * data_write_pointer()
void data_read_advance(size_t len)
Advances the head pointer.
void reset(const LinkedDataBufferPtr &o, ssize_t size=-1)
Takes a reference of o, taking a prefix of len size (or all the data).
void append_empty_buffer(DataBuffer *buf)
Adds an empty buffer to the end of this buffer chain.
void data_write_advance(size_t len)
Advances the tail pointer after a write occurred into the tail.
const uint8_t * data_read_pointer(size_t *len)
Retrieves a pointer where data can be read out of the buffer.
An object that can schedule itself on an executor to run.
void alloc(Buffer< BufferType > **result, Executable *flow=NULL)
Get a free item out of the pool.
This class implements a linked list "queue" of buffers.
void insert_locked(QMember *item, unsigned index=0)
Add an item to the back of the queue.
Result next_locked()
Get an item from the front of the queue.
size_t pending(unsigned index)
Get the number of pending items in the queue.
bool empty(unsigned index)
Test if the queue is empty.
QMember * next(unsigned index)
Get an item from the front of the queue.
Collection of related state machines that pend on incoming messages.
ExecutorBase * executor()
Return type for a state flow callback.
Base class for state machines.
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 CP...
Service * service()
Return a pointer to the service I am bound to.
void notify() override
Wakeup call arrived.
StateFlowBase()
Default constructor.
Action yield()
Place the current flow to the back of the executor, and re-try the current state after we get the CPU...
Action delete_this()
Terminates the flow and deletes *this.
Action wait()
Wait for an asynchronous call.
Action again()
Call the current state again via call_immediately.
Action call_immediately(Callback c)
Imediately call the next state upon return.
Action wait_and_call(Callback c)
Wait for resource to become available before proceeding to next state.
bool notRunning_
1 if the state flow is paused, waiting for the notification.
void send(MessageAccessor< uint8_t[]> *msg) override
Synchronous output routine called by the hub.
std::function< void(const uint8_t *data, size_t len)> SendFunction
This function needs to be implemented by the application that has the specific BLE stack.
static constexpr size_t MAX_BYTES_PER_WRITE
How big can a single attribute write be? ESP's BLE implementation says 600 bytes.
Action shutdown_and_exit()
Invoked after pendingShutdown == true.
SendFunction sendFunction_
Function object used to send out actual data.
void ack()
Called by the BLE stack, when a send function is completed.
size_t totalPendingSize_
Total number of bytes in the pendingQueue.
bool pendingShutdown_
True if we have an error and we are trying to shut down.
void nack()
Called by the BLE stack, when a send has failed.
QueueType pendingQueue_
Contains buffers of OutputDataEntries to write.
void disconnect_and_delete() override
Notifies the protocol engine that the connection has been terminated.
Buffer< OutputDataEntry > BufferType
Type of buffers we are enqueuing for output.
void input_data(const uint8_t *data, size_t len)
Called by the BLE stack when input data arrives from this remote endpoint.
OutputDataEntry * pendingTail_
Last tail pointer in the pendingQueue.
bool waitingForAck_
true if the write flow is paused waiting for the BLE stack to ack the data.
Action read_queue()
Entry point to the flow, when an outgoing message got into the queue and we are woken up.
BLEHubPort(DirectHubInterface< uint8_t[]> *hub, std::unique_ptr< MessageSegmenter > segmenter, Service *ble_write_service, SendFunction send_function, Notifiable *on_error=nullptr)
Constructor.
Notifiable * onError_
This notifiable will be called before exiting.
BufferPtr< OutputDataEntry > currentHead_
The buffer that is taken out of the queue while flushing.
int sendPending_
Number of in-flight messages sent but not acknowledged.
Q QueueType
Type of the queue used to keep the output buffer queue.
Shared base class for protocol implementation on a per-BLE-connection basis.
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int INFO
Loglevel that is printed by default, reporting some status information.
static const int ALWAYS
Loglevel that is always printed.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
QMember * item
item pulled from queue
Holds the necessary information we need to keep in the queue about a single output entry.