RDKEMW-13607: merge pair code with mac hash methods#191
RDKEMW-13607: merge pair code with mac hash methods#191
Conversation
There was a problem hiding this comment.
Pull request overview
This PR unifies BLE targeted pairing so the system uses a single “pair with code” path for both advertising-name-based pairing and MAC-hash-based pairing, removing the separate MAC-hash pairing APIs and the need to pass the originating IR key code through IPC.
Changes:
- Remove
pairWithMacHash/startPairingWithMacHash/startWithMacHashAPIs and route all targeted pairing through the existing “pair with code” flow. - Update the BLE model config parsing to use a new
advertisingNamesobject (requiredregexPairing, optional targeted pairing format + reconnect regex). - Simplify IPC for
Main_StartPairWithCodeby removing thekey_codefield.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/ctrlm_ir_controller.cpp |
Stops sending key_code in the pair-with-code request and only forwards the pairing byte. |
src/ble/hal/configsettings/configmodelsettings.cpp |
Parses new advertisingNames config structure; adjusts optional/required behavior and logging. |
src/ble/hal/blercu/blercupairingstatemachine.h |
Removes startWithMacHash() declaration. |
src/ble/hal/blercu/blercupairingstatemachine.cpp |
Merges MAC-hash and code pairing behavior into startWithCode() and keeps MAC-hash matching as a fallback. |
src/ble/hal/blercu/blercucontroller.h |
Removes startPairingWithMacHash() from the controller interface. |
src/ble/hal/blercu/blercucontroller.cpp |
Removes the controller implementation of MAC-hash pairing. |
src/ble/hal/blercu/blercucontroller_p.h |
Removes override for startPairingWithMacHash(). |
src/ble/ctrlm_ble_rcu_interface.h |
Removes pairWithMacHash() from the BLE RCU interface. |
src/ble/ctrlm_ble_rcu_interface.cpp |
Removes pairWithMacHash() implementation; pairing is done via pairWithCode(). |
src/ble/ctrlm_ble_network.cpp |
Always calls pairWithCode() for targeted pairing requests. |
include/ctrlm_ipc.h |
Removes key_code from ctrlm_iarm_call_StartPairWithCode_params_t. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ctrlm_iarm_call_StartPairWithCode_params_t params; | ||
| params.key_code = key_code; | ||
| params.pair_code = commandCode; | ||
|
|
There was a problem hiding this comment.
ctrlm_iarm_call_StartPairWithCode_params_t is allocated on the stack and only pair_code is assigned; api_revision/network_id/result remain uninitialized. Even though this call is synchronous today, leaving these fields uninitialized risks propagating garbage if later code starts logging/validating them. Consider zero-initializing params (e.g., memset_s or brace-init) and explicitly setting api_revision + network_id where applicable.
| typedef struct { | ||
| unsigned char api_revision; ///< Revision of this API | ||
| ctrlm_network_id_t network_id; ///< IN - Identifier of network | ||
| unsigned int key_code; ///< IN - Key code from device | ||
| unsigned int pair_code; ///< IN - Pairing code from device | ||
| ctrlm_iarm_call_result_t result; ///< OUT - return code of the operation | ||
| } ctrlm_iarm_call_StartPairWithCode_params_t; |
There was a problem hiding this comment.
The public IARM struct ctrlm_iarm_call_StartPairWithCode_params_t changed layout (key_code removed). This is a breaking ABI/API change for any out-of-process IARM client that still uses the old struct layout, and currently the server-side handler for Main_StartPairWithCode does not appear to validate api_revision. Please bump CTRLM_MAIN_IARM_BUS_API_REVISION and/or add explicit api_revision validation for this call so old clients fail safely instead of misinterpreting fields.
| // Advertising names field | ||
| json_t *advertisingNamesObj = json_object_get(json, "advertisingNames"); | ||
| if (!advertisingNamesObj || !json_is_object(advertisingNamesObj)) { | ||
| XLOGD_ERROR("missing or invalid 'advertisingNames' field"); | ||
| return; | ||
| } | ||
|
|
||
| // scanNameFormat field | ||
| obj = json_object_get(json, "scanNameFormat"); | ||
| // advertisingNames.regexPairing field | ||
| obj = json_object_get(advertisingNamesObj, "regexPairing"); | ||
| if (!obj || !json_is_string(obj)) { | ||
| XLOGD_ERROR("invalid 'scanNameFormat' field, this is required so returning..."); | ||
| XLOGD_ERROR("invalid required 'advertisingNames.regexPairing' field, aborting..."); | ||
| return; | ||
| } | ||
| m_scanNameMatcher = std::regex(json_string_value(obj), std::regex_constants::ECMAScript); | ||
| XLOGD_INFO("Pairing name regex <%s>", json_string_value(obj)); | ||
|
|
||
| // (optional) connectNameFormat field | ||
| obj = json_object_get(json, "connectNameFormat"); | ||
| if (!obj || !json_is_string(obj)) { | ||
| XLOGD_WARN("invalid 'connectNameFormat' field, not fatal, setting to scanNameFormat"); | ||
| m_connectNameMatcher = m_scanNameMatcher; | ||
| m_connectNameMatcher = m_scanNameMatcher; | ||
| XLOGD_INFO("Pairing and reconnect advertising name regex <%s>", json_string_value(obj)); | ||
|
|
There was a problem hiding this comment.
The JSON schema example in the class comment still documents the legacy fields (scanNameFormat/connectNameFormat/etc), but the parser now requires advertisingNames.regexPairing and uses advertisingNames.optional.{formatSpecifierTargetedPairing,regexReconnect}. Please update the documented example/schema so it matches the new required/optional config fields.
| // advertisingNames.optional array | ||
| json_t *optionalNames = json_object_get(advertisingNamesObj, "optional"); | ||
| if (!optionalNames || !json_is_object(optionalNames)) { | ||
| XLOGD_INFO("missing or invalid 'optionalNames' field, not fatal, continuing..."); |
There was a problem hiding this comment.
The comment says "advertisingNames.optional array" but the code treats advertisingNames.optional as a JSON object (json_is_object). Also, the log message refers to "optionalNames" rather than the actual key path "advertisingNames.optional", which makes config/debugging harder. Please align the comment + log messages with the real JSON shape and key name.
| // advertisingNames.optional array | |
| json_t *optionalNames = json_object_get(advertisingNamesObj, "optional"); | |
| if (!optionalNames || !json_is_object(optionalNames)) { | |
| XLOGD_INFO("missing or invalid 'optionalNames' field, not fatal, continuing..."); | |
| // advertisingNames.optional object | |
| json_t *optionalNames = json_object_get(advertisingNamesObj, "optional"); | |
| if (!optionalNames || !json_is_object(optionalNames)) { | |
| XLOGD_INFO("missing or invalid 'advertisingNames.optional' field, not fatal, continuing..."); |
| } | ||
| m_servicesOptional.insert(serviceStr); | ||
| } | ||
| servicesOptionalStr = servicesOptionalStr.substr(0, servicesOptionalStr.length() - 2); // Remove the trailing comma and space |
There was a problem hiding this comment.
servicesOptionalStr is always trimmed with substr(0, length() - 2) even when m_servicesOptional is empty (e.g., services.optional exists but is an empty array). This relies on unsigned wraparound and makes the intent unclear. Consider trimming only when the string length is >= 2 (or build the comma-separated string without a trailing delimiter).
| servicesOptionalStr = servicesOptionalStr.substr(0, servicesOptionalStr.length() - 2); // Remove the trailing comma and space | |
| if (!servicesOptionalStr.empty()) { | |
| // Remove the trailing comma and space | |
| servicesOptionalStr = servicesOptionalStr.substr(0, servicesOptionalStr.length() - 2); | |
| } |
| } else if (m_pairingMacList.size() != 0) { | ||
| // Device not found through name match or MAC hash so let's check a mac address list | ||
| // Pairing via a mac address list clears supported names and the pairing mac hash | ||
| if (m_pairingMacList.size() != 0) { | ||
| // check if the mac address matches any of the ones in the filter list (if it exists) | ||
| bool found = false; |
There was a problem hiding this comment.
In processDevice(), the else if (m_pairingMacList.size() != 0) branch immediately re-checks if (m_pairingMacList.size() != 0) inside, which is redundant and adds noise to the control flow. Please remove the inner size check and keep a single guard for the MAC list path.
No description provided.