Hi,
I was recently looking on how we could reduce size of SM code.
So my proposal is to change the way PDUs are parsed and constructed.
Instead of having ble_sm_foo_parse(), ble_sm_foo_write() and ble_sm_foo_tx()
for parsing and constructing PDU byte by byte we could use packed structures
for describing PDU and let compiler figure out details related to
unaligned access.
This also reduces number of memcpy since there is no need for intermediate
structures describing PDUs as those are packed now and can be cast directly
to underlying mbuf buffer.
So now parsing incoming data looks like:
struct ble_sm_pair_confirm *cmd;
rc = ble_hs_mbuf_pullup_base(om, sizeof(*cmd));
if (rc)
return;
cmd = (struct ble_sm_pair_confirm *)(*om)->om_data;
/* use cmd-> to access fields */
while constructing and sending PDU:
struct ble_sm_pair_confirm *cmd;
struct os_mbuf *txom;
cmd = ble_sm_cmd_get(BLE_SM_OP_PAIR_CONFIRM, sizeof(*cmd), &txom);
if (cmd == NULL)
return;
/* fill cmd with data */
ble_sm_tx(proc->conn_handle, txom);
For convenience casting in RX path could be also wrapped in some helper macro.
My experiments shows following code size reduction in net_nimble_host.a when
building bletiny app: 137112 bytes to 136008 bytes so almost 1100
bytes difference.
Code is available at [1]. I'm not making it a pull request yet since
I'd like to get some
feedback about this approach from others. Also I still need to get
tests passing since
SM keys related tests fail now (and I'm not yet sure why). I tested
this with Android
phone and both legacy and LE SC seems to work just fine.
Also this approach with packed structs could probably be used for
other protocols
like L2CAP or ATT.
Comments are welcome.
[1] https://github.com/sjanc/incubator-mynewt-core/commits/sm
--
pozdrawiam
Szymon K. Janc