{"action":"created","comment":{"url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/comments/61372561","id":61372561,"diff_hunk":"@@ -0,0 +1,273 @@\n+/*\n+ * Copyright (C) 2016 Swift Navigation Inc.\n+ * Contact: Roman Gezikov <rgezikov@exafore.com>\n+ *\n+ * This source is subject to the license found in the file 'LICENSE' which must\n+ * be be distributed together with this source. All other rights reserved.\n+ *\n+ * THIS CODE AND INFORMATION IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND,\n+ * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED\n+ * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.\n+ */\n+#include <string.h>\n+#include <assert.h>\n+#include \"ndb.h\"\n+#include \"ndb_internal.h\"\n+#include <libswiftnav/constants.h>\n+#include \"libswiftnav/logging.h\"\n+#include \"timing.h\"\n+#include \"sbp.h\"\n+#include \"sbp_utils.h\"\n+\n+#define NDB_EPHE_FILE_NAME   \"ephe\"\n+\n+static ephemeris_t ndb_ephemeris[PLATFORM_SIGNAL_COUNT] _CCM;\n+static ndb_element_metadata_t ndb_ephemeris_md[PLATFORM_SIGNAL_COUNT] _CCM;\n+static ndb_file_t ndb_ephe_file = {\n+    .name = NDB_EPHE_FILE_NAME,\n+    .fh = -1,\n+    .expected_size =\n+          sizeof(ephemeris_t) * PLATFORM_SIGNAL_COUNT\n+        + sizeof(ndb_element_metadata_nv_t) * PLATFORM_SIGNAL_COUNT\n+        + sizeof(ndb_file_end_mark),\n+    .data_size = sizeof(ephemeris_t),\n+    .n_elements = PLATFORM_SIGNAL_COUNT,\n+};\n+\n+typedef struct {\n+  ephemeris_t ephe;\n+  bool used;\n+  ndb_timestamp_t received_at;\n+} ephemeris_candidate_t;\n+\n+typedef enum {\n+  EPHE_IDENTICAL,\n+  EPHE_NEW_CANDIDATE,\n+  EPHE_NEW_TRUSTED,\n+  EPHE_CAND_MISMATCH,\n+} ndb_ephemeris_status_t;\n+\n+#define EPHE_CAND_LIST_LEN (MAX_CHANNELS*2/3)\n+#define MAX_EPHE_CANDIDATE_AGE 92 /* seconds */\n+static ephemeris_candidate_t ephe_candidates[EPHE_CAND_LIST_LEN] _CCM;\n+static MUTEX_DECL(cand_list_access);\n+\n+#define EPHEMERIS_MESSAGE_SPACING_cycle        (200 / NV_WRITE_REQ_TIMEOUT)\n+#define EPHEMERIS_TRANSMIT_EPOCH_SPACING_cycle (15000 / NV_WRITE_REQ_TIMEOUT)\n+\n+void ndb_ephemeris_init()\n+{\n+  memset(ephe_candidates, 0, sizeof(ephe_candidates));\n+\n+  ndb_load_data(&ndb_ephe_file, \"ephemeris\", ndb_ephemeris, ndb_ephemeris_md,\n+                sizeof(ephemeris_t), PLATFORM_SIGNAL_COUNT);\n+}\n+\n+enum ndb_op_code ndb_ephemeris_read(gnss_signal_t sid, ephemeris_t *e)\n+{\n+  u16 idx = sid_to_global_index(sid);\n+  ndb_retrieve(e, &ndb_ephemeris[idx], sizeof(ephemeris_t));\n+  return NDB_ERR_NONE;\n+}\n+\n+enum ndb_op_code ndb_ephemeris_cache_update(ephemeris_t *cached_e,\n+                                            ndb_update_counter_t *uc)\n+{\n+  enum ndb_op_code r = NDB_ERR_NONE;\n+\n+  u16 idx = sid_to_global_index(cached_e->sid);\n+  ndb_element_metadata_t *md = &ndb_ephemeris_md[idx];\n+\n+  ndb_lock();\n+  if (md->update_c != *uc) {\n+    r = ndb_ephemeris_read(cached_e->sid, cached_e);\n+    if (NDB_ERR_NONE != r) {\n+      ndb_unlock();\n+      return r;\n+    }\n+    *uc = md->update_c;\n+  }\n+  ndb_unlock();\n+  return r;\n+}\n+\n+s16 ndb_ephe_find_candidate(const ephemeris_t *new)\n+{\n+  int i;\n+  for (i = 0; i < EPHE_CAND_LIST_LEN; i++) {\n+    if (ephe_candidates[i].used &&\n+        sid_is_equal(ephe_candidates[i].ephe.sid, new->sid))\n+      return i;\n+  }\n+  return -1;\n+}\n+\n+void ndb_ephe_try_adding_candidate(const ephemeris_t *new)\n+{\n+  int i;\n+  u32 candidate_age;\n+  ndb_timestamp_t now  = ndb_get_timestamp();\n+  for (i = 0; i < EPHE_CAND_LIST_LEN; i++) {\n+    bool empty = true;\n+    if(ephe_candidates[i].used) {\n+      candidate_age = ST2S(now - ephe_candidates[i].received_at);\n+      empty = candidate_age >  MAX_EPHE_CANDIDATE_AGE;\n+    }\n+\n+    if (empty) {\n+      memcpy(&ephe_candidates[i].ephe, new, sizeof(ephemeris_t));\n+      ephe_candidates[i].received_at = ndb_get_timestamp();\n+      ephe_candidates[i].used = true;\n+      return;\n+    }\n+  }\n+}\n+\n+void ndb_ephe_release_candidate(s16 cand_index)\n+{\n+  if((cand_index < 0) || (cand_index >= EPHE_CAND_LIST_LEN))\n+    return;\n+  ephe_candidates[cand_index].used = false;\n+}\n+\n+bool ndb_check_candidate(const ephemeris_t *new, s16 idx) {\n+  bool r = memcmp(&ephe_candidates[idx].ephe, new, sizeof(ephemeris_t)) == 0;\n+  ndb_ephe_release_candidate(idx);\n+  return r;\n+}\n+\n+ndb_ephemeris_status_t ndb_is_ephemeris_reliable(const ephemeris_t *new)\n+{\n+  ndb_ephemeris_status_t r = EPHE_CAND_MISMATCH;\n+  ephemeris_t existing;\n+  ndb_ephemeris_read(new->sid, &existing);\n+  s16 cand_index = ndb_ephe_find_candidate(new);\n+\n+  chMtxLock(&cand_list_access);\n+\n+  if (!existing.valid) {\n+    assert(cand_index == -1);\n+    chMtxUnlock(&cand_list_access);\n+    return EPHE_NEW_TRUSTED;\n+  }\n+\n+  /* Ephemeris for this SV was stored to the database already */\n+  if (memcmp(&existing, new, sizeof(ephemeris_t)) == 0) {\n+    /* New one is identical to the one in DB, no need to do anything */\n+    if (cand_index != -1)\n+      ndb_ephe_release_candidate(cand_index);\n+    chMtxUnlock(&cand_list_access);\n+    return EPHE_IDENTICAL;\n+  }\n+\n+  if (cand_index != -1) {\n+    /* Candidate was added already */\n+    r = ndb_check_candidate(new, cand_index) ?\n+        EPHE_NEW_TRUSTED : EPHE_CAND_MISMATCH;\n+  } else {\n+    /* New one is not in candidate list yet, try to put it\n+     * to an empty slot */\n+    ndb_ephe_try_adding_candidate(new);\n+    r = EPHE_NEW_CANDIDATE;\n+  }\n+\n+  chMtxUnlock(&cand_list_access);\n+  return r;\n+}\n+\n+enum ndb_op_code ndb_ephemeris_store(ephemeris_t *e, enum ndb_data_source src)\n+{\n+  if (!e->valid || !e->healthy) {\n+    return NDB_ERR_BAD_PARAM;\n+  }\n+\n+  if (NDB_DS_RECEIVER == src) {\n+    switch (ndb_is_ephemeris_reliable(e)) {\n+      case EPHE_IDENTICAL:\n+        return NDB_ERR_NONE;\n+      case EPHE_NEW_TRUSTED:\n+      {\n+        u16 idx = sid_to_global_index(e->sid);\n+        return ndb_update(e, src, &ndb_ephemeris_md[idx]);\n+      }\n+      case EPHE_NEW_CANDIDATE:\n+      case EPHE_CAND_MISMATCH:\n+        return NDB_ERR_UNRELIABLE_DATA;\n+    }\n+  } else if (NDB_DS_SBP == src) {\n+#ifndef NEVER_DEFINED","path":"src/ndb/ndb_ephemeris.c","position":198,"original_position":198,"commit_id":"27ee5226638a6d9181be94a2112952b338a8be94","original_commit_id":"27ee5226638a6d9181be94a2112952b338a8be94","user":{"login":"jacobmcnamee","id":4461703,"avatar_url":"https://avatars.githubusercontent.com/u/4461703?v=3","gravatar_id":"","url":"https://api.github.com/users/jacobmcnamee","html_url":"https://github.com/jacobmcnamee","followers_url":"https://api.github.com/users/jacobmcnamee/followers","following_url":"https://api.github.com/users/jacobmcnamee/following{/other_user}","gists_url":"https://api.github.com/users/jacobmcnamee/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobmcnamee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobmcnamee/subscriptions","organizations_url":"https://api.github.com/users/jacobmcnamee/orgs","repos_url":"https://api.github.com/users/jacobmcnamee/repos","events_url":"https://api.github.com/users/jacobmcnamee/events{/privacy}","received_events_url":"https://api.github.com/users/jacobmcnamee/received_events","type":"User","site_admin":false},"body":"Can this be removed?","created_at":"2016-04-28T04:35:40Z","updated_at":"2016-04-28T04:35:40Z","html_url":"https://github.com/swift-nav/piksi_firmware/pull/621#discussion_r61372561","pull_request_url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621","_links":{"self":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/comments/61372561"},"html":{"href":"https://github.com/swift-nav/piksi_firmware/pull/621#discussion_r61372561"},"pull_request":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621"}}},"pull_request":{"url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621","id":60084181,"html_url":"https://github.com/swift-nav/piksi_firmware/pull/621","diff_url":"https://github.com/swift-nav/piksi_firmware/pull/621.diff","patch_url":"https://github.com/swift-nav/piksi_firmware/pull/621.patch","issue_url":"https://api.github.com/repos/swift-nav/piksi_firmware/issues/621","number":621,"state":"open","locked":false,"title":"WIP: Add Nav DB module","user":{"login":"rge-exafore","id":16404161,"avatar_url":"https://avatars.githubusercontent.com/u/16404161?v=3","gravatar_id":"","url":"https://api.github.com/users/rge-exafore","html_url":"https://github.com/rge-exafore","followers_url":"https://api.github.com/users/rge-exafore/followers","following_url":"https://api.github.com/users/rge-exafore/following{/other_user}","gists_url":"https://api.github.com/users/rge-exafore/gists{/gist_id}","starred_url":"https://api.github.com/users/rge-exafore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rge-exafore/subscriptions","organizations_url":"https://api.github.com/users/rge-exafore/orgs","repos_url":"https://api.github.com/users/rge-exafore/repos","events_url":"https://api.github.com/users/rge-exafore/events{/privacy}","received_events_url":"https://api.github.com/users/rge-exafore/received_events","type":"User","site_admin":false},"body":"This change adds Nav DB module.\r\n\r\nIssues: \r\nhttps://github.com/swift-nav/exafore_planning/issues/55\r\nhttps://github.com/swift-nav/exafore_planning/issues/63\r\n\r\nDesign doc:\r\nhttps://swiftnav.hackpad.com/Piksi-Nav-DB-SMUivUFDh0Q","created_at":"2016-02-21T11:33:00Z","updated_at":"2016-04-28T04:35:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7ea2a1abed67e1fcf566beef5fb66995bcc2d2fa","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621/commits","review_comments_url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621/comments","review_comment_url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/comments{/number}","comments_url":"https://api.github.com/repos/swift-nav/piksi_firmware/issues/621/comments","statuses_url":"https://api.github.com/repos/swift-nav/piksi_firmware/statuses/27ee5226638a6d9181be94a2112952b338a8be94","head":{"label":"rge-exafore:i63-nav-db","ref":"i63-nav-db","sha":"27ee5226638a6d9181be94a2112952b338a8be94","user":{"login":"rge-exafore","id":16404161,"avatar_url":"https://avatars.githubusercontent.com/u/16404161?v=3","gravatar_id":"","url":"https://api.github.com/users/rge-exafore","html_url":"https://github.com/rge-exafore","followers_url":"https://api.github.com/users/rge-exafore/followers","following_url":"https://api.github.com/users/rge-exafore/following{/other_user}","gists_url":"https://api.github.com/users/rge-exafore/gists{/gist_id}","starred_url":"https://api.github.com/users/rge-exafore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rge-exafore/subscriptions","organizations_url":"https://api.github.com/users/rge-exafore/orgs","repos_url":"https://api.github.com/users/rge-exafore/repos","events_url":"https://api.github.com/users/rge-exafore/events{/privacy}","received_events_url":"https://api.github.com/users/rge-exafore/received_events","type":"User","site_admin":false},"repo":{"id":52073502,"name":"piksi_firmware","full_name":"rge-exafore/piksi_firmware","owner":{"login":"rge-exafore","id":16404161,"avatar_url":"https://avatars.githubusercontent.com/u/16404161?v=3","gravatar_id":"","url":"https://api.github.com/users/rge-exafore","html_url":"https://github.com/rge-exafore","followers_url":"https://api.github.com/users/rge-exafore/followers","following_url":"https://api.github.com/users/rge-exafore/following{/other_user}","gists_url":"https://api.github.com/users/rge-exafore/gists{/gist_id}","starred_url":"https://api.github.com/users/rge-exafore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rge-exafore/subscriptions","organizations_url":"https://api.github.com/users/rge-exafore/orgs","repos_url":"https://api.github.com/users/rge-exafore/repos","events_url":"https://api.github.com/users/rge-exafore/events{/privacy}","received_events_url":"https://api.github.com/users/rge-exafore/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rge-exafore/piksi_firmware","description":"Firmware for the Piksi GNSS receiver.","fork":true,"url":"https://api.github.com/repos/rge-exafore/piksi_firmware","forks_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/forks","keys_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/teams","hooks_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/hooks","issue_events_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/issues/events{/number}","events_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/events","assignees_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/assignees{/user}","branches_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/branches{/branch}","tags_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/tags","blobs_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/git/refs{/sha}","trees_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/statuses/{sha}","languages_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/languages","stargazers_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/stargazers","contributors_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/contributors","subscribers_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/subscribers","subscription_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/subscription","commits_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/commits{/sha}","git_commits_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/git/commits{/sha}","comments_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/comments{/number}","issue_comment_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/issues/comments{/number}","contents_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/contents/{+path}","compare_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/merges","archive_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/downloads","issues_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/issues{/number}","pulls_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/pulls{/number}","milestones_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/milestones{/number}","notifications_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/labels{/name}","releases_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/releases{/id}","deployments_url":"https://api.github.com/repos/rge-exafore/piksi_firmware/deployments","created_at":"2016-02-19T08:35:32Z","updated_at":"2016-02-19T08:35:33Z","pushed_at":"2016-04-27T07:49:31Z","git_url":"git://github.com/rge-exafore/piksi_firmware.git","ssh_url":"git@github.com:rge-exafore/piksi_firmware.git","clone_url":"https://github.com/rge-exafore/piksi_firmware.git","svn_url":"https://github.com/rge-exafore/piksi_firmware","homepage":"swift-nav.com","size":4422,"stargazers_count":0,"watchers_count":0,"language":"C","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":"swift-nav:master","ref":"master","sha":"7d8d827100b7949e9ad11d622d3c03b71014a377","user":{"login":"swift-nav","id":1069835,"avatar_url":"https://avatars.githubusercontent.com/u/1069835?v=3","gravatar_id":"","url":"https://api.github.com/users/swift-nav","html_url":"https://github.com/swift-nav","followers_url":"https://api.github.com/users/swift-nav/followers","following_url":"https://api.github.com/users/swift-nav/following{/other_user}","gists_url":"https://api.github.com/users/swift-nav/gists{/gist_id}","starred_url":"https://api.github.com/users/swift-nav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swift-nav/subscriptions","organizations_url":"https://api.github.com/users/swift-nav/orgs","repos_url":"https://api.github.com/users/swift-nav/repos","events_url":"https://api.github.com/users/swift-nav/events{/privacy}","received_events_url":"https://api.github.com/users/swift-nav/received_events","type":"Organization","site_admin":false},"repo":{"id":2464156,"name":"piksi_firmware","full_name":"swift-nav/piksi_firmware","owner":{"login":"swift-nav","id":1069835,"avatar_url":"https://avatars.githubusercontent.com/u/1069835?v=3","gravatar_id":"","url":"https://api.github.com/users/swift-nav","html_url":"https://github.com/swift-nav","followers_url":"https://api.github.com/users/swift-nav/followers","following_url":"https://api.github.com/users/swift-nav/following{/other_user}","gists_url":"https://api.github.com/users/swift-nav/gists{/gist_id}","starred_url":"https://api.github.com/users/swift-nav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swift-nav/subscriptions","organizations_url":"https://api.github.com/users/swift-nav/orgs","repos_url":"https://api.github.com/users/swift-nav/repos","events_url":"https://api.github.com/users/swift-nav/events{/privacy}","received_events_url":"https://api.github.com/users/swift-nav/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/swift-nav/piksi_firmware","description":"Firmware for the Piksi GNSS receiver.","fork":false,"url":"https://api.github.com/repos/swift-nav/piksi_firmware","forks_url":"https://api.github.com/repos/swift-nav/piksi_firmware/forks","keys_url":"https://api.github.com/repos/swift-nav/piksi_firmware/keys{/key_id}","collaborators_url":"https://api.github.com/repos/swift-nav/piksi_firmware/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/swift-nav/piksi_firmware/teams","hooks_url":"https://api.github.com/repos/swift-nav/piksi_firmware/hooks","issue_events_url":"https://api.github.com/repos/swift-nav/piksi_firmware/issues/events{/number}","events_url":"https://api.github.com/repos/swift-nav/piksi_firmware/events","assignees_url":"https://api.github.com/repos/swift-nav/piksi_firmware/assignees{/user}","branches_url":"https://api.github.com/repos/swift-nav/piksi_firmware/branches{/branch}","tags_url":"https://api.github.com/repos/swift-nav/piksi_firmware/tags","blobs_url":"https://api.github.com/repos/swift-nav/piksi_firmware/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/swift-nav/piksi_firmware/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/swift-nav/piksi_firmware/git/refs{/sha}","trees_url":"https://api.github.com/repos/swift-nav/piksi_firmware/git/trees{/sha}","statuses_url":"https://api.github.com/repos/swift-nav/piksi_firmware/statuses/{sha}","languages_url":"https://api.github.com/repos/swift-nav/piksi_firmware/languages","stargazers_url":"https://api.github.com/repos/swift-nav/piksi_firmware/stargazers","contributors_url":"https://api.github.com/repos/swift-nav/piksi_firmware/contributors","subscribers_url":"https://api.github.com/repos/swift-nav/piksi_firmware/subscribers","subscription_url":"https://api.github.com/repos/swift-nav/piksi_firmware/subscription","commits_url":"https://api.github.com/repos/swift-nav/piksi_firmware/commits{/sha}","git_commits_url":"https://api.github.com/repos/swift-nav/piksi_firmware/git/commits{/sha}","comments_url":"https://api.github.com/repos/swift-nav/piksi_firmware/comments{/number}","issue_comment_url":"https://api.github.com/repos/swift-nav/piksi_firmware/issues/comments{/number}","contents_url":"https://api.github.com/repos/swift-nav/piksi_firmware/contents/{+path}","compare_url":"https://api.github.com/repos/swift-nav/piksi_firmware/compare/{base}...{head}","merges_url":"https://api.github.com/repos/swift-nav/piksi_firmware/merges","archive_url":"https://api.github.com/repos/swift-nav/piksi_firmware/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/swift-nav/piksi_firmware/downloads","issues_url":"https://api.github.com/repos/swift-nav/piksi_firmware/issues{/number}","pulls_url":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls{/number}","milestones_url":"https://api.github.com/repos/swift-nav/piksi_firmware/milestones{/number}","notifications_url":"https://api.github.com/repos/swift-nav/piksi_firmware/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/swift-nav/piksi_firmware/labels{/name}","releases_url":"https://api.github.com/repos/swift-nav/piksi_firmware/releases{/id}","deployments_url":"https://api.github.com/repos/swift-nav/piksi_firmware/deployments","created_at":"2011-09-26T23:35:50Z","updated_at":"2016-04-25T01:11:20Z","pushed_at":"2016-04-27T20:22:52Z","git_url":"git://github.com/swift-nav/piksi_firmware.git","ssh_url":"git@github.com:swift-nav/piksi_firmware.git","clone_url":"https://github.com/swift-nav/piksi_firmware.git","svn_url":"https://github.com/swift-nav/piksi_firmware","homepage":"swift-nav.com","size":5973,"stargazers_count":69,"watchers_count":69,"language":"C","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":83,"mirror_url":null,"open_issues_count":116,"forks":83,"open_issues":116,"watchers":69,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621"},"html":{"href":"https://github.com/swift-nav/piksi_firmware/pull/621"},"issue":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/issues/621"},"comments":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/issues/621/comments"},"review_comments":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621/comments"},"review_comment":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/pulls/621/commits"},"statuses":{"href":"https://api.github.com/repos/swift-nav/piksi_firmware/statuses/27ee5226638a6d9181be94a2112952b338a8be94"}}}}