@@ -82,18 +82,20 @@ size_t historyEncodeRecord(const BinaryHistoryRecord& rec,
8282 /* DELTA */
8383 uint8_t * p = buf;
8484
85- /* Mask: bit 0=amb_temp, bit 1=amb_hum, bit 2..17=sensors[0..15]. */
86- uint16_t mask = 0 ;
87- if (rec.ambientTemp != HIST_NAN_SENTINEL ) mask |= (1u << 0 );
88- if (rec.ambientHum != HIST_NAN_SENTINEL ) mask |= (1u << 1 );
85+ /* Mask: bit 0=amb_temp, bit 1=amb_hum, bit 2..17=sensors[0..15].
86+ * Uses 3 bytes (18 bits) — uint32_t to fit all 16 sensor slots. */
87+ uint32_t mask = 0 ;
88+ if (rec.ambientTemp != HIST_NAN_SENTINEL ) mask |= (1ul << 0 );
89+ if (rec.ambientHum != HIST_NAN_SENTINEL ) mask |= (1ul << 1 );
8990 for (int i = 0 ; i < MAX_SENSORS ; i++) {
90- if (rec.sensors [i] != HIST_NAN_SENTINEL ) mask |= (1u << (2 + i));
91+ if (rec.sensors [i] != HIST_NAN_SENTINEL ) mask |= (1ul << (2 + i));
9192 }
9293
93- if ((size_t )(p - buf) + 2 > bufSize) return 0 ;
94+ if ((size_t )(p - buf) + 3 > bufSize) return 0 ;
9495 p[0 ] = (uint8_t )(mask & 0xFF );
95- p[1 ] = (uint8_t )((mask >> 8 ) & 0x0F ); /* ensure top 4 bits = 0 */
96- p += 2 ;
96+ p[1 ] = (uint8_t )((mask >> 8 ) & 0xFF );
97+ p[2 ] = (uint8_t )((mask >> 16 ) & 0x03 ); /* only bits 16-17 used */
98+ p += 3 ;
9799
98100 /* Δepoch always present. In normal use = configured interval (1B). */
99101 int32_t depoch = (int32_t )rec.epoch - (int32_t )s.lastValid .epoch ;
@@ -108,19 +110,19 @@ size_t historyEncodeRecord(const BinaryHistoryRecord& rec,
108110 return true ;
109111 };
110112
111- if (!encField (mask & (1u << 0 ), s.fieldHasValid [0 ], rec.ambientTemp , s.lastValid .ambientTemp )) return 0 ;
112- if (!encField (mask & (1u << 1 ), s.fieldHasValid [1 ], rec.ambientHum , s.lastValid .ambientHum )) return 0 ;
113+ if (!encField (mask & (1ul << 0 ), s.fieldHasValid [0 ], rec.ambientTemp , s.lastValid .ambientTemp )) return 0 ;
114+ if (!encField (mask & (1ul << 1 ), s.fieldHasValid [1 ], rec.ambientHum , s.lastValid .ambientHum )) return 0 ;
113115 for (int i = 0 ; i < MAX_SENSORS ; i++) {
114- if (!encField (mask & (1u << (2 + i)), s.fieldHasValid [2 + i],
116+ if (!encField (mask & (1ul << (2 + i)), s.fieldHasValid [2 + i],
115117 rec.sensors [i], s.lastValid .sensors [i])) return 0 ;
116118 }
117119
118120 /* Update state only for fields actually present. */
119121 s.lastValid .epoch = rec.epoch ;
120- if (mask & (1u << 0 )) { s.lastValid .ambientTemp = rec.ambientTemp ; s.fieldHasValid [0 ] = true ; }
121- if (mask & (1u << 1 )) { s.lastValid .ambientHum = rec.ambientHum ; s.fieldHasValid [1 ] = true ; }
122+ if (mask & (1ul << 0 )) { s.lastValid .ambientTemp = rec.ambientTemp ; s.fieldHasValid [0 ] = true ; }
123+ if (mask & (1ul << 1 )) { s.lastValid .ambientHum = rec.ambientHum ; s.fieldHasValid [1 ] = true ; }
122124 for (int i = 0 ; i < MAX_SENSORS ; i++) {
123- if (mask & (1u << (2 + i))) {
125+ if (mask & (1ul << (2 + i))) {
124126 s.lastValid .sensors [i] = rec.sensors [i];
125127 s.fieldHasValid [2 + i] = true ;
126128 }
@@ -148,11 +150,11 @@ size_t historyDecodeRecord(const uint8_t* buf, size_t bufLen,
148150 return sizeof (BinaryHistoryRecord);
149151 }
150152
151- if (bufLen < 2 ) return 0 ;
153+ if (bufLen < 3 ) return 0 ;
152154 const uint8_t * p = buf;
153155
154- uint16_t mask = (uint16_t )p[0 ] | ((uint16_t )p[1 ] << 8 );
155- p += 2 ;
156+ uint32_t mask = (uint32_t )p[0 ] | ((uint32_t )p[1 ] << 8 ) | (( uint32_t )p[ 2 ] << 16 );
157+ p += 3 ;
156158
157159 int32_t depoch = 0 ;
158160 size_t n = readVarintZ (p, bufLen - (size_t )(p - buf), depoch);
@@ -172,22 +174,22 @@ size_t historyDecodeRecord(const uint8_t* buf, size_t bufLen,
172174 };
173175
174176 int16_t tmpTemp = HIST_NAN_SENTINEL , tmpHum = HIST_NAN_SENTINEL ;
175- if (!decField (mask & (1u << 0 ), s.fieldHasValid [0 ], s.lastValid .ambientTemp , &tmpTemp)) return 0 ;
176- if (!decField (mask & (1u << 1 ), s.fieldHasValid [1 ], s.lastValid .ambientHum , &tmpHum)) return 0 ;
177+ if (!decField (mask & (1ul << 0 ), s.fieldHasValid [0 ], s.lastValid .ambientTemp , &tmpTemp)) return 0 ;
178+ if (!decField (mask & (1ul << 1 ), s.fieldHasValid [1 ], s.lastValid .ambientHum , &tmpHum)) return 0 ;
177179 outRec.ambientTemp = tmpTemp;
178180 outRec.ambientHum = tmpHum;
179181 for (int i = 0 ; i < MAX_SENSORS ; i++) {
180182 int16_t tmpS = HIST_NAN_SENTINEL ;
181- if (!decField (mask & (1u << (2 + i)), s.fieldHasValid [2 + i],
183+ if (!decField (mask & (1ul << (2 + i)), s.fieldHasValid [2 + i],
182184 s.lastValid .sensors [i], &tmpS)) return 0 ;
183185 outRec.sensors [i] = tmpS;
184186 }
185187
186188 s.lastValid .epoch = outRec.epoch ;
187- if (mask & (1u << 0 )) { s.lastValid .ambientTemp = outRec.ambientTemp ; s.fieldHasValid [0 ] = true ; }
188- if (mask & (1u << 1 )) { s.lastValid .ambientHum = outRec.ambientHum ; s.fieldHasValid [1 ] = true ; }
189+ if (mask & (1ul << 0 )) { s.lastValid .ambientTemp = outRec.ambientTemp ; s.fieldHasValid [0 ] = true ; }
190+ if (mask & (1ul << 1 )) { s.lastValid .ambientHum = outRec.ambientHum ; s.fieldHasValid [1 ] = true ; }
189191 for (int i = 0 ; i < MAX_SENSORS ; i++) {
190- if (mask & (1u << (2 + i))) {
192+ if (mask & (1ul << (2 + i))) {
191193 s.lastValid .sensors [i] = outRec.sensors [i];
192194 s.fieldHasValid [2 + i] = true ;
193195 }
0 commit comments