Add getLen() and getTag() method to get length and tag of tlv8_t.
Also overrode subscript operator [] so you can access any element of internal uint8_t array.
Given previous additions (such as getVal()) there is now no reason to need to access the underlying std::unique_ptr directly.
Makes it easier to chain .add() functions as well as dynamically create sub TLVs.
Changing TLV8::add() in this fashion also required updating various use cases of TLV::add() in HAP.cpp where add() was used to reserve space for a blank TLV element. All changes have been tested.
This is much more memory efficient. Instead of decoding entire STRING from base64 to a temporary buffer or potentially very large size and then unpacking into TLV object, we decode a maximum of 48 characters at a time and unpack the resulting 36 (max) bytes until entire STRING is consumed.
getTLV() returns pack_size of final TLV, unless there is a problem with conversion, in which cae TLV is wiped and return value=0
Works, but is memory-inefficient since it decodes entire string before unpacking. Need to add new functionality to TLV8 so that unpacking can be done in chunks similar to how pack() works.
Also need to create getNewTLV() OR make all get/getNew generic to reduce code size.
Though this increases space requirement for TLV8 (just a little), using std::list allows adding elements directly to end, which ensure the order is maintained when packing and unpacking. Will avoid potential confusion when TLV8 is used for Characteristics.
Throws warning, but still performs change, if setVal() is used within update() to change the value of a Characteristic that is being updated by the Home App, UNLESS the Characteristics has requested a write-response (in which case setVal() is expected).
Throw warning, and DOES NOT perform change, if setVal() is used on a Characteristic without EV permission, UNLESS it has been used in update() in response to a write-response request.
Also added diagnostic to 'i' CLI command that indicates which connections have currently asked to EV Notifications for each Characteristic. Only applies if EV permission is set for a Characteristic.
HAPClient::putCharacteristics() now parses for "r":true in JSON, which is the HAP request for a write-response. When found, HomeSpan will return with a full write-response for all Characteristics updated using "207 Multi-Status", where "value" will be included only if "r":true was specified for a Characteristic.
HomeSpan processes "r":true for any Characteristic regardless if permissions includes WR.
To change the value of the Characteristic from within an update() method, use setVal() WITH OPTIONAL SECOND ARGUMENT AS FALSE to supress an EV broadcast (in the unlikely event that there was a notification subscriber).
To do: Consider generally disallowing the changing of any Characteristic value from within update() using setVal() unless the Characteristic has WR permission. And if so, automatically surpress EV notification.
When printing SpanPoint configuration data to the Serial Monitor info using the 'i' CLI command, HomeSpan did NOT check to see if the receiveSize was zero, in which case there would be no queue, which caused a crash when trying to report the queue depth. Since all existing SpanPoint examples were based on receiving data from remote devices, this bug was never encountered (since the receiveSize was always greater than zero).
Fix: check to see if receiveSize==0. If it is, do not retrieve queue depth, but report zero instead.
Eliminated the need to instantiate a static HKDF structure within HAPClient since there is no storage within HKDF itself, just a single function call (create).
homeSpan.setPairingCode() operates silently if called from within a sketch, but will report error to Serial Monitor and HALT sketch if code is invalid.
Otherwise, if called from 'S', or from AP, or as default during start-up, diagnostics are printed as usual and sketch will NOT halt if invalid code is provided