Skip to content

Jira 793 Support Characteristic UUID that is not subset of Service, g… #451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 1, 2017

Conversation

SidLeung
Copy link
Contributor

…it 384

Root cause:

  • Nordic stack does not return long UUID for Characteristic
    discovery. It is expecting Characteristic UUID is a
    subset of the Service UUID (eg. a sequential increament of
    the Service UUID).
  • In order for the Central mode (to behave like Apple) to
    discover long Characteristic UUID, the process is now done
    in two steps (similar to the Service discovery). First,
    initiate a read of the Characteristic and then discover the
    long UUID upon successful read.

Code Mods:

  1. BLECallbacks.cpp:
    • Added a call back to handle the read Characteristic
      completion event.
  2. BLECallbacks.h:
    • Prototyping.
  3. BLEProfileManager.cpp:
    • Added getServiceBySubHandle() to enable the call back to
      locate the Service of a discovered Characteristic.
  4. BLEProfileManager.h:
    • Prototyping.
  5. BLEServiceImp.cpp:
    • This is where the two steps Characteristic discovery is
      implemented. At discoverAttributes(), reading of
      Characteristic is first initiated. When the stack
      completes the operation, extract the UUID thereafter.
    • To support this two steps process, additional functions,
      discoverNextCharacteristic and readCharacteristic, are
      added.
  6. BLEServiceImp.h:
    • Prototyping.

    • Change the discover process.

    • Add read operation after discover returned invalid UUID.

@SidLeung
Copy link
Contributor Author

@bigdinotech @eriknyquist , please review the code change.

@russmcinnis @noelpaz , this change is to make our library to behave more like an Apple Central. The capability of discovering Characteristic UUID that is not sequential increment of the Service UUID. Please use an existing Peripheral sketch, modify the Characteristic UUID so that it is different from its Service UUID, and use a Central sketch to discover the Characteristic.

params,
data,
length);
pr_debug(LOG_MODULE_BLE, "%s-%d:ret-%d", __FUNCTION__, __LINE__, ret);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr_debug? should this be here? not sure if these prints are disabled or not for release builds

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only for debug. For the release, the log will never output to the terminal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I tested it out also and saw no serial output.

}
BLEServiceNodePtr node = serviceHeader->next;

while (node != NULL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lot of extra (slightly confusing) code in lines 524 - 540. It took me a few reads to understand what was actually happening here. This while loop could be greatly simplified, and thus easier on the eyes.....

while (node != NULL) {
    serviceImp = node->value;
    end_handle = serviceImp->endHandle();
    if (handle >= start_handle && handle <= end_handle)
    {
        return serviceImp;
    }
    node = node->next;
}

return NULL;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like use break instead of return. Because we may extend the code in the feature, we don't need add the code in the loop if we use the break. Just add the code at the end of the function. But if you persist in your style, I can update the code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it's OK. I understand your explanation, just looking for the reasoning :)

BLECharacteristicImp* chrcCurImp = NULL;
BLECharacteristicNodePtr node = chrcHeader->next;

//pr_debug(LOG_MODULE_BLE, "%s-%d: node-%p",__FUNCTION__, __LINE__, node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented pr_debug? I forgot what our policy is on this. Personally I'd take it out.

if (NULL == _cur_discover_chrc)
{
bool result = chrcCurImp->discoverAttributes(&bledevice);
pr_debug(LOG_MODULE_BLE, "%s-%d",__FUNCTION__, __LINE__);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr_debug? should this line be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted.

}
// Record the current discovering service
_cur_discover_chrc = chrcCurImp;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use return here instead of break. The intention is clearer, and it is easier to follow the loop logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before.

{
_reading = true;
}
pr_debug(LOG_MODULE_BLE, "%s-%d", __FUNCTION__, __LINE__);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe all these calls to pr_debug will incur some serial I/O. If this is the case, please remove them..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we disable the debug, the serial I/O will not be called.

}
else if (_cur_discover_chrc == chrcCurImp)
}
else if (_cur_discover_chrc == chrcCurImp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like perhaps just else would be sufficient here. @sgbihu could you confirm/deny please?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not correct. The else-if is necessary, because the code need find the previous characteristic, and find next one by previous characteristic. So this is try to reset it to NULL.

@russmcinnis
Copy link
Contributor

Tested this with and without pull request 451. I used these in the led peripheral. I was able to prove it breaks without PR 451 and passes with PR 451. Also ran the system tests and this holds up.

// create service
BLEService ledService("18c2444459e3648f5e7dc215879b0000");

// create switch characteristic
BLECharCharacteristic switchCharacteristic("19b10001e8f2537e4f6cd104768a1214", BLERead | BLEWrite);

…it 384

Root cause:
  - Nordic stack does not return long UUID for Characteristic
    discovery.  It is expecting Characteristic UUID is a
    subset of the Service UUID (eg. a sequential increament of
    the Service UUID).
  - In order for the Central mode (to behave like Apple) to
    discover long Characteristic UUID, the process is now done
    in two steps (similar to the Service discovery).  First,
    initiate a read of the Characteristic and then discover the
    long UUID upon successful read.

Code Mods:

1. BLECallbacks.cpp:
   - Added a call back to handle the read Characteristic
     completion event.
2. BLECallbacks.h:
   - Prototyping.
3. BLEProfileManager.cpp:
   - Added getServiceBySubHandle() to enable the call back to
     locate the Service of a discovered Characteristic.
4. BLEProfileManager.h:
   - Prototyping.
5. BLEServiceImp.cpp:
   - This is where the two steps Characteristic discovery is
     implemented.  At discoverAttributes(), reading of
     Characteristic is first initiated.  When the stack
     completes the operation, extract the UUID thereafter.
   - To support this two steps process, additional functions,
     discoverNextCharacteristic and readCharacteristic, are
     added.
6. BLEServiceImp.h:
   - Prototyping.

    - Change the discover process.
    - Add read operation after discover returned invalid UUID.
@SidLeung
Copy link
Contributor Author

SidLeung commented Mar 1, 2017

Code review approach, system testing passed, proceed with merging to main trunk.

@yashaswini-hanji , please merge this PR and close out the Jira ticket.

@SidLeung SidLeung assigned yashaswini-hanji and unassigned SidLeung Mar 1, 2017
@ndgbuilder ndgbuilder merged commit d818a3a into arduino:master Mar 1, 2017
@yashaswini-hanji
Copy link
Contributor

PR merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants