{"action":"created","comment":{"url":"https://api.github.com/repos/szeged/servo/pulls/comments/57134687","id":57134687,"diff_hunk":"@@ -0,0 +1,371 @@\n+/* This Source Code Form is subject to the terms of the Mozilla Public\n+ * License, v. 2.0. If a copy of the MPL was not distributed with this\n+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n+\n+use device::bluetooth::BluetoothAdapter;\n+use device::bluetooth::BluetoothDevice;\n+use device::bluetooth::BluetoothGATTCharacteristic;\n+use device::bluetooth::BluetoothGATTDescriptor;\n+use device::bluetooth::BluetoothGATTService;\n+use ipc_channel::ipc::{self, IpcReceiver, IpcSender};\n+use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};\n+use std::borrow::ToOwned;\n+use std::collections::HashMap;\n+use std::string::String;\n+use util::thread::spawn_named;\n+\n+pub trait BluetoothThreadFactory {\n+    fn new() -> Self;\n+}\n+\n+impl BluetoothThreadFactory for IpcSender<BluetoothMethodMsg> {\n+    fn new() -> IpcSender<BluetoothMethodMsg> {\n+        let (sender, receiver) = ipc::channel().unwrap();\n+        let adapter = BluetoothAdapter::init();\n+        spawn_named(\"BluetoothThread\".to_owned(), move || {\n+            BluetoothManager::new(receiver, adapter).start();\n+        });\n+        sender\n+    }\n+}\n+\n+pub struct BluetoothManager {\n+    receiver: IpcReceiver<BluetoothMethodMsg>,\n+    adapter: BluetoothAdapter,\n+    service_to_device: HashMap<String, String>,\n+    characteristic_to_service: HashMap<String, String>,\n+    descriptor_to_characteristic: HashMap<String, String>,\n+    cached_devices: HashMap<String, BluetoothDevice>,\n+    cached_services: HashMap<String, BluetoothGATTService>,\n+    cached_characteristic: HashMap<String, BluetoothGATTCharacteristic>,\n+    cached_descriptors: HashMap<String, BluetoothGATTDescriptor>,\n+}\n+\n+impl BluetoothManager {\n+    pub fn new (receiver: IpcReceiver<BluetoothMethodMsg>, adapter: BluetoothAdapter) -> BluetoothManager {\n+        BluetoothManager {\n+            receiver: receiver,\n+            adapter: adapter,\n+            service_to_device: HashMap::new(),\n+            characteristic_to_service: HashMap::new(),\n+            descriptor_to_characteristic: HashMap::new(),\n+            cached_devices: HashMap::new(),\n+            cached_services: HashMap::new(),\n+            cached_characteristic: HashMap::new(),\n+            cached_descriptors: HashMap::new(),\n+        }\n+    }\n+\n+    fn start(&mut self) {\n+        loop {\n+            match self.receiver.recv().unwrap() {\n+                BluetoothMethodMsg::RequestDevice(sender) => {\n+                    self.request_device(sender)\n+                }\n+                BluetoothMethodMsg::GATTServerConnect(device_id, sender) => {\n+                    self.gatt_server_connect(device_id, sender)\n+                }\n+                BluetoothMethodMsg::GATTServerDisconnect(device_id, sender) => {\n+                    self.gatt_server_disconnect(device_id, sender)\n+                }\n+                BluetoothMethodMsg::GetPrimaryService(device_id, sender) => {\n+                    self.get_primary_service(device_id, sender)\n+                }\n+                BluetoothMethodMsg::GetCharacteristic(service_id, sender) => {\n+                    self.get_characteristic(service_id, sender)\n+                }\n+                BluetoothMethodMsg::GetDescriptor(characteristic_id, sender) => {\n+                    self.get_descriptor(characteristic_id, sender)\n+                }\n+                BluetoothMethodMsg::ReadValue(id, sender) => {\n+                    self.read_value(id, sender)\n+                }\n+                BluetoothMethodMsg::WriteValue(id, value, sender) => {\n+                    self.write_value(id, value, sender)\n+                }\n+                BluetoothMethodMsg::Exit => {\n+                    break\n+                }\n+            }\n+        }\n+    }\n+\n+    fn request_device(&mut self, sender: IpcSender<BluetoothObjectMsg>) {\n+        if !self.adapter.is_initialized() {\n+            sender.send(BluetoothObjectMsg::Error { error: String::from(\"No adapter found\") }).unwrap();","path":"components/net/bluetooth_thread.rs","position":95,"original_position":95,"commit_id":"231e0e16db15fecfde9be11f173dc3e5e6b02510","original_commit_id":"e9408210b732ab73ad68a52be9b1cc759e63c0c8","user":{"login":"mmatyas","id":4354863,"avatar_url":"https://avatars.githubusercontent.com/u/4354863?v=3","gravatar_id":"","url":"https://api.github.com/users/mmatyas","html_url":"https://github.com/mmatyas","followers_url":"https://api.github.com/users/mmatyas/followers","following_url":"https://api.github.com/users/mmatyas/following{/other_user}","gists_url":"https://api.github.com/users/mmatyas/gists{/gist_id}","starred_url":"https://api.github.com/users/mmatyas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mmatyas/subscriptions","organizations_url":"https://api.github.com/users/mmatyas/orgs","repos_url":"https://api.github.com/users/mmatyas/repos","events_url":"https://api.github.com/users/mmatyas/events{/privacy}","received_events_url":"https://api.github.com/users/mmatyas/received_events","type":"User","site_admin":false},"body":"Hm.","created_at":"2016-03-23T10:09:53Z","updated_at":"2016-03-23T10:09:53Z","html_url":"https://github.com/szeged/servo/pull/9#discussion_r57134687","pull_request_url":"https://api.github.com/repos/szeged/servo/pulls/9","_links":{"self":{"href":"https://api.github.com/repos/szeged/servo/pulls/comments/57134687"},"html":{"href":"https://github.com/szeged/servo/pull/9#discussion_r57134687"},"pull_request":{"href":"https://api.github.com/repos/szeged/servo/pulls/9"}}},"pull_request":{"url":"https://api.github.com/repos/szeged/servo/pulls/9","id":63846264,"html_url":"https://github.com/szeged/servo/pull/9","diff_url":"https://github.com/szeged/servo/pull/9.diff","patch_url":"https://github.com/szeged/servo/pull/9.patch","issue_url":"https://api.github.com/repos/szeged/servo/issues/9","number":9,"state":"open","locked":false,"title":"Bluetooth ipc","user":{"login":"dati91","id":2149430,"avatar_url":"https://avatars.githubusercontent.com/u/2149430?v=3","gravatar_id":"","url":"https://api.github.com/users/dati91","html_url":"https://github.com/dati91","followers_url":"https://api.github.com/users/dati91/followers","following_url":"https://api.github.com/users/dati91/following{/other_user}","gists_url":"https://api.github.com/users/dati91/gists{/gist_id}","starred_url":"https://api.github.com/users/dati91/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dati91/subscriptions","organizations_url":"https://api.github.com/users/dati91/orgs","repos_url":"https://api.github.com/users/dati91/repos","events_url":"https://api.github.com/users/dati91/events{/privacy}","received_events_url":"https://api.github.com/users/dati91/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-03-23T08:27:37Z","updated_at":"2016-03-23T10:09:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4ae83da19ec1586450debc8eae248aaaccb414c6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/szeged/servo/pulls/9/commits","review_comments_url":"https://api.github.com/repos/szeged/servo/pulls/9/comments","review_comment_url":"https://api.github.com/repos/szeged/servo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/szeged/servo/issues/9/comments","statuses_url":"https://api.github.com/repos/szeged/servo/statuses/231e0e16db15fecfde9be11f173dc3e5e6b02510","head":{"label":"dati91:bluetooth-ipc","ref":"bluetooth-ipc","sha":"231e0e16db15fecfde9be11f173dc3e5e6b02510","user":{"login":"dati91","id":2149430,"avatar_url":"https://avatars.githubusercontent.com/u/2149430?v=3","gravatar_id":"","url":"https://api.github.com/users/dati91","html_url":"https://github.com/dati91","followers_url":"https://api.github.com/users/dati91/followers","following_url":"https://api.github.com/users/dati91/following{/other_user}","gists_url":"https://api.github.com/users/dati91/gists{/gist_id}","starred_url":"https://api.github.com/users/dati91/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dati91/subscriptions","organizations_url":"https://api.github.com/users/dati91/orgs","repos_url":"https://api.github.com/users/dati91/repos","events_url":"https://api.github.com/users/dati91/events{/privacy}","received_events_url":"https://api.github.com/users/dati91/received_events","type":"User","site_admin":false},"repo":{"id":54104273,"name":"servo","full_name":"dati91/servo","owner":{"login":"dati91","id":2149430,"avatar_url":"https://avatars.githubusercontent.com/u/2149430?v=3","gravatar_id":"","url":"https://api.github.com/users/dati91","html_url":"https://github.com/dati91","followers_url":"https://api.github.com/users/dati91/followers","following_url":"https://api.github.com/users/dati91/following{/other_user}","gists_url":"https://api.github.com/users/dati91/gists{/gist_id}","starred_url":"https://api.github.com/users/dati91/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dati91/subscriptions","organizations_url":"https://api.github.com/users/dati91/orgs","repos_url":"https://api.github.com/users/dati91/repos","events_url":"https://api.github.com/users/dati91/events{/privacy}","received_events_url":"https://api.github.com/users/dati91/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dati91/servo","description":"The Servo Browser Engine","fork":true,"url":"https://api.github.com/repos/dati91/servo","forks_url":"https://api.github.com/repos/dati91/servo/forks","keys_url":"https://api.github.com/repos/dati91/servo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dati91/servo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dati91/servo/teams","hooks_url":"https://api.github.com/repos/dati91/servo/hooks","issue_events_url":"https://api.github.com/repos/dati91/servo/issues/events{/number}","events_url":"https://api.github.com/repos/dati91/servo/events","assignees_url":"https://api.github.com/repos/dati91/servo/assignees{/user}","branches_url":"https://api.github.com/repos/dati91/servo/branches{/branch}","tags_url":"https://api.github.com/repos/dati91/servo/tags","blobs_url":"https://api.github.com/repos/dati91/servo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dati91/servo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dati91/servo/git/refs{/sha}","trees_url":"https://api.github.com/repos/dati91/servo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dati91/servo/statuses/{sha}","languages_url":"https://api.github.com/repos/dati91/servo/languages","stargazers_url":"https://api.github.com/repos/dati91/servo/stargazers","contributors_url":"https://api.github.com/repos/dati91/servo/contributors","subscribers_url":"https://api.github.com/repos/dati91/servo/subscribers","subscription_url":"https://api.github.com/repos/dati91/servo/subscription","commits_url":"https://api.github.com/repos/dati91/servo/commits{/sha}","git_commits_url":"https://api.github.com/repos/dati91/servo/git/commits{/sha}","comments_url":"https://api.github.com/repos/dati91/servo/comments{/number}","issue_comment_url":"https://api.github.com/repos/dati91/servo/issues/comments{/number}","contents_url":"https://api.github.com/repos/dati91/servo/contents/{+path}","compare_url":"https://api.github.com/repos/dati91/servo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dati91/servo/merges","archive_url":"https://api.github.com/repos/dati91/servo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dati91/servo/downloads","issues_url":"https://api.github.com/repos/dati91/servo/issues{/number}","pulls_url":"https://api.github.com/repos/dati91/servo/pulls{/number}","milestones_url":"https://api.github.com/repos/dati91/servo/milestones{/number}","notifications_url":"https://api.github.com/repos/dati91/servo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dati91/servo/labels{/name}","releases_url":"https://api.github.com/repos/dati91/servo/releases{/id}","deployments_url":"https://api.github.com/repos/dati91/servo/deployments","created_at":"2016-03-17T09:13:33Z","updated_at":"2016-01-25T13:06:41Z","pushed_at":"2016-03-23T09:48:01Z","git_url":"git://github.com/dati91/servo.git","ssh_url":"git@github.com:dati91/servo.git","clone_url":"https://github.com/dati91/servo.git","svn_url":"https://github.com/dati91/servo","homepage":"https://servo.org/","size":179134,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"szeged:bluetooth-ipc","ref":"bluetooth-ipc","sha":"3a6c88792ddc3336d9bba57ac1d7a5367c1c1c3a","user":{"login":"szeged","id":1826696,"avatar_url":"https://avatars.githubusercontent.com/u/1826696?v=3","gravatar_id":"","url":"https://api.github.com/users/szeged","html_url":"https://github.com/szeged","followers_url":"https://api.github.com/users/szeged/followers","following_url":"https://api.github.com/users/szeged/following{/other_user}","gists_url":"https://api.github.com/users/szeged/gists{/gist_id}","starred_url":"https://api.github.com/users/szeged/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/szeged/subscriptions","organizations_url":"https://api.github.com/users/szeged/orgs","repos_url":"https://api.github.com/users/szeged/repos","events_url":"https://api.github.com/users/szeged/events{/privacy}","received_events_url":"https://api.github.com/users/szeged/received_events","type":"Organization","site_admin":false},"repo":{"id":50353354,"name":"servo","full_name":"szeged/servo","owner":{"login":"szeged","id":1826696,"avatar_url":"https://avatars.githubusercontent.com/u/1826696?v=3","gravatar_id":"","url":"https://api.github.com/users/szeged","html_url":"https://github.com/szeged","followers_url":"https://api.github.com/users/szeged/followers","following_url":"https://api.github.com/users/szeged/following{/other_user}","gists_url":"https://api.github.com/users/szeged/gists{/gist_id}","starred_url":"https://api.github.com/users/szeged/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/szeged/subscriptions","organizations_url":"https://api.github.com/users/szeged/orgs","repos_url":"https://api.github.com/users/szeged/repos","events_url":"https://api.github.com/users/szeged/events{/privacy}","received_events_url":"https://api.github.com/users/szeged/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/szeged/servo","description":"The Servo Browser Engine","fork":true,"url":"https://api.github.com/repos/szeged/servo","forks_url":"https://api.github.com/repos/szeged/servo/forks","keys_url":"https://api.github.com/repos/szeged/servo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/szeged/servo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/szeged/servo/teams","hooks_url":"https://api.github.com/repos/szeged/servo/hooks","issue_events_url":"https://api.github.com/repos/szeged/servo/issues/events{/number}","events_url":"https://api.github.com/repos/szeged/servo/events","assignees_url":"https://api.github.com/repos/szeged/servo/assignees{/user}","branches_url":"https://api.github.com/repos/szeged/servo/branches{/branch}","tags_url":"https://api.github.com/repos/szeged/servo/tags","blobs_url":"https://api.github.com/repos/szeged/servo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/szeged/servo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/szeged/servo/git/refs{/sha}","trees_url":"https://api.github.com/repos/szeged/servo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/szeged/servo/statuses/{sha}","languages_url":"https://api.github.com/repos/szeged/servo/languages","stargazers_url":"https://api.github.com/repos/szeged/servo/stargazers","contributors_url":"https://api.github.com/repos/szeged/servo/contributors","subscribers_url":"https://api.github.com/repos/szeged/servo/subscribers","subscription_url":"https://api.github.com/repos/szeged/servo/subscription","commits_url":"https://api.github.com/repos/szeged/servo/commits{/sha}","git_commits_url":"https://api.github.com/repos/szeged/servo/git/commits{/sha}","comments_url":"https://api.github.com/repos/szeged/servo/comments{/number}","issue_comment_url":"https://api.github.com/repos/szeged/servo/issues/comments{/number}","contents_url":"https://api.github.com/repos/szeged/servo/contents/{+path}","compare_url":"https://api.github.com/repos/szeged/servo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/szeged/servo/merges","archive_url":"https://api.github.com/repos/szeged/servo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/szeged/servo/downloads","issues_url":"https://api.github.com/repos/szeged/servo/issues{/number}","pulls_url":"https://api.github.com/repos/szeged/servo/pulls{/number}","milestones_url":"https://api.github.com/repos/szeged/servo/milestones{/number}","notifications_url":"https://api.github.com/repos/szeged/servo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/szeged/servo/labels{/name}","releases_url":"https://api.github.com/repos/szeged/servo/releases{/id}","deployments_url":"https://api.github.com/repos/szeged/servo/deployments","created_at":"2016-01-25T13:48:48Z","updated_at":"2016-01-25T13:06:41Z","pushed_at":"2016-03-23T09:48:02Z","git_url":"git://github.com/szeged/servo.git","ssh_url":"git@github.com:szeged/servo.git","clone_url":"https://github.com/szeged/servo.git","svn_url":"https://github.com/szeged/servo","homepage":"https://servo.org/","size":178906,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":1,"forks":3,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/szeged/servo/pulls/9"},"html":{"href":"https://github.com/szeged/servo/pull/9"},"issue":{"href":"https://api.github.com/repos/szeged/servo/issues/9"},"comments":{"href":"https://api.github.com/repos/szeged/servo/issues/9/comments"},"review_comments":{"href":"https://api.github.com/repos/szeged/servo/pulls/9/comments"},"review_comment":{"href":"https://api.github.com/repos/szeged/servo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/szeged/servo/pulls/9/commits"},"statuses":{"href":"https://api.github.com/repos/szeged/servo/statuses/231e0e16db15fecfde9be11f173dc3e5e6b02510"}}}}