6#include "dawn/proto/ipc/simple.hxx"
8#include "dawn/common/poll_loop.hxx"
20int CProtoIpc::sendFrame(uint8_t cmd,
const uint8_t *payload,
size_t len)
22 uint8_t frame[FRAME_MAX_PAYLOAD + FRAME_MIN_LEN];
28 tosend = FRAME_MIN_LEN + len;
31 if (len > FRAME_MAX_PAYLOAD || txfd < 0)
33 DAWNERR(
"IPC sendFrame invalid state cmd=0x%02x len=%zu fd=%d\n", cmd, len, txfd);
38 frame[1] = (uint8_t)(len & 0xFF);
39 frame[2] = (uint8_t)((len >> 8) & 0xFF);
44 std::memcpy(&frame[4], payload, len);
48 frame[4 + len] = (uint8_t)(crc & 0xFF);
49 frame[5 + len] = (uint8_t)((crc >> 8) & 0xFF);
53 ret = write(txfd, &frame[sent], tosend - sent);
61 DAWNERR(
"IPC write failed cmd=0x%02x ret=%d errno=%d\n", cmd, (
int)ret, errno);
67 DAWNERR(
"IPC write returned zero bytes\n");
77void CProtoIpc::thread()
82 std::memset(fds, 0,
sizeof(fds));
85 fds[0].events = POLLIN;
90 callbacks.beforePoll = CProtoIpc::cbPollBefore;
91 callbacks.afterPoll = CProtoIpc::cbPollAfter;
92 callbacks.onPollReady = CProtoIpc::cbPollOnReady;
97int CProtoIpc::pollBefore(
struct pollfd *pfds, nfds_t nfds)
99 if (pfds ==
nullptr || nfds == 0)
108void CProtoIpc::pollAfter(
int ret)
110 if (ret < 0 && errno != EINTR)
112 DAWNERR(
"IPC poll failed %d\n", -errno);
116int CProtoIpc::pollOnReady(
struct pollfd *pfds, nfds_t nfds,
int pollRet)
124 if (pfds ==
nullptr || nfds == 0 || pollRet <= 0)
129 if ((pfds[0].revents & (POLLIN | POLLERR | POLLHUP)) == 0)
134 rdret = read(rxfd, chunk,
sizeof(chunk));
137 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
142 DAWNERR(
"IPC read failed ret=%d errno=%d\n", (
int)rdret, errno);
153 for (i = 0; i < (size_t)rdret; i++)
163 rxbuffer[parserPos] = byte;
175 rxbuffer[parserPos] = byte;
183 parserLen |= (uint16_t)(
byte << 8);
184 if (parserLen > FRAME_MAX_PAYLOAD)
191 rxbuffer[parserPos] = byte;
199 rxbuffer[parserPos++] = byte;
201 if (parserPos >= (
size_t)(FRAME_MIN_LEN + parserLen))
206 DAWNERR(
"IPC handleFrame failed ret=%d\n", ret);
221int CProtoIpc::cbPollBefore(
void *priv,
struct pollfd *pfds, nfds_t nfds)
231 return self->pollBefore(pfds, nfds);
234void CProtoIpc::cbPollAfter(
void *priv,
struct pollfd *pfds, nfds_t nfds,
int ret)
246 self->pollAfter(ret);
249int CProtoIpc::cbPollOnReady(
void *priv,
struct pollfd *pfds, nfds_t nfds,
int pollRet)
259 return self->pollOnReady(pfds, nfds, pollRet);
262int CProtoIpc::configureDesc(
const CDescObject &desc)
269 for (
size_t i = 0; i < desc.
getSize(); i++)
275 DAWNERR(
"Unsupported IPC config 0x%08" PRIx32
"\n", item->
cfgid.
v);
281 case PROTO_IPC_CFG_IOBIND:
285 SProtoIpcIOBind *tmp;
287 tmp =
reinterpret_cast<SProtoIpcIOBind *
>(item->
data + j);
290 j +=
sizeof(SProtoIpcIOBind) / 4;
296 case PROTO_IPC_CFG_RX_PATH:
298 rxPath =
reinterpret_cast<const char *
>(&item->
data);
302 case PROTO_IPC_CFG_TX_PATH:
304 txPath =
reinterpret_cast<const char *
>(&item->
data);
310 DAWNERR(
"Unsupported IPC config 0x%08" PRIx32
"\n", item->
cfgid.
v);
319int CProtoIpc::ensureFifo(
const char *path)
327 DAWNERR(
"IPC FIFO path not configured\n");
331 ret = mkfifo(path, 0666);
341 ret = stat(path, &st);
342 if (ret == 0 && S_ISFIFO(st.st_mode))
362 DAWNERR(
"Failed to create FIFO %s errno=%d\n", path, err);
367int CProtoIpc::fifoInit()
371 ret = ensureFifo(rxPath);
377 ret = ensureFifo(txPath);
383 rxfd = open(rxPath, O_RDWR | O_NONBLOCK);
386 DAWNERR(
"Failed to open IPC RX FIFO %s errno=%d\n", rxPath, errno);
390 txfd = open(txPath, O_RDWR | O_NONBLOCK);
393 DAWNERR(
"Failed to open IPC TX FIFO %s errno=%d\n", txPath, errno);
399 DAWNINFO(
"IPC protocol initialized rx=%s tx=%s\n", rxPath, txPath);
404CProtoIpc::~CProtoIpc()
413 ret = configureDesc(
getDesc());
416 DAWNERR(
"IPC configure failed (error %d)\n", ret);
436 DAWNERR(
"failed to create data %d\n", ret);
440#ifdef CONFIG_DAWN_IO_NOTIFY
441 ret = setupNotifications();
444 DAWNERR(
"failed to setup notifications %d\n", ret);
453#ifdef CONFIG_DAWN_IO_NOTIFY
454 destroyNotifications();
491 DAWNERR(
"failed to start thread %d\n", ret);
495 DAWNINFO(
"IPC protocol started\n");
502#ifdef CONFIG_DAWN_IO_NOTIFY
503 cleanupNotifications();
508 DAWNINFO(
"IPC protocol stopped\n");
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
CDescObject & getDesc()
Get descriptor object for this object.
static int run(CThreadedObject &threadCtl, struct pollfd *pfds, nfds_t nfds, int timeoutMs, const SPollLoopCallbacks &callbacks, void *priv)
Run poll loop until quit is requested.
@ PROTO_CLASS_IPC
FIFO-based local IPC protocol.
Simple FIFO-based IPC transport for local Dawn communication.
int doStart()
Start implementation hook.
int deinit()
De-initialize object.
int configure()
Configure object from descriptor data.
int doStop()
Stop implementation hook.
int init()
One-time initialize object after bindings are resolved.
bool hasThread() const
Check if a background thread is active.
static uint8_t FRAME_SYNC
Frame structure constants.
void allocObject(SProtoSimpleIOBind *cfg)
Store an allocated IO binding.
uint16_t calculateCrc(const uint8_t *data, size_t len)
Calculate 16-bit CRC checksum.
int handleFrame(const uint8_t *frame, size_t len)
Process a received frame.
int createBuffers()
Allocate shared per-IO data buffers.
int destroyBuffers()
Destroy shared per-IO data buffers.
bool workerThreadRunning() const
Check if the worker thread is running.
int stopWorkerThread()
Stop the worker thread.
int startWorkerThread(Func &&func)
Start the worker thread with a given function.
CThreadedObject & workerThread()
Get a reference to this thread controller.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
Callback set for poll-based worker loops.
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.