{"action":"created","comment":{"url":"https://api.github.com/repos/OpenLightingProject/ola/pulls/comments/22439324","id":22439324,"diff_hunk":"@@ -47,36 +54,169 @@ using std::vector;\n \n FtdiWidget::FtdiWidget(const string& serial,\n                        const string& name,\n-                       uint32_t id)\n+                       uint32_t id,\n+                       const int vid,\n+                       const int pid\n+                      )\n     : m_serial(serial),\n       m_name(name),\n-      m_id(id) {\n-  bzero(&m_handle, sizeof(struct ftdi_context));\n+      m_id(id),\n+      m_vid(vid),\n+      m_pid(pid) {}\n+\n+FtdiWidget::~FtdiWidget() {\n+}\n+\n+/**\n+ * Get the number of physical interfaces our widgit has to offer.\n+ *\n+ * This does not deal with product names being named in a different way.\n+ *\n+ * Originally I had hoped to use ftdi_context::type however, it only gets set\n+ * properly after the device has been opened.\n+ */\n+int FtdiWidget::GetInterfaceCount() {\n+  std::string tmp = m_name;\n+  ToLower(&tmp);\n+  if (std::string::npos != tmp.find(\"plus4\")) {\n+    return 4;\n+  } else  if (std::string::npos != tmp.find(\"plus2\")) {\n+    return 2;\n+  } else {\n+    return 1;\n+  }\n+}\n+\n+/**\n+ * Build a list of all attached ftdi devices\n+ */\n+void FtdiWidget::Widgets(vector<FtdiWidgetInfo> *widgets) {\n+  int i = -1;\n+  widgets->clear();\n+  struct ftdi_context *ftdi = ftdi_new();\n+  if (!ftdi) {\n+    OLA_WARN << \"Failed to allocate FTDI context\";\n+    return;\n+  }\n+\n+  const int pids[2] = { 0x6001, 0x6011 };\n+  const int vid = 0x0403;\n+  const unsigned int pidCount = 2;\n+\n+  for (unsigned int cur_pid = 0; cur_pid < pidCount; cur_pid++) {\n+    struct ftdi_device_list* list = NULL;\n+\n+    int devices_found = ftdi_usb_find_all(ftdi, &list, vid, pids[cur_pid]);\n+\n+    if (devices_found < 0) {\n+      OLA_WARN << \"Failed to get FTDI devices: \"\n+               << ftdi_get_error_string(ftdi);\n+    } else {\n+      OLA_INFO << \"Found \" << devices_found << \" FTDI devices with PID: \"\n+               << pids[cur_pid] << \".\";\n+\n+      ftdi_device_list* current_device = list;\n+\n+      while (current_device != NULL) {\n+        struct usb_device *dev = current_device->dev;\n+        current_device = current_device->next;\n+        i++;\n+\n+        if (!dev) {\n+          OLA_WARN << \"Device returned from ftdi_usb_find_all was NULL\";\n+          continue;\n+        }\n+\n+        char serial[256];\n+        char name[256];\n+        char vendor[256];\n+\n+        int r = ftdi_usb_get_strings(ftdi, dev,\n+                                    vendor, sizeof(vendor),\n+                                    name, sizeof(name),\n+                                    serial, sizeof(serial));\n+\n+        // libftdi doesn't enumerate error codes,\n+        // -9 is 'get serial number failed', not ideal but workable.\n+        if (r < 0 && r != -9) {","path":"plugins/ftdidmx/FtdiWidget-libftdi.cpp","position":112,"original_position":112,"commit_id":"130c4fa04e8f7483de98b321db0cb5b15a543250","original_commit_id":"130c4fa04e8f7483de98b321db0cb5b15a543250","user":{"login":"peternewman","id":6216436,"avatar_url":"https://avatars.githubusercontent.com/u/6216436?v=3","gravatar_id":"","url":"https://api.github.com/users/peternewman","html_url":"https://github.com/peternewman","followers_url":"https://api.github.com/users/peternewman/followers","following_url":"https://api.github.com/users/peternewman/following{/other_user}","gists_url":"https://api.github.com/users/peternewman/gists{/gist_id}","starred_url":"https://api.github.com/users/peternewman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peternewman/subscriptions","organizations_url":"https://api.github.com/users/peternewman/orgs","repos_url":"https://api.github.com/users/peternewman/repos","events_url":"https://api.github.com/users/peternewman/events{/privacy}","received_events_url":"https://api.github.com/users/peternewman/received_events","type":"User","site_admin":false},"body":"Probably worth enumerating them internally for us then.","created_at":"2015-01-04T13:49:50Z","updated_at":"2015-01-04T13:49:50Z","html_url":"https://github.com/OpenLightingProject/ola/pull/433#discussion_r22439324","pull_request_url":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433","_links":{"self":{"href":"https://api.github.com/repos/OpenLightingProject/ola/pulls/comments/22439324"},"html":{"href":"https://github.com/OpenLightingProject/ola/pull/433#discussion_r22439324"},"pull_request":{"href":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433"}}},"pull_request":{"url":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433","id":18365752,"html_url":"https://github.com/OpenLightingProject/ola/pull/433","diff_url":"https://github.com/OpenLightingProject/ola/pull/433.diff","patch_url":"https://github.com/OpenLightingProject/ola/pull/433.patch","issue_url":"https://api.github.com/repos/OpenLightingProject/ola/issues/433","number":433,"state":"open","locked":false,"title":"Ftdi Support for chips with multiple interfaces (ie. FT4232H, 4 interfaces)","user":{"login":"Keeper-of-the-Keys","id":1500246,"avatar_url":"https://avatars.githubusercontent.com/u/1500246?v=3","gravatar_id":"","url":"https://api.github.com/users/Keeper-of-the-Keys","html_url":"https://github.com/Keeper-of-the-Keys","followers_url":"https://api.github.com/users/Keeper-of-the-Keys/followers","following_url":"https://api.github.com/users/Keeper-of-the-Keys/following{/other_user}","gists_url":"https://api.github.com/users/Keeper-of-the-Keys/gists{/gist_id}","starred_url":"https://api.github.com/users/Keeper-of-the-Keys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Keeper-of-the-Keys/subscriptions","organizations_url":"https://api.github.com/users/Keeper-of-the-Keys/orgs","repos_url":"https://api.github.com/users/Keeper-of-the-Keys/repos","events_url":"https://api.github.com/users/Keeper-of-the-Keys/events{/privacy}","received_events_url":"https://api.github.com/users/Keeper-of-the-Keys/received_events","type":"User","site_admin":false},"body":"This was originally meant a scratch to be redone, as far as I recall the code isn't too terrible, but if you think I need to clean up more and split FtdiInterface into seperate .h and .c files I'll be happy to sit down more on it.\r\n\r\nI really wanted to do more work before I sent the pull req but I see I haven't had time to work on it for a while and it's a pity to let it sit. ","created_at":"2014-07-14T18:40:16Z","updated_at":"2015-01-04T13:49:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7d59df238415150c68c9d06077bdd51571f1c812","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433/commits","review_comments_url":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433/comments","review_comment_url":"https://api.github.com/repos/OpenLightingProject/ola/pulls/comments/{number}","comments_url":"https://api.github.com/repos/OpenLightingProject/ola/issues/433/comments","statuses_url":"https://api.github.com/repos/OpenLightingProject/ola/statuses/130c4fa04e8f7483de98b321db0cb5b15a543250","head":{"label":"Keeper-of-the-Keys:ftdi_scratch","ref":"ftdi_scratch","sha":"130c4fa04e8f7483de98b321db0cb5b15a543250","user":{"login":"Keeper-of-the-Keys","id":1500246,"avatar_url":"https://avatars.githubusercontent.com/u/1500246?v=3","gravatar_id":"","url":"https://api.github.com/users/Keeper-of-the-Keys","html_url":"https://github.com/Keeper-of-the-Keys","followers_url":"https://api.github.com/users/Keeper-of-the-Keys/followers","following_url":"https://api.github.com/users/Keeper-of-the-Keys/following{/other_user}","gists_url":"https://api.github.com/users/Keeper-of-the-Keys/gists{/gist_id}","starred_url":"https://api.github.com/users/Keeper-of-the-Keys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Keeper-of-the-Keys/subscriptions","organizations_url":"https://api.github.com/users/Keeper-of-the-Keys/orgs","repos_url":"https://api.github.com/users/Keeper-of-the-Keys/repos","events_url":"https://api.github.com/users/Keeper-of-the-Keys/events{/privacy}","received_events_url":"https://api.github.com/users/Keeper-of-the-Keys/received_events","type":"User","site_admin":false},"repo":{"id":18859745,"name":"ola","full_name":"Keeper-of-the-Keys/ola","owner":{"login":"Keeper-of-the-Keys","id":1500246,"avatar_url":"https://avatars.githubusercontent.com/u/1500246?v=3","gravatar_id":"","url":"https://api.github.com/users/Keeper-of-the-Keys","html_url":"https://github.com/Keeper-of-the-Keys","followers_url":"https://api.github.com/users/Keeper-of-the-Keys/followers","following_url":"https://api.github.com/users/Keeper-of-the-Keys/following{/other_user}","gists_url":"https://api.github.com/users/Keeper-of-the-Keys/gists{/gist_id}","starred_url":"https://api.github.com/users/Keeper-of-the-Keys/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Keeper-of-the-Keys/subscriptions","organizations_url":"https://api.github.com/users/Keeper-of-the-Keys/orgs","repos_url":"https://api.github.com/users/Keeper-of-the-Keys/repos","events_url":"https://api.github.com/users/Keeper-of-the-Keys/events{/privacy}","received_events_url":"https://api.github.com/users/Keeper-of-the-Keys/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Keeper-of-the-Keys/ola","description":"The Open Lighting Architecture","fork":true,"url":"https://api.github.com/repos/Keeper-of-the-Keys/ola","forks_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/forks","keys_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/teams","hooks_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/hooks","issue_events_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/issues/events{/number}","events_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/events","assignees_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/assignees{/user}","branches_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/branches{/branch}","tags_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/tags","blobs_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/git/refs{/sha}","trees_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/statuses/{sha}","languages_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/languages","stargazers_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/stargazers","contributors_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/contributors","subscribers_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/subscribers","subscription_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/subscription","commits_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/commits{/sha}","git_commits_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/git/commits{/sha}","comments_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/comments{/number}","issue_comment_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/issues/comments/{number}","contents_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/contents/{+path}","compare_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/merges","archive_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/downloads","issues_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/issues{/number}","pulls_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/pulls{/number}","milestones_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/milestones{/number}","notifications_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/labels{/name}","releases_url":"https://api.github.com/repos/Keeper-of-the-Keys/ola/releases{/id}","created_at":"2014-04-16T23:09:57Z","updated_at":"2015-01-04T12:45:36Z","pushed_at":"2015-01-04T13:06:44Z","git_url":"git://github.com/Keeper-of-the-Keys/ola.git","ssh_url":"git@github.com:Keeper-of-the-Keys/ola.git","clone_url":"https://github.com/Keeper-of-the-Keys/ola.git","svn_url":"https://github.com/Keeper-of-the-Keys/ola","homepage":null,"size":14794,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"OpenLightingProject:master","ref":"master","sha":"7f3f386d20be46a82b2067fdd6ce7133ad9edccd","user":{"login":"OpenLightingProject","id":6199314,"avatar_url":"https://avatars.githubusercontent.com/u/6199314?v=3","gravatar_id":"","url":"https://api.github.com/users/OpenLightingProject","html_url":"https://github.com/OpenLightingProject","followers_url":"https://api.github.com/users/OpenLightingProject/followers","following_url":"https://api.github.com/users/OpenLightingProject/following{/other_user}","gists_url":"https://api.github.com/users/OpenLightingProject/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenLightingProject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenLightingProject/subscriptions","organizations_url":"https://api.github.com/users/OpenLightingProject/orgs","repos_url":"https://api.github.com/users/OpenLightingProject/repos","events_url":"https://api.github.com/users/OpenLightingProject/events{/privacy}","received_events_url":"https://api.github.com/users/OpenLightingProject/received_events","type":"Organization","site_admin":false},"repo":{"id":15233168,"name":"ola","full_name":"OpenLightingProject/ola","owner":{"login":"OpenLightingProject","id":6199314,"avatar_url":"https://avatars.githubusercontent.com/u/6199314?v=3","gravatar_id":"","url":"https://api.github.com/users/OpenLightingProject","html_url":"https://github.com/OpenLightingProject","followers_url":"https://api.github.com/users/OpenLightingProject/followers","following_url":"https://api.github.com/users/OpenLightingProject/following{/other_user}","gists_url":"https://api.github.com/users/OpenLightingProject/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenLightingProject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenLightingProject/subscriptions","organizations_url":"https://api.github.com/users/OpenLightingProject/orgs","repos_url":"https://api.github.com/users/OpenLightingProject/repos","events_url":"https://api.github.com/users/OpenLightingProject/events{/privacy}","received_events_url":"https://api.github.com/users/OpenLightingProject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/OpenLightingProject/ola","description":"The Open Lighting Architecture","fork":false,"url":"https://api.github.com/repos/OpenLightingProject/ola","forks_url":"https://api.github.com/repos/OpenLightingProject/ola/forks","keys_url":"https://api.github.com/repos/OpenLightingProject/ola/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenLightingProject/ola/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenLightingProject/ola/teams","hooks_url":"https://api.github.com/repos/OpenLightingProject/ola/hooks","issue_events_url":"https://api.github.com/repos/OpenLightingProject/ola/issues/events{/number}","events_url":"https://api.github.com/repos/OpenLightingProject/ola/events","assignees_url":"https://api.github.com/repos/OpenLightingProject/ola/assignees{/user}","branches_url":"https://api.github.com/repos/OpenLightingProject/ola/branches{/branch}","tags_url":"https://api.github.com/repos/OpenLightingProject/ola/tags","blobs_url":"https://api.github.com/repos/OpenLightingProject/ola/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenLightingProject/ola/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenLightingProject/ola/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenLightingProject/ola/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenLightingProject/ola/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenLightingProject/ola/languages","stargazers_url":"https://api.github.com/repos/OpenLightingProject/ola/stargazers","contributors_url":"https://api.github.com/repos/OpenLightingProject/ola/contributors","subscribers_url":"https://api.github.com/repos/OpenLightingProject/ola/subscribers","subscription_url":"https://api.github.com/repos/OpenLightingProject/ola/subscription","commits_url":"https://api.github.com/repos/OpenLightingProject/ola/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenLightingProject/ola/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenLightingProject/ola/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenLightingProject/ola/issues/comments/{number}","contents_url":"https://api.github.com/repos/OpenLightingProject/ola/contents/{+path}","compare_url":"https://api.github.com/repos/OpenLightingProject/ola/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenLightingProject/ola/merges","archive_url":"https://api.github.com/repos/OpenLightingProject/ola/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenLightingProject/ola/downloads","issues_url":"https://api.github.com/repos/OpenLightingProject/ola/issues{/number}","pulls_url":"https://api.github.com/repos/OpenLightingProject/ola/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenLightingProject/ola/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenLightingProject/ola/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenLightingProject/ola/labels{/name}","releases_url":"https://api.github.com/repos/OpenLightingProject/ola/releases{/id}","created_at":"2013-12-16T18:06:52Z","updated_at":"2015-01-04T00:21:00Z","pushed_at":"2015-01-04T00:21:00Z","git_url":"git://github.com/OpenLightingProject/ola.git","ssh_url":"git@github.com:OpenLightingProject/ola.git","clone_url":"https://github.com/OpenLightingProject/ola.git","svn_url":"https://github.com/OpenLightingProject/ola","homepage":null,"size":19373,"stargazers_count":61,"watchers_count":61,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":32,"mirror_url":null,"open_issues_count":72,"forks":32,"open_issues":72,"watchers":61,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433"},"html":{"href":"https://github.com/OpenLightingProject/ola/pull/433"},"issue":{"href":"https://api.github.com/repos/OpenLightingProject/ola/issues/433"},"comments":{"href":"https://api.github.com/repos/OpenLightingProject/ola/issues/433/comments"},"review_comments":{"href":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433/comments"},"review_comment":{"href":"https://api.github.com/repos/OpenLightingProject/ola/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/OpenLightingProject/ola/pulls/433/commits"},"statuses":{"href":"https://api.github.com/repos/OpenLightingProject/ola/statuses/130c4fa04e8f7483de98b321db0cb5b15a543250"}}}}