Lines Matching full:context
41 static void chppSetRxState(struct ChppTransportState *context,
43 static size_t chppConsumePreamble(struct ChppTransportState *context,
45 static size_t chppConsumeHeader(struct ChppTransportState *context,
47 static size_t chppConsumePayload(struct ChppTransportState *context,
49 static size_t chppConsumeFooter(struct ChppTransportState *context,
51 static void chppAbortRxPacket(struct ChppTransportState *context);
54 struct ChppTransportState *context);
58 struct ChppTransportState *context);
60 static void chppSetResetComplete(struct ChppTransportState *context);
61 static void chppProcessResetAck(struct ChppTransportState *context);
62 static void chppProcessRxPacket(struct ChppTransportState *context);
63 static void chppProcessRxPayload(struct ChppTransportState *context);
64 static void chppClearRxDatagram(struct ChppTransportState *context);
65 static bool chppRxChecksumIsOk(const struct ChppTransportState *context);
67 const struct ChppTransportState *context);
68 static void chppRegisterRxAck(struct ChppTransportState *context);
70 static void chppEnqueueTxPacket(struct ChppTransportState *context,
74 struct ChppTransportState *context);
75 static void chppAddPayload(struct ChppTransportState *context);
76 static void chppAddFooter(struct ChppTransportState *context);
78 size_t chppDequeueTxDatagram(struct ChppTransportState *context);
79 static void chppClearTxDatagramQueue(struct ChppTransportState *context);
80 static void chppTransportDoWork(struct ChppTransportState *context);
81 static void chppAppendToPendingTxPacket(struct ChppTransportState *context,
84 static bool chppEnqueueTxDatagram(struct ChppTransportState *context,
87 struct ChppTransportState *context);
89 static void chppResetTransportContext(struct ChppTransportState *context);
90 static void chppReset(struct ChppTransportState *context,
94 struct ChppTransportState *context, enum ChppEndpointType type);
96 static void chppWorkHandleTimeout(struct ChppTransportState *context);
123 * @param context State of the transport layer.
126 static void chppSetRxState(struct ChppTransportState *context, in chppSetRxState() argument
131 chppGetRxStatusLabel(context->rxStatus.state), in chppSetRxState()
132 chppGetRxStatusLabel(newState), context->rxStatus.locInState); in chppSetRxState()
133 context->rxStatus.locInState = 0; in chppSetRxState()
134 context->rxStatus.state = newState; in chppSetRxState()
145 * @param context State of the transport layer.
151 static size_t chppConsumePreamble(struct ChppTransportState *context, in chppConsumePreamble() argument
158 context->rxStatus.locInState < CHPP_PREAMBLE_LEN_BYTES) { in chppConsumePreamble()
159 size_t offset = context->rxStatus.locInState; in chppConsumePreamble()
163 context->rxStatus.locInState++; in chppConsumePreamble()
167 context->rxStatus.locInState = 1; in chppConsumePreamble()
171 context->rxStatus.locInState = 0; in chppConsumePreamble()
178 if (context->rxStatus.locInState == CHPP_PREAMBLE_LEN_BYTES) { in chppConsumePreamble()
180 context->rxStatus.packetStartTimeNs = chppGetCurrentTimeNs(); in chppConsumePreamble()
181 chppSetRxState(context, CHPP_STATE_HEADER); in chppConsumePreamble()
192 * @param context State of the transport layer.
198 static size_t chppConsumeHeader(struct ChppTransportState *context, in chppConsumeHeader() argument
200 CHPP_ASSERT(context->rxStatus.locInState < in chppConsumeHeader()
203 len, (sizeof(struct ChppTransportHeader) - context->rxStatus.locInState)); in chppConsumeHeader()
204 memcpy(((uint8_t *)&context->rxHeader) + context->rxStatus.locInState, buf, in chppConsumeHeader()
206 context->rxStatus.locInState += bytesToCopy; in chppConsumeHeader()
208 if (context->rxStatus.locInState == sizeof(struct ChppTransportHeader)) { in chppConsumeHeader()
211 enum ChppTransportErrorCode headerCheckResult = chppRxHeaderCheck(context); in chppConsumeHeader()
215 context, CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(CHPP_TRANSPORT_ATTR_NONE, in chppConsumeHeader()
217 chppSetRxState(context, CHPP_STATE_PREAMBLE); in chppConsumeHeader()
219 } else if (context->rxHeader.length == 0) { in chppConsumeHeader()
221 chppSetRxState(context, CHPP_STATE_FOOTER); in chppConsumeHeader()
227 if (context->rxDatagram.length == 0) { in chppConsumeHeader()
229 tempPayload = chppMalloc(context->rxHeader.length); in chppConsumeHeader()
233 chppRealloc(context->rxDatagram.payload, in chppConsumeHeader()
234 context->rxDatagram.length + context->rxHeader.length, in chppConsumeHeader()
235 context->rxDatagram.length); in chppConsumeHeader()
240 chppEnqueueTxPacket(context, CHPP_TRANSPORT_ERROR_OOM); in chppConsumeHeader()
241 chppSetRxState(context, CHPP_STATE_PREAMBLE); in chppConsumeHeader()
243 context->rxDatagram.payload = tempPayload; in chppConsumeHeader()
244 context->rxDatagram.length += context->rxHeader.length; in chppConsumeHeader()
245 chppSetRxState(context, CHPP_STATE_PAYLOAD); in chppConsumeHeader()
258 * @param context State of the transport layer.
264 static size_t chppConsumePayload(struct ChppTransportState *context, in chppConsumePayload() argument
266 CHPP_ASSERT(context->rxStatus.locInState < context->rxHeader.length); in chppConsumePayload()
268 MIN(len, (context->rxHeader.length - context->rxStatus.locInState)); in chppConsumePayload()
269 memcpy(context->rxDatagram.payload + context->rxStatus.locInDatagram, buf, in chppConsumePayload()
271 context->rxStatus.locInDatagram += bytesToCopy; in chppConsumePayload()
272 context->rxStatus.locInState += bytesToCopy; in chppConsumePayload()
274 if (context->rxStatus.locInState == context->rxHeader.length) { in chppConsumePayload()
276 chppSetRxState(context, CHPP_STATE_FOOTER); in chppConsumePayload()
287 * @param context State of the transport layer.
293 static size_t chppConsumeFooter(struct ChppTransportState *context, in chppConsumeFooter() argument
295 CHPP_ASSERT(context->rxStatus.locInState < in chppConsumeFooter()
298 len, (sizeof(struct ChppTransportFooter) - context->rxStatus.locInState)); in chppConsumeFooter()
299 memcpy(((uint8_t *)&context->rxFooter) + context->rxStatus.locInState, buf, in chppConsumeFooter()
302 context->rxStatus.locInState += bytesToCopy; in chppConsumeFooter()
303 if (context->rxStatus.locInState == sizeof(struct ChppTransportFooter)) { in chppConsumeFooter()
306 if (CHPP_TRANSPORT_GET_ERROR(context->rxHeader.packetCode) != in chppConsumeFooter()
310 context->rxHeader.length, context->rxHeader.seq, in chppConsumeFooter()
311 context->rxHeader.ackSeq, in chppConsumeFooter()
312 (uint8_t)CHPP_TRANSPORT_GET_ATTR(context->rxHeader.packetCode), in chppConsumeFooter()
313 (uint8_t)CHPP_TRANSPORT_GET_ERROR(context->rxHeader.packetCode), in chppConsumeFooter()
314 context->rxHeader.flags); in chppConsumeFooter()
318 context->rxHeader.length, context->rxHeader.seq, in chppConsumeFooter()
319 context->rxHeader.ackSeq, in chppConsumeFooter()
320 (uint8_t)CHPP_TRANSPORT_GET_ATTR(context->rxHeader.packetCode), in chppConsumeFooter()
321 (uint8_t)CHPP_TRANSPORT_GET_ERROR(context->rxHeader.packetCode), in chppConsumeFooter()
322 context->rxHeader.flags); in chppConsumeFooter()
325 if (CHPP_TRANSPORT_GET_ATTR(context->rxHeader.packetCode) == in chppConsumeFooter()
328 chppProcessTransportLoopbackRequest(context); in chppConsumeFooter()
331 } else if (CHPP_TRANSPORT_GET_ATTR(context->rxHeader.packetCode) == in chppConsumeFooter()
334 chppProcessTransportLoopbackResponse(context); in chppConsumeFooter()
337 } else if (!chppRxChecksumIsOk(context)) { in chppConsumeFooter()
339 context->rxHeader.seq, context->rxHeader.length); in chppConsumeFooter()
340 chppAbortRxPacket(context); in chppConsumeFooter()
341 chppEnqueueTxPacket(context, CHPP_TRANSPORT_ERROR_CHECKSUM); // NACK in chppConsumeFooter()
343 } else if (CHPP_TRANSPORT_GET_ATTR(context->rxHeader.packetCode) == in chppConsumeFooter()
346 context->rxHeader.seq, in chppConsumeFooter()
347 CHPP_TRANSPORT_GET_ERROR(context->rxHeader.packetCode)); in chppConsumeFooter()
348 chppMutexUnlock(&context->mutex); in chppConsumeFooter()
349 chppReset(context, CHPP_TRANSPORT_ATTR_RESET_ACK, in chppConsumeFooter()
351 chppMutexLock(&context->mutex); in chppConsumeFooter()
353 } else if (context->resetState == CHPP_RESET_STATE_PERMANENT_FAILURE) { in chppConsumeFooter()
356 context->rxHeader.seq, context->rxHeader.length); in chppConsumeFooter()
357 chppAbortRxPacket(context); in chppConsumeFooter()
359 } else if (CHPP_TRANSPORT_GET_ATTR(context->rxHeader.packetCode) == in chppConsumeFooter()
361 CHPP_LOGI("RX RESET-ACK packet seq=%" PRIu8, context->rxHeader.seq); in chppConsumeFooter()
362 chppProcessResetAck(context); in chppConsumeFooter()
364 } else if (context->resetState == CHPP_RESET_STATE_RESETTING) { in chppConsumeFooter()
366 context->rxHeader.seq, context->rxHeader.length); in chppConsumeFooter()
367 chppAbortRxPacket(context); in chppConsumeFooter()
370 chppProcessRxPacket(context); in chppConsumeFooter()
374 chppSetRxState(context, CHPP_STATE_PREAMBLE); in chppConsumeFooter()
384 * @param context State of the transport layer.
386 static void chppAbortRxPacket(struct ChppTransportState *context) { in chppAbortRxPacket() argument
390 switch (context->rxStatus.state) { in chppAbortRxPacket()
397 undoLen = context->rxHeader.length; in chppAbortRxPacket()
398 undoLoc = context->rxStatus.locInState; in chppAbortRxPacket()
403 undoLen = context->rxHeader.length; in chppAbortRxPacket()
404 undoLoc = context->rxHeader.length; in chppAbortRxPacket()
416 CHPP_ASSERT(context->rxDatagram.length >= undoLen); in chppAbortRxPacket()
417 CHPP_ASSERT(context->rxStatus.locInDatagram >= undoLoc); in chppAbortRxPacket()
418 context->rxDatagram.length -= undoLen; in chppAbortRxPacket()
419 context->rxStatus.locInDatagram -= undoLoc; in chppAbortRxPacket()
421 if (context->rxDatagram.length == 0) { in chppAbortRxPacket()
423 CHPP_FREE_AND_NULLIFY(context->rxDatagram.payload); in chppAbortRxPacket()
428 chppRealloc(context->rxDatagram.payload, context->rxDatagram.length, in chppAbortRxPacket()
429 context->rxDatagram.length + undoLen); in chppAbortRxPacket()
434 context->rxDatagram.payload = tempPayload; in chppAbortRxPacket()
439 chppSetRxState(context, CHPP_STATE_PREAMBLE); in chppAbortRxPacket()
445 * @param context State of the transport layer.
449 struct ChppTransportState *context) { in chppProcessTransportLoopbackRequest() argument
450 if (context->txStatus.linkBusy) { in chppProcessTransportLoopbackRequest()
454 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppProcessTransportLoopbackRequest()
455 context->txStatus.linkBusy = true; in chppProcessTransportLoopbackRequest()
456 context->linkBufferSize = 0; in chppProcessTransportLoopbackRequest()
457 context->linkBufferSize += chppAddPreamble(&linkTxBuffer[0]); in chppProcessTransportLoopbackRequest()
460 (struct ChppTransportHeader *)&linkTxBuffer[context->linkBufferSize]; in chppProcessTransportLoopbackRequest()
461 context->linkBufferSize += sizeof(*txHeader); in chppProcessTransportLoopbackRequest()
463 *txHeader = context->rxHeader; in chppProcessTransportLoopbackRequest()
468 MIN(context->rxDatagram.length, chppTransportTxMtuSize(context)); in chppProcessTransportLoopbackRequest()
469 chppAppendToPendingTxPacket(context, context->rxDatagram.payload, in chppProcessTransportLoopbackRequest()
471 CHPP_FREE_AND_NULLIFY(context->rxDatagram.payload); in chppProcessTransportLoopbackRequest()
472 chppClearRxDatagram(context); in chppProcessTransportLoopbackRequest()
474 chppAddFooter(context); in chppProcessTransportLoopbackRequest()
477 txHeader->length, context->rxDatagram.length); in chppProcessTransportLoopbackRequest()
478 enum ChppLinkErrorCode error = chppSendPendingPacket(context); in chppProcessTransportLoopbackRequest()
481 chppLinkSendDoneCb(context, error); in chppProcessTransportLoopbackRequest()
490 * @param context State of the transport layer.
494 struct ChppTransportState *context) { in chppProcessTransportLoopbackResponse() argument
495 if (context->transportLoopbackData.length != context->rxDatagram.length) { in chppProcessTransportLoopbackResponse()
497 context->rxDatagram.length, in chppProcessTransportLoopbackResponse()
498 context->transportLoopbackData.length - CHPP_PREAMBLE_LEN_BYTES - in chppProcessTransportLoopbackResponse()
501 context->loopbackResult = CHPP_APP_ERROR_INVALID_LENGTH; in chppProcessTransportLoopbackResponse()
503 } else if (memcmp(context->rxDatagram.payload, in chppProcessTransportLoopbackResponse()
504 context->transportLoopbackData.payload, in chppProcessTransportLoopbackResponse()
505 context->rxDatagram.length) != 0) { in chppProcessTransportLoopbackResponse()
507 context->rxDatagram.length); in chppProcessTransportLoopbackResponse()
508 context->loopbackResult = CHPP_APP_ERROR_INVALID_ARG; in chppProcessTransportLoopbackResponse()
511 context->loopbackResult = CHPP_APP_ERROR_NONE; in chppProcessTransportLoopbackResponse()
514 context->rxDatagram.length); in chppProcessTransportLoopbackResponse()
517 context->transportLoopbackData.length = 0; in chppProcessTransportLoopbackResponse()
518 CHPP_FREE_AND_NULLIFY(context->transportLoopbackData.payload); in chppProcessTransportLoopbackResponse()
519 CHPP_FREE_AND_NULLIFY(context->rxDatagram.payload); in chppProcessTransportLoopbackResponse()
520 chppClearRxDatagram(context); in chppProcessTransportLoopbackResponse()
527 * @param context State of the transport layer.
529 static void chppSetResetComplete(struct ChppTransportState *context) { in chppSetResetComplete() argument
530 context->resetState = CHPP_RESET_STATE_NONE; in chppSetResetComplete()
531 context->resetCount = 0; in chppSetResetComplete()
532 chppConditionVariableSignal(&context->resetCondVar); in chppSetResetComplete()
539 * @param context State of the transport layer.
541 static void chppProcessResetAck(struct ChppTransportState *context) { in chppProcessResetAck() argument
542 if (context->resetState == CHPP_RESET_STATE_NONE) { in chppProcessResetAck()
544 context->rxHeader.seq, context->rxHeader.packetCode); in chppProcessResetAck()
554 chppDatagramProcessDoneCb(context, context->rxDatagram.payload); in chppProcessResetAck()
555 chppClearRxDatagram(context); in chppProcessResetAck()
560 chppSetResetComplete(context); in chppProcessResetAck()
561 context->rxStatus.receivedPacketCode = context->rxHeader.packetCode; in chppProcessResetAck()
562 context->rxStatus.expectedSeq = context->rxHeader.seq + 1; in chppProcessResetAck()
563 chppRegisterRxAck(context); in chppProcessResetAck()
567 chppDatagramProcessDoneCb(context, context->rxDatagram.payload); in chppProcessResetAck()
568 chppClearRxDatagram(context); in chppProcessResetAck()
571 if (context->appContext->isDiscoveryComplete) { in chppProcessResetAck()
572 chppEnqueueTxPacket(context, CHPP_TRANSPORT_ERROR_NONE); in chppProcessResetAck()
575 chppEnqueueTxPacket(context, CHPP_TRANSPORT_ERROR_NONE); in chppProcessResetAck()
579 chppMutexUnlock(&context->mutex); in chppProcessResetAck()
580 chppAppProcessReset(context->appContext); in chppProcessResetAck()
581 chppMutexLock(&context->mutex); in chppProcessResetAck()
587 * @param context State of the transport layer.
589 static void chppProcessRxPacket(struct ChppTransportState *context) { in chppProcessRxPacket() argument
591 context->rxStatus.lastGoodPacketTimeMs = (uint32_t)(now / CHPP_NSEC_PER_MSEC); in chppProcessRxPacket()
592 context->rxStatus.receivedPacketCode = context->rxHeader.packetCode; in chppProcessRxPacket()
593 chppRegisterRxAck(context); in chppProcessRxPacket()
596 if (context->rxHeader.length > 0 && in chppProcessRxPacket()
597 context->rxHeader.seq != context->rxStatus.expectedSeq) { in chppProcessRxPacket()
602 if (context->txDatagramQueue.pending > 0 || in chppProcessRxPacket()
611 if (context->rxHeader.length > 0 && in chppProcessRxPacket()
612 context->rxHeader.seq == context->rxStatus.expectedSeq - 1) { in chppProcessRxPacket()
617 context, CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(CHPP_TRANSPORT_ATTR_NONE, in chppProcessRxPacket()
624 context->rxHeader.seq, context->rxStatus.expectedSeq, in chppProcessRxPacket()
625 context->rxHeader.length); in chppProcessRxPacket()
626 chppAbortRxPacket(context); in chppProcessRxPacket()
628 } else if (context->rxHeader.length > 0) { in chppProcessRxPacket()
630 chppProcessRxPayload(context); in chppProcessRxPacket()
631 } else if (!context->txStatus.hasPacketsToSend) { in chppProcessRxPacket()
635 chppNotifierSignal(&context->notifier, in chppProcessRxPacket()
644 * @param context State of the transport layer.
646 static void chppProcessRxPayload(struct ChppTransportState *context) { in chppProcessRxPayload() argument
647 context->rxStatus.expectedSeq++; // chppProcessRxPacket() already confirms in chppProcessRxPayload()
648 // that context->rxStatus.expectedSeq == in chppProcessRxPayload()
649 // context->rxHeader.seq, protecting against in chppProcessRxPayload()
652 if (context->rxHeader.flags & CHPP_TRANSPORT_FLAG_UNFINISHED_DATAGRAM) { in chppProcessRxPayload()
656 context->rxHeader.seq, context->rxHeader.length, in chppProcessRxPayload()
657 context->rxDatagram.length, context->rxStatus.expectedSeq); in chppProcessRxPayload()
665 chppMutexUnlock(&context->mutex); in chppProcessRxPayload()
666 chppAppProcessRxDatagram(context->appContext, context->rxDatagram.payload, in chppProcessRxPayload()
667 context->rxDatagram.length); in chppProcessRxPayload()
668 chppMutexLock(&context->mutex); in chppProcessRxPayload()
673 context->rxDatagram.length, context->rxHeader.seq, in chppProcessRxPayload()
674 context->rxHeader.length, context->rxStatus.expectedSeq, in chppProcessRxPayload()
675 context->txStatus.sentAckSeq); in chppProcessRxPayload()
676 chppClearRxDatagram(context); in chppProcessRxPayload()
680 chppEnqueueTxPacket(context, CHPP_TRANSPORT_ERROR_NONE); in chppProcessRxPayload()
690 * @param context State of the transport layer.
692 static void chppClearRxDatagram(struct ChppTransportState *context) { in chppClearRxDatagram() argument
693 context->rxStatus.locInDatagram = 0; in chppClearRxDatagram()
694 context->rxDatagram.length = 0; in chppClearRxDatagram()
695 context->rxDatagram.payload = NULL; in chppClearRxDatagram()
701 * @param context State of the transport layer.
705 static bool chppRxChecksumIsOk(const struct ChppTransportState *context) { in chppRxChecksumIsOk() argument
706 uint32_t crc = chppCrc32(0, (const uint8_t *)&context->rxHeader, in chppRxChecksumIsOk()
707 sizeof(context->rxHeader)); in chppRxChecksumIsOk()
710 &context->rxDatagram in chppRxChecksumIsOk()
711 .payload[context->rxStatus.locInDatagram - context->rxHeader.length], in chppRxChecksumIsOk()
712 context->rxHeader.length); in chppRxChecksumIsOk()
714 if (context->rxFooter.checksum != crc) { in chppRxChecksumIsOk()
717 context->rxFooter.checksum, crc, in chppRxChecksumIsOk()
718 (size_t)(context->rxHeader.length + in chppRxChecksumIsOk()
722 return (context->rxFooter.checksum == crc); in chppRxChecksumIsOk()
729 * @param context State of the transport layer.
734 const struct ChppTransportState *context) { in chppRxHeaderCheck() argument
737 if (context->rxHeader.length > chppTransportRxMtuSize(context)) { in chppRxHeaderCheck()
744 context->rxHeader.seq, context->rxStatus.expectedSeq, in chppRxHeaderCheck()
745 context->rxHeader.length, result); in chppRxHeaderCheck()
755 * @param context State of the transport layer.
757 static void chppRegisterRxAck(struct ChppTransportState *context) { in chppRegisterRxAck() argument
758 uint8_t rxAckSeq = context->rxHeader.ackSeq; in chppRegisterRxAck()
760 if (context->rxStatus.receivedAckSeq != rxAckSeq) { in chppRegisterRxAck()
763 if ((uint8_t)(context->rxStatus.receivedAckSeq + 1) != rxAckSeq) { in chppRegisterRxAck()
765 context->rxStatus.receivedAckSeq, rxAckSeq); in chppRegisterRxAck()
771 context->rxStatus.receivedAckSeq, rxAckSeq, in chppRegisterRxAck()
772 context->txDatagramQueue.pending, context->txDatagramQueue.front, in chppRegisterRxAck()
773 context->txStatus.ackedLocInDatagram, in chppRegisterRxAck()
774 context->txDatagramQueue.datagram[context->txDatagramQueue.front] in chppRegisterRxAck()
777 context->rxStatus.receivedAckSeq = rxAckSeq; in chppRegisterRxAck()
778 if (context->txStatus.txAttempts > 1) { in chppRegisterRxAck()
780 context->rxHeader.ackSeq - 1, in chppRegisterRxAck()
781 context->txStatus.txAttempts - 1); in chppRegisterRxAck()
783 context->txStatus.txAttempts = 0; in chppRegisterRxAck()
786 context->txStatus.ackedLocInDatagram += chppTransportTxMtuSize(context); in chppRegisterRxAck()
787 if (context->txStatus.ackedLocInDatagram >= in chppRegisterRxAck()
788 context->txDatagramQueue.datagram[context->txDatagramQueue.front] in chppRegisterRxAck()
792 context->txStatus.ackedLocInDatagram = 0; in chppRegisterRxAck()
793 context->txStatus.sentLocInDatagram = 0; in chppRegisterRxAck()
797 // front-of-queue). e.g. context->txStatus.datagramBeingSent--; in chppRegisterRxAck()
799 if (chppDequeueTxDatagram(context) == 0) { in chppRegisterRxAck()
800 context->txStatus.hasPacketsToSend = false; in chppRegisterRxAck()
823 * @param context State of the transport layer.
826 static void chppEnqueueTxPacket(struct ChppTransportState *context, in chppEnqueueTxPacket() argument
828 context->txStatus.hasPacketsToSend = true; in chppEnqueueTxPacket()
829 context->txStatus.packetCodeToSend = packetCode; in chppEnqueueTxPacket()
835 chppNotifierSignal(&context->notifier, CHPP_TRANSPORT_SIGNAL_EVENT); in chppEnqueueTxPacket()
854 * @param context State of the transport layer.
859 struct ChppTransportState *context) { in chppAddHeader() argument
860 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppAddHeader()
862 (struct ChppTransportHeader *)&linkTxBuffer[context->linkBufferSize]; in chppAddHeader()
863 context->linkBufferSize += sizeof(*txHeader); in chppAddHeader()
865 txHeader->packetCode = context->txStatus.packetCodeToSend; in chppAddHeader()
866 context->txStatus.packetCodeToSend = CHPP_ATTR_AND_ERROR_TO_PACKET_CODE( in chppAddHeader()
867 context->txStatus.packetCodeToSend, CHPP_TRANSPORT_ERROR_NONE); in chppAddHeader()
869 txHeader->ackSeq = context->rxStatus.expectedSeq; in chppAddHeader()
870 context->txStatus.sentAckSeq = txHeader->ackSeq; in chppAddHeader()
878 * @param context State of the transport layer.
880 static void chppAddPayload(struct ChppTransportState *context) { in chppAddPayload() argument
881 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppAddPayload()
886 context->txDatagramQueue.datagram[context->txDatagramQueue.front].length - in chppAddPayload()
887 context->txStatus.ackedLocInDatagram; in chppAddPayload()
891 txHeader->seq, remainingBytes, context->txDatagramQueue.pending); in chppAddPayload()
893 if (remainingBytes > chppTransportTxMtuSize(context)) { in chppAddPayload()
896 txHeader->length = (uint16_t)chppTransportTxMtuSize(context); in chppAddPayload()
905 context, in chppAddPayload()
906 context->txDatagramQueue.datagram[context->txDatagramQueue.front] in chppAddPayload()
908 context->txStatus.ackedLocInDatagram, in chppAddPayload()
911 context->txStatus.sentLocInDatagram = in chppAddPayload()
912 context->txStatus.ackedLocInDatagram + txHeader->length; in chppAddPayload()
918 * @param context State of the transport layer.
920 static void chppAddFooter(struct ChppTransportState *context) { in chppAddFooter() argument
922 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppAddFooter()
923 size_t bufferSize = context->linkBufferSize; in chppAddFooter()
932 chppAppendToPendingTxPacket(context, (const uint8_t *)&footer, in chppAddFooter()
940 * @param context State of the transport layer.
943 size_t chppDequeueTxDatagram(struct ChppTransportState *context) { in chppDequeueTxDatagram() argument
944 if (context->txDatagramQueue.pending == 0) { in chppDequeueTxDatagram()
950 context->txDatagramQueue.front, in chppDequeueTxDatagram()
951 context->txDatagramQueue.datagram[context->txDatagramQueue.front] in chppDequeueTxDatagram()
953 context->txDatagramQueue.pending, in chppDequeueTxDatagram()
954 context->txDatagramQueue.pending - 1); in chppDequeueTxDatagram()
957 context->txDatagramQueue.datagram[context->txDatagramQueue.front] in chppDequeueTxDatagram()
959 context->txDatagramQueue.datagram[context->txDatagramQueue.front].length = in chppDequeueTxDatagram()
962 context->txDatagramQueue.pending--; in chppDequeueTxDatagram()
963 context->txDatagramQueue.front++; in chppDequeueTxDatagram()
964 context->txDatagramQueue.front %= CHPP_TX_DATAGRAM_QUEUE_LEN; in chppDequeueTxDatagram()
967 return context->txDatagramQueue.pending; in chppDequeueTxDatagram()
973 * @param context State of the transport layer.
975 static void chppClearTxDatagramQueue(struct ChppTransportState *context) { in chppClearTxDatagramQueue() argument
976 while (context->txDatagramQueue.pending > 0) { in chppClearTxDatagramQueue()
977 chppDequeueTxDatagram(context); in chppClearTxDatagramQueue()
979 context->txStatus.hasPacketsToSend = false; in chppClearTxDatagramQueue()
993 * @param context State of the transport layer.
995 static void chppTransportDoWork(struct ChppTransportState *context) { in chppTransportDoWork() argument
1000 chppMutexLock(&context->mutex); in chppTransportDoWork()
1002 if (context->txStatus.hasPacketsToSend && !context->txStatus.linkBusy) { in chppTransportDoWork()
1005 context->txStatus.linkBusy = true; in chppTransportDoWork()
1007 context->linkBufferSize = 0; in chppTransportDoWork()
1008 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppTransportDoWork()
1010 context->linkApi->getConfig(context->linkContext); in chppTransportDoWork()
1014 context->linkBufferSize += chppAddPreamble(linkTxBuffer); in chppTransportDoWork()
1017 txHeader = chppAddHeader(context); in chppTransportDoWork()
1020 if ((context->txDatagramQueue.pending > 0)) { in chppTransportDoWork()
1027 txHeader->seq = context->rxStatus.receivedAckSeq; in chppTransportDoWork()
1028 context->txStatus.sentSeq = txHeader->seq; in chppTransportDoWork()
1030 if (context->txStatus.txAttempts > CHPP_TRANSPORT_MAX_RETX && in chppTransportDoWork()
1031 context->resetState != CHPP_RESET_STATE_RESETTING) { in chppTransportDoWork()
1035 chppMutexUnlock(&context->mutex); in chppTransportDoWork()
1036 chppReset(context, CHPP_TRANSPORT_ATTR_RESET, in chppTransportDoWork()
1038 chppMutexLock(&context->mutex); in chppTransportDoWork()
1041 chppAddPayload(context); in chppTransportDoWork()
1042 context->txStatus.txAttempts++; in chppTransportDoWork()
1047 context->txStatus.hasPacketsToSend = false; in chppTransportDoWork()
1050 chppAddFooter(context); in chppTransportDoWork()
1056 context->txStatus.hasPacketsToSend, context->txStatus.linkBusy, in chppTransportDoWork()
1057 context->txDatagramQueue.pending, context->rxStatus.receivedAckSeq, in chppTransportDoWork()
1058 context->txStatus.sentSeq, in chppTransportDoWork()
1059 chppGetRxStatusLabel(context->rxStatus.state)); in chppTransportDoWork()
1062 chppMutexUnlock(&context->mutex); in chppTransportDoWork()
1068 context->linkBufferSize, txHeader->flags, txHeader->packetCode, in chppTransportDoWork()
1070 context->txDatagramQueue.pending); in chppTransportDoWork()
1071 enum ChppLinkErrorCode error = chppSendPendingPacket(context); in chppTransportDoWork()
1077 chppLinkSendDoneCb(context, error); in chppTransportDoWork()
1084 chppTransportGetRequestTimeoutResponse(context, CHPP_ENDPOINT_CLIENT); in chppTransportDoWork()
1090 chppAppProcessRxDatagram(context->appContext, (uint8_t *)timeoutResponse, in chppTransportDoWork()
1098 chppTransportGetRequestTimeoutResponse(context, CHPP_ENDPOINT_SERVICE); in chppTransportDoWork()
1104 chppAppProcessRxDatagram(context->appContext, (uint8_t *)timeoutResponse, in chppTransportDoWork()
1115 * @param context State of the transport layer.
1119 static void chppAppendToPendingTxPacket(struct ChppTransportState *context, in chppAppendToPendingTxPacket() argument
1121 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppAppendToPendingTxPacket()
1123 size_t bufferSize = context->linkBufferSize; in chppAppendToPendingTxPacket()
1126 context->linkApi->getConfig(context->linkContext).txBufferLen); in chppAppendToPendingTxPacket()
1128 context->linkBufferSize += len; in chppAppendToPendingTxPacket()
1158 * @param context State of the transport layer.
1166 static bool chppEnqueueTxDatagram(struct ChppTransportState *context, in chppEnqueueTxDatagram() argument
1179 (uint8_t)(context->txDatagramQueue.pending + 1)); in chppEnqueueTxDatagram()
1186 header->command, (uint8_t)(context->txDatagramQueue.pending + 1)); in chppEnqueueTxDatagram()
1189 chppMutexLock(&context->mutex); in chppEnqueueTxDatagram()
1191 if (context->txDatagramQueue.pending >= CHPP_TX_DATAGRAM_QUEUE_LEN) { in chppEnqueueTxDatagram()
1196 (context->txDatagramQueue.front + context->txDatagramQueue.pending) % in chppEnqueueTxDatagram()
1198 context->txDatagramQueue.datagram[end].length = len; in chppEnqueueTxDatagram()
1199 context->txDatagramQueue.datagram[end].payload = buf; in chppEnqueueTxDatagram()
1200 context->txDatagramQueue.pending++; in chppEnqueueTxDatagram()
1202 if (context->txDatagramQueue.pending == 1) { in chppEnqueueTxDatagram()
1204 chppEnqueueTxPacket(context, packetCode); in chppEnqueueTxDatagram()
1210 chppMutexUnlock(&context->mutex); in chppEnqueueTxDatagram()
1220 * @param context State of the transport layer.
1225 struct ChppTransportState *context) { in chppSendPendingPacket() argument
1227 context->linkApi->send(context->linkContext, context->linkBufferSize); in chppSendPendingPacket()
1229 context->txStatus.lastTxTimeNs = chppGetCurrentTimeNs(); in chppSendPendingPacket()
1237 * @param context State of the transport layer.
1239 static void chppResetTransportContext(struct ChppTransportState *context) { in chppResetTransportContext() argument
1240 memset(&context->rxStatus, 0, sizeof(struct ChppRxStatus)); in chppResetTransportContext()
1241 memset(&context->rxDatagram, 0, sizeof(struct ChppDatagram)); in chppResetTransportContext()
1243 memset(&context->txStatus, 0, sizeof(struct ChppTxStatus)); in chppResetTransportContext()
1244 memset(&context->txDatagramQueue, 0, sizeof(struct ChppTxDatagramQueue)); in chppResetTransportContext()
1246 context->txStatus.sentSeq = in chppResetTransportContext()
1248 context->resetState = CHPP_RESET_STATE_RESETTING; in chppResetTransportContext()
1298 // (context->rxHeader is not wiped in reset) in chppReset()
1318 * @param context State of the transport layer.
1323 struct ChppTransportState *context, enum ChppEndpointType type) { in chppTransportGetRequestTimeoutResponse() argument
1324 CHPP_DEBUG_NOT_NULL(context); in chppTransportGetRequestTimeoutResponse()
1326 struct ChppAppState *appState = context->appContext; in chppTransportGetRequestTimeoutResponse()
1333 chppMutexLock(&context->mutex); in chppTransportGetRequestTimeoutResponse()
1388 chppMutexUnlock(&context->mutex); in chppTransportGetRequestTimeoutResponse()
1477 bool chppRxDataCb(struct ChppTransportState *context, const uint8_t *buf, in chppRxDataCb() argument
1480 CHPP_NOT_NULL(context); in chppRxDataCb()
1482 chppMutexLock(&context->mutex); in chppRxDataCb()
1483 if (context->rxStatus.state != CHPP_STATE_PREAMBLE && in chppRxDataCb()
1485 context->rxStatus.packetStartTimeNs + CHPP_TRANSPORT_RX_TIMEOUT_NS) { in chppRxDataCb()
1487 chppAbortRxPacket(context); in chppRxDataCb()
1489 chppMutexUnlock(&context->mutex); in chppRxDataCb()
1492 chppGetRxStatusLabel(context->rxStatus.state)); in chppRxDataCb()
1494 context->rxStatus.lastDataTimeMs = (uint32_t)(now / CHPP_NSEC_PER_MSEC); in chppRxDataCb()
1495 context->rxStatus.numTotalDataBytes += len; in chppRxDataCb()
1499 chppMutexLock(&context->mutex); in chppRxDataCb()
1505 switch (context->rxStatus.state) { in chppRxDataCb()
1508 chppConsumePreamble(context, &buf[consumed], len - consumed); in chppRxDataCb()
1512 consumed += chppConsumeHeader(context, &buf[consumed], len - consumed); in chppRxDataCb()
1516 consumed += chppConsumePayload(context, &buf[consumed], len - consumed); in chppRxDataCb()
1520 consumed += chppConsumeFooter(context, &buf[consumed], len - consumed); in chppRxDataCb()
1525 context->rxStatus.state); in chppRxDataCb()
1526 chppSetRxState(context, CHPP_STATE_PREAMBLE); in chppRxDataCb()
1529 chppMutexUnlock(&context->mutex); in chppRxDataCb()
1532 return (context->rxStatus.state == CHPP_STATE_PREAMBLE && in chppRxDataCb()
1533 context->rxStatus.locInState == 0); in chppRxDataCb()
1536 void chppRxPacketCompleteCb(struct ChppTransportState *context) { in chppRxPacketCompleteCb() argument
1537 chppMutexLock(&context->mutex); in chppRxPacketCompleteCb()
1538 if (context->rxStatus.state != CHPP_STATE_PREAMBLE) { in chppRxPacketCompleteCb()
1540 chppGetRxStatusLabel(context->rxStatus.state), in chppRxPacketCompleteCb()
1541 context->rxHeader.seq, context->rxHeader.length); in chppRxPacketCompleteCb()
1542 chppAbortRxPacket(context); in chppRxPacketCompleteCb()
1543 chppEnqueueTxPacket(context, CHPP_TRANSPORT_ERROR_HEADER); // NACK in chppRxPacketCompleteCb()
1545 chppMutexUnlock(&context->mutex); in chppRxPacketCompleteCb()
1548 bool chppEnqueueTxDatagramOrFail(struct ChppTransportState *context, void *buf, in chppEnqueueTxDatagramOrFail() argument
1551 bool resetting = (context->resetState == CHPP_RESET_STATE_RESETTING); in chppEnqueueTxDatagramOrFail()
1557 context, CHPP_TRANSPORT_ERROR_NONE, buf, len)) { in chppEnqueueTxDatagramOrFail()
1572 void chppEnqueueTxErrorDatagram(struct ChppTransportState *context, in chppEnqueueTxErrorDatagram() argument
1574 chppMutexLock(&context->mutex); in chppEnqueueTxErrorDatagram()
1575 bool resetting = (context->resetState == CHPP_RESET_STATE_RESETTING); in chppEnqueueTxErrorDatagram()
1594 chppEnqueueTxPacket(context, CHPP_ATTR_AND_ERROR_TO_PACKET_CODE( in chppEnqueueTxErrorDatagram()
1597 chppMutexUnlock(&context->mutex); in chppEnqueueTxErrorDatagram()
1601 struct ChppTransportState *context) { in chppTransportGetTimeUntilNextDoWorkNs() argument
1603 // This function is called in the context of the transport worker thread. in chppTransportGetTimeUntilNextDoWorkNs()
1604 // As we do not know if the transport is used in the context of a service in chppTransportGetTimeUntilNextDoWorkNs()
1607 MIN(context->appContext->nextClientRequestTimeoutNs, in chppTransportGetTimeUntilNextDoWorkNs()
1608 context->appContext->nextServiceRequestTimeoutNs); in chppTransportGetTimeUntilNextDoWorkNs()
1610 if (context->txStatus.hasPacketsToSend || in chppTransportGetTimeUntilNextDoWorkNs()
1611 context->resetState == CHPP_RESET_STATE_RESETTING) { in chppTransportGetTimeUntilNextDoWorkNs()
1614 ((context->txStatus.lastTxTimeNs == 0) in chppTransportGetTimeUntilNextDoWorkNs()
1616 : context->txStatus.lastTxTimeNs)); in chppTransportGetTimeUntilNextDoWorkNs()
1635 void chppWorkThreadStart(struct ChppTransportState *context) { in chppWorkThreadStart() argument
1636 chppTransportSendReset(context, CHPP_TRANSPORT_ATTR_RESET, in chppWorkThreadStart()
1642 uint64_t timeout = chppTransportGetTimeUntilNextDoWorkNs(context); in chppWorkThreadStart()
1644 signals = chppNotifierGetSignal(&context->notifier); in chppWorkThreadStart()
1646 signals = chppNotifierWait(&context->notifier); in chppWorkThreadStart()
1648 signals = chppNotifierTimedWait(&context->notifier, timeout); in chppWorkThreadStart()
1651 } while (chppWorkThreadHandleSignal(context, signals)); in chppWorkThreadStart()
1654 bool chppWorkThreadHandleSignal(struct ChppTransportState *context, in chppWorkThreadHandleSignal() argument
1659 chppWorkMonitorPreProcess(&context->workMonitor); in chppWorkThreadHandleSignal()
1668 chppWorkHandleTimeout(context); in chppWorkThreadHandleSignal()
1671 chppTransportDoWork(context); in chppWorkThreadHandleSignal()
1674 context->linkApi->doWork(context->linkContext, in chppWorkThreadHandleSignal()
1681 chppWorkMonitorPostProcess(&context->workMonitor); in chppWorkThreadHandleSignal()
1700 static void chppWorkHandleTimeout(struct ChppTransportState *context) { in chppWorkHandleTimeout() argument
1702 const bool isTxTimeout = currentTimeNs - context->txStatus.lastTxTimeNs >= in chppWorkHandleTimeout()
1704 const bool isResetting = context->resetState == CHPP_RESET_STATE_RESETTING; in chppWorkHandleTimeout()
1709 context->txStatus.lastTxTimeNs / CHPP_NSEC_PER_MSEC, in chppWorkHandleTimeout()
1710 context->txStatus.txAttempts, isResetting); in chppWorkHandleTimeout()
1711 chppTransportDoWork(context); in chppWorkHandleTimeout()
1714 MIN(context->appContext->nextClientRequestTimeoutNs, in chppWorkHandleTimeout()
1715 context->appContext->nextServiceRequestTimeoutNs); in chppWorkHandleTimeout()
1718 chppTransportDoWork(context); in chppWorkHandleTimeout()
1722 if (isResetting && (currentTimeNs - context->resetTimeNs >= in chppWorkHandleTimeout()
1724 if (context->resetCount + 1 < CHPP_TRANSPORT_MAX_RESET) { in chppWorkHandleTimeout()
1726 context->resetCount++; in chppWorkHandleTimeout()
1727 chppReset(context, CHPP_TRANSPORT_ATTR_RESET, in chppWorkHandleTimeout()
1731 context->txStatus.txAttempts = 0; in chppWorkHandleTimeout()
1732 context->resetState = CHPP_RESET_STATE_PERMANENT_FAILURE; in chppWorkHandleTimeout()
1733 chppClearTxDatagramQueue(context); in chppWorkHandleTimeout()
1738 void chppWorkThreadStop(struct ChppTransportState *context) { in chppWorkThreadStop() argument
1739 chppNotifierSignal(&context->notifier, CHPP_TRANSPORT_SIGNAL_EXIT); in chppWorkThreadStop()
1742 void chppLinkSendDoneCb(struct ChppTransportState *context, in chppLinkSendDoneCb() argument
1748 chppMutexLock(&context->mutex); in chppLinkSendDoneCb()
1750 context->txStatus.linkBusy = false; in chppLinkSendDoneCb()
1755 chppMutexUnlock(&context->mutex); in chppLinkSendDoneCb()
1758 void chppDatagramProcessDoneCb(struct ChppTransportState *context, in chppDatagramProcessDoneCb() argument
1760 UNUSED_VAR(context); in chppDatagramProcessDoneCb()
1765 uint8_t chppRunTransportLoopback(struct ChppTransportState *context, in chppRunTransportLoopback() argument
1770 context->loopbackResult = result; in chppRunTransportLoopback()
1774 context->loopbackResult = CHPP_APP_ERROR_UNSPECIFIED; in chppRunTransportLoopback()
1776 if (len == 0 || len > chppTransportTxMtuSize(context)) { in chppRunTransportLoopback()
1778 context->loopbackResult = result; in chppRunTransportLoopback()
1780 } else if (context->txStatus.linkBusy) { in chppRunTransportLoopback()
1782 context->loopbackResult = result; in chppRunTransportLoopback()
1784 } else if (context->transportLoopbackData.payload != NULL) { in chppRunTransportLoopback()
1786 context->loopbackResult = result; in chppRunTransportLoopback()
1788 } else if ((context->transportLoopbackData.payload = chppMalloc(len)) == in chppRunTransportLoopback()
1791 context->loopbackResult = result; in chppRunTransportLoopback()
1794 uint8_t *linkTxBuffer = context->linkApi->getTxBuffer(context->linkContext); in chppRunTransportLoopback()
1795 context->transportLoopbackData.length = len; in chppRunTransportLoopback()
1796 memcpy(context->transportLoopbackData.payload, buf, len); in chppRunTransportLoopback()
1798 context->txStatus.linkBusy = true; in chppRunTransportLoopback()
1799 context->linkBufferSize = 0; in chppRunTransportLoopback()
1801 context->linkApi->getConfig(context->linkContext); in chppRunTransportLoopback()
1803 context->linkBufferSize += chppAddPreamble(linkTxBuffer); in chppRunTransportLoopback()
1806 (struct ChppTransportHeader *)&linkTxBuffer[context->linkBufferSize]; in chppRunTransportLoopback()
1807 context->linkBufferSize += sizeof(*txHeader); in chppRunTransportLoopback()
1812 size_t payloadLen = MIN(len, chppTransportTxMtuSize(context)); in chppRunTransportLoopback()
1814 chppAppendToPendingTxPacket(context, buf, payloadLen); in chppRunTransportLoopback()
1816 chppAddFooter(context); in chppRunTransportLoopback()
1820 context->linkBufferSize, txHeader->length, len); in chppRunTransportLoopback()
1821 enum ChppLinkErrorCode error = chppSendPendingPacket(context); in chppRunTransportLoopback()
1825 chppLinkSendDoneCb(context, error); in chppRunTransportLoopback()
1829 CHPP_FREE_AND_NULLIFY(context->transportLoopbackData.payload); in chppRunTransportLoopback()
1830 context->transportLoopbackData.length = 0; in chppRunTransportLoopback()
1843 void chppTransportSendReset(struct ChppTransportState *context, in chppTransportSendReset() argument
1847 CHPP_ASSERT_LOG((context->txDatagramQueue.pending == 0 && in chppTransportSendReset()
1848 context->txDatagramQueue.front == 0), in chppTransportSendReset()
1867 chppSetResetComplete(context); in chppTransportSendReset()
1872 context->resetTimeNs = chppGetCurrentTimeNs(); in chppTransportSendReset()
1874 chppEnqueueTxDatagram(context, in chppTransportSendReset()
1880 size_t chppTransportTxMtuSize(const struct ChppTransportState *context) { in chppTransportTxMtuSize() argument
1882 context->linkApi->getConfig(context->linkContext); in chppTransportTxMtuSize()
1887 size_t chppTransportRxMtuSize(const struct ChppTransportState *context) { in chppTransportRxMtuSize() argument
1889 context->linkApi->getConfig(context->linkContext); in chppTransportRxMtuSize()