@@ -437,6 +437,12 @@ struct osdp_pd {
437437 uint32_t packet_scan_skip ;
438438 bool reply_prebuilt ;
439439
440+ /* Retransmit cache: last successfully-sent reply bytes live in the
441+ * shared tx_buf as long as nothing overwrites them. On a sequence
442+ * repeat we re-emit those bytes verbatim (see phy_check_packet). */
443+ uint16_t last_tx_len ; /* 0 = cache empty */
444+ uint8_t last_cmd_id ;
445+
440446 int cmd_id ; /* Currently processing command ID */
441447 int reply_id ; /* Currently processing reply ID */
442448 union {
@@ -477,6 +483,7 @@ struct osdp {
477483 struct osdp_pd * pd ; /* base of PD list (must be at lest one) */
478484 struct osdp_channel channel ; /* OSDP channel */
479485 uint8_t tx_buf [OSDP_PACKET_BUF_SIZE ];
486+ uint8_t * rx_buf ; /* RX landing buffer: aliased to tx_buf in CP; distinct in PD */
480487
481488 /* CP event callback to app with opaque arg pointer as passed by app */
482489 void * event_callback_arg ;
@@ -704,6 +711,8 @@ static inline void sc_deactivate(struct osdp_pd *pd)
704711 osdp_sc_teardown (pd );
705712 }
706713 CLEAR_FLAG (pd , PD_FLAG_SC_ACTIVE );
714+ /* Cached retransmit reply is no longer meaningful without SC. */
715+ pd -> last_tx_len = 0 ;
707716}
708717
709718static inline void make_request (struct osdp_pd * pd , uint32_t req ) {
@@ -791,13 +800,20 @@ static inline struct osdp_rb *cp_static_rx_rb_array_get(void)
791800
792801static inline struct osdp * cp_ctx_alloc (void )
793802{
803+ struct osdp * ctx ;
794804#ifdef OPT_OSDP_STATIC
795- struct osdp * ctx = cp_static_ctx_get ();
805+ ctx = cp_static_ctx_get ();
796806 memset (ctx , 0 , sizeof (struct osdp ));
797- return ctx ;
798807#else
799- return calloc (1 , sizeof (struct osdp ));
808+ ctx = calloc (1 , sizeof (struct osdp ));
809+ if (!ctx ) {
810+ return NULL ;
811+ }
800812#endif /* OPT_OSDP_STATIC */
813+ /* CP mode does not cache retransmit replies; alias rx_buf to tx_buf
814+ * to preserve the legacy shared-buffer behavior with zero cost. */
815+ ctx -> rx_buf = ctx -> tx_buf ;
816+ return ctx ;
801817}
802818
803819static inline struct osdp_pd * cp_pd_array_alloc (int old_num_pd , int num_pd )
@@ -861,6 +877,12 @@ static inline struct osdp_pd *pd_static_ctx_pd_get(void)
861877 return & g_osdp_pd_ctx ;
862878}
863879
880+ static inline uint8_t * pd_static_rx_buf_get (void )
881+ {
882+ static uint8_t g_osdp_pd_rx_buf [OSDP_PACKET_BUF_SIZE ];
883+ return g_osdp_pd_rx_buf ;
884+ }
885+
864886#ifdef OPT_OSDP_RX_ZERO_COPY
865887
866888static inline struct osdp_rx_pkt * pd_static_rx_pkt_get (void )
@@ -883,13 +905,23 @@ static inline struct osdp_rb *pd_static_rx_rb_get(void)
883905
884906static inline struct osdp * pd_ctx_alloc (void )
885907{
908+ struct osdp * ctx ;
886909#ifdef OPT_OSDP_STATIC
887- struct osdp * ctx = pd_static_ctx_get ();
910+ ctx = pd_static_ctx_get ();
888911 memset (ctx , 0 , sizeof (struct osdp ));
889- return ctx ;
912+ ctx -> rx_buf = pd_static_rx_buf_get () ;
890913#else
891- return calloc (1 , sizeof (struct osdp ));
914+ ctx = calloc (1 , sizeof (struct osdp ));
915+ if (!ctx ) {
916+ return NULL ;
917+ }
918+ ctx -> rx_buf = calloc (1 , OSDP_PACKET_BUF_SIZE );
919+ if (!ctx -> rx_buf ) {
920+ free (ctx );
921+ return NULL ;
922+ }
892923#endif /* OPT_OSDP_STATIC */
924+ return ctx ;
893925}
894926
895927static inline struct osdp_pd * pd_instance_alloc (void )
0 commit comments