payload: {"action":"opened","number":1890,"pull_request":{"url":"https://api.github.com/repos/particle-iot/device-os/pulls/1890","id":309798217,"node_id":"MDExOlB1bGxSZXF1ZXN0MzA5Nzk4MjE3","html_url":"https://github.com/particle-iot/device-os/pull/1890","diff_url":"https://github.com/particle-iot/device-os/pull/1890.diff","patch_url":"https://github.com/particle-iot/device-os/pull/1890.patch","issue_url":"https://api.github.com/repos/particle-iot/device-os/issues/1890","number":1890,"state":"open","locked":false,"title":"BLE: introduces BLE.begin() and BLE.end() wiring APIs.","user":{"login":"XuGuohui","id":8130559,"node_id":"MDQ6VXNlcjgxMzA1NTk=","avatar_url":"https://avatars0.githubusercontent.com/u/8130559?v=4","gravatar_id":"","url":"https://api.github.com/users/XuGuohui","html_url":"https://github.com/XuGuohui","followers_url":"https://api.github.com/users/XuGuohui/followers","following_url":"https://api.github.com/users/XuGuohui/following{/other_user}","gists_url":"https://api.github.com/users/XuGuohui/gists{/gist_id}","starred_url":"https://api.github.com/users/XuGuohui/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/XuGuohui/subscriptions","organizations_url":"https://api.github.com/users/XuGuohui/orgs","repos_url":"https://api.github.com/users/XuGuohui/repos","events_url":"https://api.github.com/users/XuGuohui/events{/privacy}","received_events_url":"https://api.github.com/users/XuGuohui/received_events","type":"User","site_admin":false},"body":"### Problem\r\n\r\nIn Device OS 1.3.1-rc.1 and below, to terminate all the BLE activities initiated by user application, we can call `BLE.off()` to just shut off the BLE radio. While this API will also prevent the mobile setup from going further when device is in the Listening mode, since BLE will stop advertising and Peripheral connection is dropped if connected when that API is called.\r\n\r\n### Solution\r\n\r\nBy introducing the `BLE.end()` API, it makes sure that only the BLE activities initiated by user application is terminated, leaving the mobile setup works as expected.\r\n\r\n### Examples App\r\n\r\n1. BLE scanner\r\n```c\r\n#include \"Particle.h\"\r\n\r\nSYSTEM_MODE(MANUAL);\r\n\r\nSerial1LogHandler log(115200, LOG_LEVEL_ALL);\r\n\r\nvoid bleOnScanResultCallback(const BleScanResult* result, void* context) {\r\n    LOG(TRACE, \"---------- END ----------\");\r\n    BLE.end()\r\n}\r\n\r\nvoid setup() {\r\n}\r\n\r\nvoid loop() {\r\n    BLE.scan(bleOnScanResultCallback, nullptr);\r\n    delay(3000);\r\n}\r\n```\r\n2. BLE Peripheral\r\n```c\r\n#include \"Particle.h\"\r\n\r\nSYSTEM_MODE(MANUAL);\r\nSYSTEM_THREAD(ENABLED);\r\n\r\nSerial1LogHandler log(115200, LOG_LEVEL_ALL);\r\n\r\nconst char* serviceUuid = \"6E400001-B5A3-F393-E0A9-E50E24DCCA9E\";\r\n\r\nvoid setup() {\r\n    BleAdvertisingData data;\r\n    data.appendServiceUUID(serviceUuid);\r\n    BLE.advertise(&data);\r\n}\r\n\r\nvoid loop() {\r\n    delay(20000);\r\n    LOG(TRACE, \"---------- END ----------\");\r\n    BLE.end()\r\n}\r\n```\r\n3. BLE Central\r\n```c\r\n#include \"Particle.h\"\r\n\r\nSYSTEM_MODE(MANUAL);\r\nSYSTEM_THREAD(ENABLED);\r\n\r\nSerial1LogHandler log(115200, LOG_LEVEL_ALL);\r\n\r\n#define SCAN_RESULT_COUNT       20\r\n\r\nBleScanResult results[SCAN_RESULT_COUNT];\r\n\r\nBlePeerDevice peer;\r\n\r\nvoid setup() {\r\n}\r\n\r\nvoid loop() {\r\n    if (peer.connected()) {\r\n        delay(10000);\r\n        LOG(TRACE, \"---------- END ----------\");\r\n        BLE.end()\r\n    }\r\n    else {\r\n        delay(3000);\r\n        size_t count = BLE.scan(results, SCAN_RESULT_COUNT);\r\n        if (count > 0) {\r\n            for (uint8_t i = 0; i < count; i++) {\r\n                BleUuid foundServiceUUID;\r\n                size_t svcCount = results[i].advertisingData.serviceUUID(&foundServiceUUID, 1);\r\n                if (svcCount > 0 && foundServiceUUID == \"6E400001-B5A3-F393-E0A9-E50E24DCCA9E\") {\r\n                    peer = BLE.connect(results[i].address);\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n### Steps to Test\r\n\r\n1. Build and flash the 1st application, see if BLE stops scanning on device scanned.\r\n2. Build and flash the 2nd application:\r\n    - See if BLE stops advertising after 20 seconds.\r\n    - On device started, make it enter the Listening mode, see if BLE is still advertising after 20 seconds.\r\n    - On device started, make it enter the Listening mode and connect to the device using a mobile App, see if BLE connection is retained after 20 seconds.\r\n3. Build and flash the 3rd application (need another device that is running the 1st application but without the `BLE.end()` is called), see if BLE connection is dropped after device being connected for 10 seconds.\r\n\r\n### References\r\n\r\nKnown issue: https://github.com/particle-iot/device-os/pull/1847","created_at":"2019-08-22T06:20:58Z","updated_at":"2019-08-22T06:20:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"assignees":[],"requested_reviewers":[{"login":"avtolstoy","id":388478,"node_id":"MDQ6VXNlcjM4ODQ3OA==","avatar_url":"https://avatars3.githubusercontent.com/u/388478?v=4","gravatar_id":"","url":"https://api.github.com/users/avtolstoy","html_url":"https://github.com/avtolstoy","followers_url":"https://api.github.com/users/avtolstoy/followers","following_url":"https://api.github.com/users/avtolstoy/following{/other_user}","gists_url":"https://api.github.com/users/avtolstoy/gists{/gist_id}","starred_url":"https://api.github.com/users/avtolstoy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/avtolstoy/subscriptions","organizations_url":"https://api.github.com/users/avtolstoy/orgs","repos_url":"https://api.github.com/users/avtolstoy/repos","events_url":"https://api.github.com/users/avtolstoy/events{/privacy}","received_events_url":"https://api.github.com/users/avtolstoy/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":1128130541,"node_id":"MDU6TGFiZWwxMTI4MTMwNTQx","url":"https://api.github.com/repos/particle-iot/device-os/labels/ble","name":"ble","color":"0052cc","default":false},{"id":511104719,"node_id":"MDU6TGFiZWw1MTExMDQ3MTk=","url":"https://api.github.com/repos/particle-iot/device-os/labels/feature","name":"feature","color":"5319e7","default":false},{"id":279587526,"node_id":"MDU6TGFiZWwyNzk1ODc1MjY=","url":"https://api.github.com/repos/particle-iot/device-os/labels/needs%20review","name":"needs review","color":"fbca04","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/particle-iot/device-os/pulls/1890/commits","review_comments_url":"https://api.github.com/repos/particle-iot/device-os/pulls/1890/comments","review_comment_url":"https://api.github.com/repos/particle-iot/device-os/pulls/comments{/number}","comments_url":"https://api.github.com/repos/particle-iot/device-os/issues/1890/comments","statuses_url":"https://api.github.com/repos/particle-iot/device-os/statuses/40433167a0a8587d13053021e585bd3d6fd32fe0","head":{"label":"particle-iot:feature/ble_end_api","ref":"feature/ble_end_api","sha":"40433167a0a8587d13053021e585bd3d6fd32fe0","user":{"login":"particle-iot","id":2348966,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNDg5NjY=","avatar_url":"https://avatars2.githubusercontent.com/u/2348966?v=4","gravatar_id":"","url":"https://api.github.com/users/particle-iot","html_url":"https://github.com/particle-iot","followers_url":"https://api.github.com/users/particle-iot/followers","following_url":"https://api.github.com/users/particle-iot/following{/other_user}","gists_url":"https://api.github.com/users/particle-iot/gists{/gist_id}","starred_url":"https://api.github.com/users/particle-iot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/particle-iot/subscriptions","organizations_url":"https://api.github.com/users/particle-iot/orgs","repos_url":"https://api.github.com/users/particle-iot/repos","events_url":"https://api.github.com/users/particle-iot/events{/privacy}","received_events_url":"https://api.github.com/users/particle-iot/received_events","type":"Organization","site_admin":false},"repo":{"id":8720130,"node_id":"MDEwOlJlcG9zaXRvcnk4NzIwMTMw","name":"device-os","full_name":"particle-iot/device-os","private":false,"owner":{"login":"particle-iot","id":2348966,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNDg5NjY=","avatar_url":"https://avatars2.githubusercontent.com/u/2348966?v=4","gravatar_id":"","url":"https://api.github.com/users/particle-iot","html_url":"https://github.com/particle-iot","followers_url":"https://api.github.com/users/particle-iot/followers","following_url":"https://api.github.com/users/particle-iot/following{/other_user}","gists_url":"https://api.github.com/users/particle-iot/gists{/gist_id}","starred_url":"https://api.github.com/users/particle-iot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/particle-iot/subscriptions","organizations_url":"https://api.github.com/users/particle-iot/orgs","repos_url":"https://api.github.com/users/particle-iot/repos","events_url":"https://api.github.com/users/particle-iot/events{/privacy}","received_events_url":"https://api.github.com/users/particle-iot/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/particle-iot/device-os","description":"Device OS (Firmware) for Particle Devices","fork":false,"url":"https://api.github.com/repos/particle-iot/device-os","forks_url":"https://api.github.com/repos/particle-iot/device-os/forks","keys_url":"https://api.github.com/repos/particle-iot/device-os/keys{/key_id}","collaborators_url":"https://api.github.com/repos/particle-iot/device-os/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/particle-iot/device-os/teams","hooks_url":"https://api.github.com/repos/particle-iot/device-os/hooks","issue_events_url":"https://api.github.com/repos/particle-iot/device-os/issues/events{/number}","events_url":"https://api.github.com/repos/particle-iot/device-os/events","assignees_url":"https://api.github.com/repos/particle-iot/device-os/assignees{/user}","branches_url":"https://api.github.com/repos/particle-iot/device-os/branches{/branch}","tags_url":"https://api.github.com/repos/particle-iot/device-os/tags","blobs_url":"https://api.github.com/repos/particle-iot/device-os/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/particle-iot/device-os/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/particle-iot/device-os/git/refs{/sha}","trees_url":"https://api.github.com/repos/particle-iot/device-os/git/trees{/sha}","statuses_url":"https://api.github.com/repos/particle-iot/device-os/statuses/{sha}","languages_url":"https://api.github.com/repos/particle-iot/device-os/languages","stargazers_url":"https://api.github.com/repos/particle-iot/device-os/stargazers","contributors_url":"https://api.github.com/repos/particle-iot/device-os/contributors","subscribers_url":"https://api.github.com/repos/particle-iot/device-os/subscribers","subscription_url":"https://api.github.com/repos/particle-iot/device-os/subscription","commits_url":"https://api.github.com/repos/particle-iot/device-os/commits{/sha}","git_commits_url":"https://api.github.com/repos/particle-iot/device-os/git/commits{/sha}","comments_url":"https://api.github.com/repos/particle-iot/device-os/comments{/number}","issue_comment_url":"https://api.github.com/repos/particle-iot/device-os/issues/comments{/number}","contents_url":"https://api.github.com/repos/particle-iot/device-os/contents/{+path}","compare_url":"https://api.github.com/repos/particle-iot/device-os/compare/{base}...{head}","merges_url":"https://api.github.com/repos/particle-iot/device-os/merges","archive_url":"https://api.github.com/repos/particle-iot/device-os/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/particle-iot/device-os/downloads","issues_url":"https://api.github.com/repos/particle-iot/device-os/issues{/number}","pulls_url":"https://api.github.com/repos/particle-iot/device-os/pulls{/number}","milestones_url":"https://api.github.com/repos/particle-iot/device-os/milestones{/number}","notifications_url":"https://api.github.com/repos/particle-iot/device-os/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/particle-iot/device-os/labels{/name}","releases_url":"https://api.github.com/repos/particle-iot/device-os/releases{/id}","deployments_url":"https://api.github.com/repos/particle-iot/device-os/deployments","created_at":"2013-03-12T04:42:33Z","updated_at":"2019-08-21T15:37:20Z","pushed_at":"2019-08-22T03:39:17Z","git_url":"git://github.com/particle-iot/device-os.git","ssh_url":"git@github.com:particle-iot/device-os.git","clone_url":"https://github.com/particle-iot/device-os.git","svn_url":"https://github.com/particle-iot/device-os","homepage":"https://www.particle.io/","size":134437,"stargazers_count":889,"watchers_count":889,"language":"C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":472,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":248,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":472,"open_issues":248,"watchers":889,"default_branch":"develop"}},"base":{"label":"particle-iot:refactor/ble_listening_mode","ref":"refactor/ble_listening_mode","sha":"2dabf4194b0baace112a4563a03e1a640d78b173","user":{"login":"particle-iot","id":2348966,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNDg5NjY=","avatar_url":"https://avatars2.githubusercontent.com/u/2348966?v=4","gravatar_id":"","url":"https://api.github.com/users/particle-iot","html_url":"https://github.com/particle-iot","followers_url":"https://api.github.com/users/particle-iot/followers","following_url":"https://api.github.com/users/particle-iot/following{/other_user}","gists_url":"https://api.github.com/users/particle-iot/gists{/gist_id}","starred_url":"https://api.github.com/users/particle-iot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/particle-iot/subscriptions","organizations_url":"https://api.github.com/users/particle-iot/orgs","repos_url":"https://api.github.com/users/particle-iot/repos","events_url":"https://api.github.com/users/particle-iot/events{/privacy}","received_events_url":"https://api.github.com/users/particle-iot/received_events","type":"Organization","site_admin":false},"repo":{"id":8720130,"node_id":"MDEwOlJlcG9zaXRvcnk4NzIwMTMw","name":"device-os","full_name":"particle-iot/device-os","private":false,"owner":{"login":"particle-iot","id":2348966,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNDg5NjY=","avatar_url":"https://avatars2.githubusercontent.com/u/2348966?v=4","gravatar_id":"","url":"https://api.github.com/users/particle-iot","html_url":"https://github.com/particle-iot","followers_url":"https://api.github.com/users/particle-iot/followers","following_url":"https://api.github.com/users/particle-iot/following{/other_user}","gists_url":"https://api.github.com/users/particle-iot/gists{/gist_id}","starred_url":"https://api.github.com/users/particle-iot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/particle-iot/subscriptions","organizations_url":"https://api.github.com/users/particle-iot/orgs","repos_url":"https://api.github.com/users/particle-iot/repos","events_url":"https://api.github.com/users/particle-iot/events{/privacy}","received_events_url":"https://api.github.com/users/particle-iot/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/particle-iot/device-os","description":"Device OS (Firmware) for Particle Devices","fork":false,"url":"https://api.github.com/repos/particle-iot/device-os","forks_url":"https://api.github.com/repos/particle-iot/device-os/forks","keys_url":"https://api.github.com/repos/particle-iot/device-os/keys{/key_id}","collaborators_url":"https://api.github.com/repos/particle-iot/device-os/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/particle-iot/device-os/teams","hooks_url":"https://api.github.com/repos/particle-iot/device-os/hooks","issue_events_url":"https://api.github.com/repos/particle-iot/device-os/issues/events{/number}","events_url":"https://api.github.com/repos/particle-iot/device-os/events","assignees_url":"https://api.github.com/repos/particle-iot/device-os/assignees{/user}","branches_url":"https://api.github.com/repos/particle-iot/device-os/branches{/branch}","tags_url":"https://api.github.com/repos/particle-iot/device-os/tags","blobs_url":"https://api.github.com/repos/particle-iot/device-os/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/particle-iot/device-os/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/particle-iot/device-os/git/refs{/sha}","trees_url":"https://api.github.com/repos/particle-iot/device-os/git/trees{/sha}","statuses_url":"https://api.github.com/repos/particle-iot/device-os/statuses/{sha}","languages_url":"https://api.github.com/repos/particle-iot/device-os/languages","stargazers_url":"https://api.github.com/repos/particle-iot/device-os/stargazers","contributors_url":"https://api.github.com/repos/particle-iot/device-os/contributors","subscribers_url":"https://api.github.com/repos/particle-iot/device-os/subscribers","subscription_url":"https://api.github.com/repos/particle-iot/device-os/subscription","commits_url":"https://api.github.com/repos/particle-iot/device-os/commits{/sha}","git_commits_url":"https://api.github.com/repos/particle-iot/device-os/git/commits{/sha}","comments_url":"https://api.github.com/repos/particle-iot/device-os/comments{/number}","issue_comment_url":"https://api.github.com/repos/particle-iot/device-os/issues/comments{/number}","contents_url":"https://api.github.com/repos/particle-iot/device-os/contents/{+path}","compare_url":"https://api.github.com/repos/particle-iot/device-os/compare/{base}...{head}","merges_url":"https://api.github.com/repos/particle-iot/device-os/merges","archive_url":"https://api.github.com/repos/particle-iot/device-os/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/particle-iot/device-os/downloads","issues_url":"https://api.github.com/repos/particle-iot/device-os/issues{/number}","pulls_url":"https://api.github.com/repos/particle-iot/device-os/pulls{/number}","milestones_url":"https://api.github.com/repos/particle-iot/device-os/milestones{/number}","notifications_url":"https://api.github.com/repos/particle-iot/device-os/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/particle-iot/device-os/labels{/name}","releases_url":"https://api.github.com/repos/particle-iot/device-os/releases{/id}","deployments_url":"https://api.github.com/repos/particle-iot/device-os/deployments","created_at":"2013-03-12T04:42:33Z","updated_at":"2019-08-21T15:37:20Z","pushed_at":"2019-08-22T03:39:17Z","git_url":"git://github.com/particle-iot/device-os.git","ssh_url":"git@github.com:particle-iot/device-os.git","clone_url":"https://github.com/particle-iot/device-os.git","svn_url":"https://github.com/particle-iot/device-os","homepage":"https://www.particle.io/","size":134437,"stargazers_count":889,"watchers_count":889,"language":"C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":472,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":248,"license":{"key":"lgpl-3.0","name":"GNU Lesser General Public License v3.0","spdx_id":"LGPL-3.0","url":"https://api.github.com/licenses/lgpl-3.0","node_id":"MDc6TGljZW5zZTEy"},"forks":472,"open_issues":248,"watchers":889,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/particle-iot/device-os/pulls/1890"},"html":{"href":"https://github.com/particle-iot/device-os/pull/1890"},"issue":{"href":"https://api.github.com/repos/particle-iot/device-os/issues/1890"},"comments":{"href":"https://api.github.com/repos/particle-iot/device-os/issues/1890/comments"},"review_comments":{"href":"https://api.github.com/repos/particle-iot/device-os/pulls/1890/comments"},"review_comment":{"href":"https://api.github.com/repos/particle-iot/device-os/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/particle-iot/device-os/pulls/1890/commits"},"statuses":{"href":"https://api.github.com/repos/particle-iot/device-os/statuses/40433167a0a8587d13053021e585bd3d6fd32fe0"}},"author_association":"CONTRIBUTOR","merged":false,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"maintainer_can_modify":false,"commits":1,"additions":31,"deletions":4,"changed_files":2}}
other: {"actor":{"display_login":"XuGuohui"}}