1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef CHPP_TRANSPORT_H_
18 #define CHPP_TRANSPORT_H_
19
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23
24 #include "chpp/condition_variable.h"
25 #include "chpp/link.h"
26 #include "chpp/macros.h"
27 #include "chpp/mutex.h"
28 #include "chpp/notifier.h"
29 #include "chpp/transport_signals.h"
30 #include "chpp/work_monitor.h"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /************************************************
37 * Public Definitions
38 ***********************************************/
39
40 /**
41 * CHPP Transport layer reset timeout in ns. The transport layer will attempt
42 * another reset if the previous reset is not acked in time.
43 */
44 #ifndef CHPP_TRANSPORT_RESET_TIMEOUT_NS
45 #define CHPP_TRANSPORT_RESET_TIMEOUT_NS \
46 (UINT64_C(1500) * CHPP_NSEC_PER_MSEC) // 1500 ms
47 #endif
48
49 /**
50 * CHPP Transport layer timeout for tx packets.
51 */
52 #ifndef CHPP_TRANSPORT_TX_TIMEOUT_NS
53 #define CHPP_TRANSPORT_TX_TIMEOUT_NS \
54 (UINT64_C(100) * CHPP_NSEC_PER_MSEC) // 100 ms
55 #endif
56
57 /**
58 * CHPP Transport layer timeout for rx packets.
59 */
60 #ifndef CHPP_TRANSPORT_RX_TIMEOUT_NS
61 #define CHPP_TRANSPORT_RX_TIMEOUT_NS \
62 (UINT64_C(80) * CHPP_NSEC_PER_MSEC) // 80 ms
63 #endif
64
65 /**
66 * CHPP Transport layer maximum retransmission attempts, after which a reset is
67 * attempted. Setting this to zero disables retransmissions.
68 */
69 #ifndef CHPP_TRANSPORT_MAX_RETX
70 #define CHPP_TRANSPORT_MAX_RETX UINT16_C(4)
71 #endif
72
73 /**
74 * CHPP Transport layer maximum reset attempts. Current functional values are 1
75 * or higher (setting to 0 currently functions identically to 1).
76 */
77 #ifndef CHPP_TRANSPORT_MAX_RESET
78 #define CHPP_TRANSPORT_MAX_RESET UINT16_C(3)
79 #endif
80
81 /**
82 * CHPP Transport layer predefined timeout values.
83 */
84 #define CHPP_TRANSPORT_TIMEOUT_INFINITE UINT64_MAX
85 #define CHPP_TRANSPORT_TIMEOUT_IMMEDIATE 0
86
87 // This lint rule is meant to ensure we make appropriate test updates whenever
88 // there are changes to the transport protocol.
89 // LINT.IfChange
90 /**
91 * CHPP Transport header flags bitmap
92 *
93 * @defgroup CHPP_TRANSPORT_FLAG
94 * @{
95 */
96 // This packet concludes a (fragmented or unfragmented) datagram
97 #define CHPP_TRANSPORT_FLAG_FINISHED_DATAGRAM 0x00
98 // Set if packet is part of a fragmented datagram, except for the last fragment
99 #define CHPP_TRANSPORT_FLAG_UNFINISHED_DATAGRAM 0x01
100 // Reserved for future use
101 #define CHPP_TRANSPORT_FLAG_RESERVED 0xfe
102 /** @} */
103
104 /**
105 * Preamble (i.e. packet start delimiter) for this version of CHPP is "Ch".
106 * Any future backwards-incompatible versions of CHPP Transport will use a
107 * different preamble.
108 *
109 * @defgroup CHPP_PREAMBLE
110 * @{
111 */
112 #define CHPP_PREAMBLE_DATA 0x6843
113 #define CHPP_PREAMBLE_LEN_BYTES 2
114 /** @} */
115
116 /**
117 * Macros for a specific byte in the CHPP_PREAMBLE.
118 * Using the CHPP_PREAMBLE_BYTE_... macros are preferred due to a reduced risk
119 * of mistakes.
120 */
121 #define chppPreambleByte(loc) \
122 ((CHPP_PREAMBLE_DATA >> (8 * (CHPP_PREAMBLE_LEN_BYTES - (loc)-1))) & 0xff)
123 #define CHPP_PREAMBLE_BYTE_FIRST chppPreambleByte(0)
124 #define CHPP_PREAMBLE_BYTE_SECOND chppPreambleByte(1)
125
126 /**
127 * Maximum number of datagrams in the Tx queue.
128 * CHPP will return an error if it is provided with a new Tx datagram when this
129 * queue is full.
130 * To be safe, this should be less than half of the maximum uint8_t value.
131 * Otherwise, ChppTxDatagramQueue should be updated accordingly.
132 */
133 #define CHPP_TX_DATAGRAM_QUEUE_LEN ((uint8_t)16)
134
135 /**
136 * Encoding overhead of the transport layer in bytes.
137 */
138 #define CHPP_TRANSPORT_ENCODING_OVERHEAD_BYTES \
139 ((uint16_t)(CHPP_PREAMBLE_LEN_BYTES + sizeof(struct ChppTransportHeader) + \
140 sizeof(struct ChppTransportFooter)))
141
142 /************************************************
143 * Status variables to store context in lieu of global variables (this)
144 ***********************************************/
145
146 /**
147 * Error codes optionally reported in ChppTransportHeader (Least significant
148 * nibble of int8_t packetCode).
149 */
150 #define CHPP_TRANSPORT_ERROR_MASK LEAST_SIGNIFICANT_NIBBLE
151 #define CHPP_TRANSPORT_GET_ERROR(value) \
152 ((enum ChppTransportErrorCode)( \
153 (value)&CHPP_TRANSPORT_ERROR_MASK)) // TODO: Consider checking if this
154 // maps into a valid enum
155 enum ChppTransportErrorCode {
156 //! No error reported (either ACK or implicit NACK)
157 CHPP_TRANSPORT_ERROR_NONE = 0,
158 //! Checksum failure
159 CHPP_TRANSPORT_ERROR_CHECKSUM = 1,
160 //! Out of memory
161 CHPP_TRANSPORT_ERROR_OOM = 2,
162 //! Busy
163 CHPP_TRANSPORT_ERROR_BUSY = 3,
164 //! Invalid header
165 CHPP_TRANSPORT_ERROR_HEADER = 4,
166 //! Out of order
167 CHPP_TRANSPORT_ERROR_ORDER = 5,
168 //! Timeout
169 CHPP_TRANSPORT_ERROR_TIMEOUT = 6,
170 //! Too many retries
171 CHPP_TRANSPORT_ERROR_MAX_RETRIES = 7,
172 //! Message incomprehensible at App Layer
173 CHPP_TRANSPORT_ERROR_APPLAYER = 0xF,
174 };
175
176 /**
177 * Packet attributes in ChppTransportHeader (Most significant nibble (MSN) of
178 * int8_t packetCode).
179 */
180 #define CHPP_TRANSPORT_ATTR_VALUE(value) (((value)&0x0f) << 4)
181 #define CHPP_TRANSPORT_ATTR_MASK MOST_SIGNIFICANT_NIBBLE
182 #define CHPP_TRANSPORT_GET_ATTR(value) \
183 ((enum ChppTransportPacketAttributes)( \
184 (value)&CHPP_TRANSPORT_ATTR_MASK)) // TODO: Consider checking if this
185 // maps into a valid enum
186
187 enum ChppTransportPacketAttributes {
188 //! None
189 CHPP_TRANSPORT_ATTR_NONE = CHPP_TRANSPORT_ATTR_VALUE(0),
190 //! Reset
191 CHPP_TRANSPORT_ATTR_RESET = CHPP_TRANSPORT_ATTR_VALUE(1),
192 //! Reset Ack
193 CHPP_TRANSPORT_ATTR_RESET_ACK = CHPP_TRANSPORT_ATTR_VALUE(2),
194 //! Transport-Layer Loopback Request
195 CHPP_TRANSPORT_ATTR_LOOPBACK_REQUEST = CHPP_TRANSPORT_ATTR_VALUE(3),
196 //! Transport-Layer Loopback Response
197 CHPP_TRANSPORT_ATTR_LOOPBACK_RESPONSE = CHPP_TRANSPORT_ATTR_VALUE(4),
198 };
199
200 #define CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(attr, error) \
201 ((uint8_t)(attr & CHPP_TRANSPORT_ATTR_MASK) | \
202 (uint8_t)(error & CHPP_TRANSPORT_ERROR_MASK))
203
204 /**
205 * CHPP Transport Layer header (not including the preamble)
206 */
207 CHPP_PACKED_START
208 struct ChppTransportHeader {
209 //! Flags bitmap, defined as CHPP_TRANSPORT_FLAG_...
210 uint8_t flags;
211
212 //! LS Nibble: Defined in enum ChppTransportErrorCode
213 //! MS Nibble: Defined in enum ChppTransportPacketAttributes
214 uint8_t packetCode;
215
216 //! Next expected sequence number for a payload-bearing packet
217 uint8_t ackSeq;
218
219 //! Sequence number
220 uint8_t seq;
221
222 //! Payload length in bytes (not including header / footer)
223 uint16_t length;
224
225 //! Reserved
226 uint16_t reserved;
227 } CHPP_PACKED_ATTR;
228 CHPP_PACKED_END
229
230 /**
231 * CHPP Transport Layer footer (containing the checksum)
232 */
233 CHPP_PACKED_START
234 struct ChppTransportFooter {
235 uint32_t checksum; // IEEE CRC-32 initialized to 0xFFFFFFFF
236 } CHPP_PACKED_ATTR;
237 CHPP_PACKED_END
238
239 enum ChppRxState {
240 //! Waiting for, or processing, the preamble (i.e. packet start delimiter)
241 //! Moves to CHPP_STATE_HEADER as soon as it has seen a complete preamble.
242 CHPP_STATE_PREAMBLE = 0,
243
244 //! Processing the packet header. Moves to CHPP_STATE_PAYLOAD after processing
245 //! the expected length of the header.
246 CHPP_STATE_HEADER = 1,
247
248 //! Copying the packet payload. The payload length is determined by the
249 //! header.
250 //! Moves to CHPP_STATE_FOOTER afterwards.
251 CHPP_STATE_PAYLOAD = 2,
252
253 //! Processing the packet footer (checksum) and responding accordingly. Moves
254 //! to CHPP_STATE_PREAMBLE afterwards.
255 CHPP_STATE_FOOTER = 3,
256 };
257
258 enum ChppResetState {
259 CHPP_RESET_STATE_RESETTING = 0, //! Reset in progress
260 CHPP_RESET_STATE_NONE = 1, //! Not in the middle of a reset
261 CHPP_RESET_STATE_PERMANENT_FAILURE = 2, //! Failed, will not retry
262 };
263
264 /**
265 * Semantic Versioning system of CHRE.
266 */
267 CHPP_PACKED_START
268 struct ChppVersion {
269 //! Major version of (breaking changes).
270 uint8_t major;
271
272 //! Minor version (backwards compatible changes).
273 uint8_t minor;
274
275 //! Patch version (bug fixes).
276 uint16_t patch;
277 } CHPP_PACKED_ATTR;
278 CHPP_PACKED_END
279
280 /**
281 * Payload that is sent along reset and reset-ack packets.
282 */
283 CHPP_PACKED_START
284 struct ChppTransportConfiguration {
285 //! CHPP transport version.
286 struct ChppVersion version;
287
288 //! CHPP 1.0.0 unused "Receive MTU size".
289 uint16_t reserved1;
290
291 //! CHPP 1.0.0 unused "window size".
292 uint16_t reserved2;
293
294 //! CHPP 1.0.0 unused "Transport layer timeout in milliseconds".
295 uint16_t reserved3;
296 } CHPP_PACKED_ATTR;
297 CHPP_PACKED_END
298 // LINT.ThenChange(chpp/test/packet_util.cpp)
299
300 struct ChppRxStatus {
301 //! Current receiving state, as described in ChppRxState.
302 enum ChppRxState state;
303
304 //! Location counter in bytes within each state. Must always be reinitialized
305 //! to 0 when switching states.
306 size_t locInState;
307
308 //! Next expected sequence number (for a payload-bearing packet)
309 uint8_t expectedSeq;
310
311 //! Packet (error) code, if any, of the last received packet
312 uint8_t receivedPacketCode;
313
314 //! Last received ACK sequence number (i.e. next expected sequence number for
315 //! an outgoing payload-bearing packet)
316 uint8_t receivedAckSeq;
317
318 //! Time when starting to receive the current packet (i.e. after preamble).
319 uint64_t packetStartTimeNs;
320
321 //! Location counter in bytes within the current Rx datagram.
322 size_t locInDatagram;
323
324 //! The total number of data received in chppRxDataCb.
325 size_t numTotalDataBytes;
326
327 //! The timestamp when the transport received any data through chppRxDataCb.
328 uint32_t lastDataTimeMs;
329
330 //! The timestamp when the transport received a good RX packet.
331 uint32_t lastGoodPacketTimeMs;
332 };
333
334 struct ChppTxStatus {
335 //! Last sent ACK sequence number (i.e. next expected sequence number for
336 //! an incoming payload-bearing packet)
337 uint8_t sentAckSeq;
338
339 //! Last sent sequence number (irrespective of whether it has been received /
340 //! ACKed or not)
341 uint8_t sentSeq;
342
343 //! Does the transport layer have any packets (with or without payload) it
344 //! needs to send out?
345 bool hasPacketsToSend;
346
347 //! Error code, if any, of the next packet the transport layer will send out.
348 uint8_t packetCodeToSend;
349
350 //! How many times the last sent sequence number has been (re-)sent.
351 size_t txAttempts;
352
353 //! Time when the last packet was sent to the link layer.
354 uint64_t lastTxTimeNs;
355
356 //! How many bytes of the front-of-queue datagram has been sent out
357 size_t sentLocInDatagram;
358
359 //! Note: For a future ACK window >1, sentLocInDatagram doesn't always apply
360 //! to the front-of-queue datagram. Instead, we need to track the queue
361 //! position the datagram being sent as well (relative to the front-of-queue).
362 //! e.g. uint8_t datagramBeingSent
363
364 //! How many bytes of the front-of-queue datagram has been acked
365 size_t ackedLocInDatagram;
366
367 //! Whether the link layer is still processing the pending packet
368 bool linkBusy;
369 };
370
371 struct ChppDatagram {
372 //! Length of datagram payload in bytes (A datagram can be constituted from
373 //! one or more packets)
374 size_t length;
375
376 // Datagram payload
377 uint8_t *payload;
378 };
379
380 struct ChppTxDatagramQueue {
381 //! Number of pending datagrams in the queue.
382 uint8_t pending;
383
384 //! Index of the datagram at the front of the queue.
385 uint8_t front;
386
387 //! Location counter within the front datagram (i.e. the datagram at the front
388 //! of the queue), showing how many bytes of this datagram have already been
389 //! packetized and processed.
390 size_t loc;
391
392 //! Array of datagrams
393 struct ChppDatagram datagram[CHPP_TX_DATAGRAM_QUEUE_LEN];
394 };
395
396 struct ChppTransportState {
397 struct ChppAppState *appContext; // Pointer to app layer context
398
399 struct ChppRxStatus rxStatus; // Rx state and location within
400 struct ChppTransportHeader rxHeader; // Rx packet header
401 struct ChppTransportFooter rxFooter; // Rx packet footer (checksum)
402 struct ChppDatagram rxDatagram; // Rx datagram
403 uint8_t loopbackResult; // Last transport-layer loopback test result as an
404 // enum ChppAppErrorCode
405
406 struct ChppTxStatus txStatus; // Tx state
407 struct ChppTxDatagramQueue txDatagramQueue; // Queue of datagrams to be Tx
408
409 size_t linkBufferSize; // Number of bytes currently in the Tx Buffer
410 void *linkContext; // Pointer to the link layer state
411 const struct ChppLinkApi *linkApi; // Link API
412
413 struct ChppDatagram transportLoopbackData; // Transport-layer loopback
414 // request data, if any
415
416 struct ChppMutex mutex; // Lock for transport state (i.e. context)
417 struct ChppNotifier notifier; // Notifier for main thread
418 bool initialized; // Has been initialized
419 enum ChppResetState resetState; // Maintains state of a reset
420 uint16_t resetCount; // (Unsuccessful) reset attempts
421 uint64_t resetTimeNs; // Time of last reset
422
423 struct ChppConditionVariable
424 resetCondVar; // Condvar specifically to wait for resetState
425
426 #ifdef CHPP_ENABLE_WORK_MONITOR
427 struct ChppWorkMonitor workMonitor; // Monitor used for the transport thread
428 #endif
429 };
430
431 /************************************************
432 * Public functions
433 ***********************************************/
434
435 /**
436 * Initializes the CHPP transport layer state stored in the parameter
437 * transportContext.
438 * It is necessary to initialize state for each transport layer instance on
439 * every platform.
440 * Each transport layer instance is associated with a single application layer
441 * instance. appContext points to the application layer status struct associated
442 * with this transport layer instance.
443 *
444 * Calling this method will in turn call the init method of the linkApi with the
445 * linkContext as the first parameter.
446 *
447 * @param transportContext Maintains state for each transport layer instance.
448 * @param appContext The app layer state associated with this transport
449 * layer instance.
450 * @param linkContext The associated link layer state.
451 * @param linkApi The API of the link layer
452 */
453 void chppTransportInit(struct ChppTransportState *transportContext,
454 struct ChppAppState *appContext, void *linkContext,
455 const struct ChppLinkApi *linkApi);
456
457 /**
458 * Deinitializes the CHPP transport layer and does necessary clean-ups for
459 * e.g. clean shutdown.
460 *
461 * @param transportContext A non-null pointer to ChppTransportState
462 * initialized previously in chppTransportInit().
463 */
464 void chppTransportDeinit(struct ChppTransportState *transportContext);
465
466 /**
467 * Blocking call until CHPP has finished resetting.
468 *
469 * @param transportContext, A non-null pointer to ChppTransportState
470 * initialized previously in chppTransportDeinit().
471 * @param timeoutMs The timeout in milliseconds.
472 *
473 * @return False if timed out.
474 */
475 bool chppTransportWaitForResetComplete(
476 struct ChppTransportState *transportContext, uint64_t timeoutMs);
477
478 /**
479 * Processes all incoming data on the serial port based on the Rx state.
480 * stream. Checks checksum, triggering the correct response (ACK / NACK).
481 * Moves the state to CHPP_STATE_PREAMBLE afterwards.
482 *
483 * TODO: Add requirements, e.g. context must not be modified unless locked via
484 * mutex.
485 *
486 * TODO: Add sufficient outward facing documentation
487 *
488 * @param context Maintains state for each transport layer instance.
489 * @param buf Input data. Cannot be null.
490 * @param len Length of input data in bytes.
491 *
492 * @return true informs the serial port driver that we are waiting for a
493 * preamble. This allows the driver to (optionally) filter incoming zeros and
494 * save processing
495 */
496 bool chppRxDataCb(struct ChppTransportState *context, const uint8_t *buf,
497 size_t len);
498
499 /**
500 * Optional callback function for the link layer to indicate the end of a
501 * packet. The availability of this information depends on the link layer
502 * implementation.
503 *
504 * @param context Maintains state for each transport layer instance.
505 */
506 void chppRxPacketCompleteCb(struct ChppTransportState *context);
507
508 /**
509 * Enqueues an outgoing datagram of a specified length and frees the payload
510 * asynchronously after it is sent. The payload must have been allocated by the
511 * caller using chppMalloc.
512 *
513 * If enqueueing a datagram is unsuccessful, the payload is freed (discarded)
514 * and an error message printed.
515 *
516 * Note that the ownership of buf is taken from the caller when this method is
517 * invoked.
518 *
519 * @param context Maintains state for each transport layer instance.
520 * @param buf Datagram payload allocated through chppMalloc. Cannot be null.
521 * @param len Datagram length in bytes.
522 *
523 * @return True informs the sender that the datagram was successfully enqueued.
524 * False informs the sender that the queue was full and the payload discarded.
525 */
526 bool chppEnqueueTxDatagramOrFail(struct ChppTransportState *context, void *buf,
527 size_t len);
528
529 /**
530 * Enables the App Layer to enqueue an outgoing error datagram, for example for
531 * an OOM situation over the wire.
532 *
533 * @param context Maintains state for each transport layer instance.
534 * @param errorCode Error code to be sent.
535 */
536 void chppEnqueueTxErrorDatagram(struct ChppTransportState *context,
537 enum ChppTransportErrorCode errorCode);
538
539 /**
540 * Provides systems that do not use chppWorkThreadStart() and its associated
541 * timeout mechanisms (that relies on chppNotifierTimedWait()) how long they
542 * should wait until they run chppTransportDoWork() again, in nanoseconds.
543 *
544 * For these implementations, chppTransportDoWork() should be run at or slightly
545 * after the wait time returned by this function.
546 *
547 * A return value of CHPP_TRANSPORT_TIMEOUT_INFINITE indicates that there is no
548 * need to run chppTransportDoWork() based on a timeout (i.e. CHPP is not
549 * waiting on an ACK).
550 *
551 * A return value of CHPP_TRANSPORT_TIMEOUT_IMMEDIATE indicates that
552 * chppTransportDoWork() should be run immediately.
553 *
554 * @param context Maintains state for each transport layer instance.
555 *
556 * @return Time until chppTransportDoWork() must be called in nanoseconds.
557 */
558 uint64_t chppTransportGetTimeUntilNextDoWorkNs(
559 struct ChppTransportState *context);
560
561 /**
562 * Starts the main thread for CHPP's Transport Layer. This thread needs to be
563 * started after the Transport Layer is initialized through chppTransportInit().
564 * Note that a platform may implement this as a new thread or as part of an
565 * existing thread.
566 *
567 * If needed (e.g. for testing and debugging), this thread can be stopped by
568 * calling chppWorkThreadStop().
569 *
570 * If a system does not support multi-threading, the system MUST replicate the
571 * high-level behavior of chppWorkThreadStart(). More details in the
572 * documentation of chppWorkThreadHandleSignal(). For such systems,
573 * chppTransportGetTimeUntilNextDoWorkNs() can be used to replicate the
574 * functionality of chppNotifierTimedWait().
575 *
576 * @param context Maintains state for each transport layer instance.
577 */
578 void chppWorkThreadStart(struct ChppTransportState *context);
579
580 /**
581 * Handles signals set for the CHPP transport instance. This method should be
582 * invoked externally if chppWorkThreadStart() cannot be directly used, for
583 * example if the system does not support thread signaling and needs explicit
584 * control of the CHPP work thread from an outer control loop. By "outer control
585 * loop," we mean the code path triggering work on the CHPP transport layer.
586 *
587 * Note that if a platform uses this method, the outer control loop MUST
588 * replicate the behavior in the chppWorkThreadStart() method exactly. All
589 * pending signals MUST be handled prior to the suspension of the outer control
590 * loop, and any initialization sequence MUST be replicated.
591 *
592 * @param context Maintains state for each transport layer instance.
593 * @param signals The signals to process. Should be obtained via
594 * chppNotifierTimedWait() for the given transport context's notifier.
595 *
596 * @return true if the CHPP work thread should exit.
597 */
598 bool chppWorkThreadHandleSignal(struct ChppTransportState *context,
599 uint32_t signals);
600
601 /**
602 * Signals the main thread for CHPP's Transport Layer to perform some work. This
603 * method should only be called from the link layer.
604 *
605 * Note that this method must be safe to call from an interrupt context, as the
606 * platform link layer implementation may send a signal from one (e.g. handling
607 * an interrupt from the physical layer or inputs from the remote endpoint).
608 *
609 * @param params Platform-specific struct with link details / parameters.
610 * @param signal The signal that describes the work to be performed. Only bits
611 * specified by CHPP_TRANSPORT_SIGNAL_PLATFORM_MASK can be set.
612 */
chppWorkThreadSignalFromLink(struct ChppTransportState * context,uint32_t signal)613 static inline void chppWorkThreadSignalFromLink(
614 struct ChppTransportState *context, uint32_t signal) {
615 CHPP_ASSERT((signal & ~(CHPP_TRANSPORT_SIGNAL_PLATFORM_MASK)) == 0);
616 chppNotifierSignal(&context->notifier,
617 signal & CHPP_TRANSPORT_SIGNAL_PLATFORM_MASK);
618 }
619
620 /**
621 * Stops the main thread for CHPP's Transport Layer that has been started by
622 * calling chppWorkThreadStart(). Stopping this thread may be necessary for
623 * testing and debugging purposes.
624 *
625 * @param context Maintains state for each transport layer instance.
626 */
627 void chppWorkThreadStop(struct ChppTransportState *context);
628
629 /**
630 * Notifies the transport layer that the link layer is done sending the previous
631 * payload (as provided to platformLinkSend() through buf and len) and can
632 * accept more data.
633 *
634 * On systems that implement the link layer Tx asynchronously, where
635 * platformLinkSend() returns False before consuming the payload provided to it
636 * (i.e. buf and len), the platform implementation must call this function after
637 * platformLinkSend() is done with the payload (i.e. buf and len).
638 *
639 * @param context Maintains state for each transport layer instance.
640 * @param error Indicates success or failure type.
641 */
642 void chppLinkSendDoneCb(struct ChppTransportState *context,
643 enum ChppLinkErrorCode error);
644
645 /**
646 * Notifies the transport layer that the app layer is done with the previous
647 * payload (as provided to chppAppProcessRxDatagram() through buf and len), so
648 * it is freed appropriately etc.
649 *
650 * TODO: Look into automatically doing this when a response is sent back by a
651 * service.
652 *
653 * @param context Maintains state for each transport layer instance.
654 * @param buf Pointer to the buf given to chppAppProcessRxDatagram. Cannot be
655 * null.
656 */
657 void chppDatagramProcessDoneCb(struct ChppTransportState *context,
658 uint8_t *buf);
659
660 /**
661 * Sends out transport-layer loopback data. Note that in most situations, an
662 * application-layer loopback test is pprefrable as it is more thorough and
663 * provides statistics regarding the correctness of the loopbacked data.
664 *
665 * The result will be available later, asynchronously, as a ChppAppErrorCode
666 * enum in context->loopbackResult.
667 *
668 * @param context Maintains state for each transport layer instance.
669 * @param buf Pointer to the loopback data to be sent. Cannot be null.
670 * @param len Length of the loopback data.
671 *
672 * @return A ChppLinkErrorCode enum indicating if the transport-layer-loopback
673 * request was accepted. Note that the actual test result will be available
674 * later, asynchronously, in context->loopbackResult.
675 */
676 uint8_t chppRunTransportLoopback(struct ChppTransportState *context,
677 uint8_t *buf, size_t len);
678
679 /**
680 * Sends a reset or reset-ack packet over the link in order to reset the remote
681 * side or inform the counterpart of a reset, respectively. The transport
682 * layer's configuration is sent as the payload of the reset packet.
683 *
684 * This function is typically used only internally, either immediately after
685 * initialization via chppWorkThreadStart() or for subsequent resets or
686 * reset-acks via chppReset(). However, implementations that do not rely on
687 * chppWorkThreadStart() would require to call this function after initializing
688 * CHPP.
689 *
690 * @param context Maintains state for each transport layer instance.
691 * @param resetType Distinguishes a reset from a reset-ack, as defined in the
692 * ChppTransportPacketAttributes struct.
693 * @param error Provides the error that led to the reset.
694 */
695 void chppTransportSendReset(struct ChppTransportState *context,
696 enum ChppTransportPacketAttributes resetType,
697 enum ChppTransportErrorCode error);
698
699 /**
700 * Returns the Tx MTU size at the transport layer in bytes.
701 *
702 * This the link MTU minus the transport overhead.
703 *
704 * @param context Maintains state for each transport layer instance.
705 */
706 size_t chppTransportTxMtuSize(const struct ChppTransportState *context);
707
708 /**
709 * Returns the Rx MTU size at the transport layer in bytes.
710 *
711 * This the link MTU minus the transport overhead.
712 *
713 * @param context Maintains state for each transport layer instance.
714 */
715 size_t chppTransportRxMtuSize(const struct ChppTransportState *context);
716
717 #ifdef __cplusplus
718 }
719 #endif
720
721 #endif // CHPP_TRANSPORT_H_
722