Пример #1
0
int __exapp_connectivity_destroy(uint32_t delay_s)
{
  struct timespec ts;

  if (g_connid == UINT32_MAX)
    {
      return OK;
    }

  if (delay_s >= 0)
    {
      if (g_contimer_id >= 0)
        {
          ts_core_timer_stop(g_contimer_id);
        }

      clock_gettime(CLOCK_MONOTONIC, &ts);
      ts.tv_sec += delay_s;
      g_contimer_id = ts_core_timer_setup_date(&ts, con_timer_cb, NULL);
    }
  else
    {
      con_timer_cb(-1, &ts, NULL);
    }

  return OK;
}
Пример #2
0
static void conman_events_cb(struct conman_client_s *client,
                             enum conman_event_type_e event,
                             void *payload, size_t payloadlen, void *arg)
{
  struct conman_event_priv_s *priv;
  struct timespec ts;
  int id;

  /* Called from conman_client_handle_events() or conman command response
   * handler (if event received while waiting for command response).
   */

  DEBUGASSERT(client == &g_conman_client);

  /* Events from conman command repsonse handler might be in
   * main.c:switch_state context. We must not handle events in this
   * context, so defer event handling with ts_core timer. */

  priv = calloc(1, sizeof(*priv) + payloadlen);
  if (!priv)
    {
      exapp_dbg("could not allocate %d bytes\n", sizeof(*priv) + payloadlen);
      return;
    }

  priv->event = event;
  priv->payloadlen = payloadlen;
  if (payloadlen)
    {
      memcpy(priv->payload, payload, payloadlen);
    }

  clock_gettime(CLOCK_MONOTONIC, &ts);

  id = ts_core_timer_setup_date(&ts, handle_deferred_conman_event, priv);
  DEBUGASSERT(id >= 0);
}
Пример #3
0
/****************************************************************************
 * Name: ubgps_sm_global
 *
 * Description:
 *   Global handler for gps_sm_searching_fix and gps_sm_fix_acquired states
 *
 ****************************************************************************/
static int ubgps_sm_global(struct ubgps_s * const gps, struct sm_event_s const * const event)
{
  DEBUGASSERT(gps && event);

  /* Check event */

  switch (event->id)
    {
      case SM_EVENT_ENTRY:
        {
          dbg_sm("SM_EVENT_ENTRY\n");
          if (gps->state.current_state == gps->state.target_state)
            {
              /* Report target reached */

              ubgps_report_target_state(gps, false);
            }

          if (gps->assist)
            {
              dbg_sm("start polling aiding status\n");

              (void)ubgps_send_aid_alp_poll(gps);
            }

          return OK;
        }

      case SM_EVENT_TARGET_STATE:
        {
          struct sm_event_target_state_s const * const target =
              (struct sm_event_target_state_s *)event;

          dbg_sm("SM_EVENT_TARGET_STATE\n");

          if (target->target_state != gps->state.current_state)
            {
              /* Setup target state transition timeout */

              ubgps_setup_timeout(gps, target->timeout);

              /* Set GPS target state */

              gps->state.target_state = target->target_state;

              /* Check current and target state */

              if (gps->state.target_state == GPS_STATE_FIX_ACQUIRED &&
                  gps->state.current_state == GPS_STATE_COLD_START)
                {
                  /* Move to GPS initialization for GPS aiding parameters */

                  ubgps_set_new_state(gps, GPS_STATE_INITIALIZATION);
                }
              else if (gps->state.target_state == GPS_STATE_FIX_ACQUIRED &&
                  gps->state.current_state < GPS_STATE_FIX_ACQUIRED)
                {
                  /* Move to search for GPS fix */

                  ubgps_set_new_state(gps, GPS_STATE_SEARCHING_FIX);
                }
              else
                {
                  /* Move to requested target state */

                  ubgps_set_new_state(gps, gps->state.target_state);
                }
            }
          else
            {
              /* Make current state the target state */

              gps->state.target_state = gps->state.current_state;

              /* Report target reached */

              ubgps_report_target_state(gps, false);
            }

          return OK;
        }

      case SM_EVENT_TIMEOUT:
        {
          struct sm_event_timeout_s const * const timeout =
              (struct sm_event_timeout_s *)event;
          dbg_sm("SM_EVENT_TIMEOUT\n");

          if (timeout->timer_id == gps->state.target_timer_id)
            {
              /* Report target state timeout */

              ubgps_report_target_state(gps, true);
            }
          else if (timeout->timer_id == gps->state.aid_timer_id)
            {
              /* poll whether ALP data has been expired */

              return ubgps_send_aid_alp_poll(gps);
            }
#ifdef CONFIG_UBGPS_PSM_MODE
          else if (timeout->timer_id == gps->state.location_timer_id)
            {
              struct gps_event_location_s levent;

              /* Publish the most accurate location event received so far. */

              dbg_sm("location filter timeout, accuracy: %um\n",
                  gps->filt_location.horizontal_accuracy / 1000);

              levent.super.id = GPS_EVENT_LOCATION;
              levent.time = &gps->time;
              levent.location = &gps->filt_location;
              ubgps_publish_event(gps, (struct gps_event_s *)&levent);

              /* Reset filtered location event. */

              gps->filt_location.horizontal_accuracy = 0;

              /* Construct power save mode event */

              if (gps->state.navigation_rate >= CONFIG_UBGPS_PSM_MODE_THRESHOLD)
                {
                  struct sm_event_psm_event_s psm;

                  psm.super.id = SM_EVENT_PSM_STATE;
                  psm.enable = true;
                  ubgps_sm_process(gps, (struct sm_event_s *)&psm);
                }
            }
#endif /* CONFIG_UBGPS_PSM_MODE */

          return OK;
        }

      case SM_EVENT_UBX_MESSAGE:
        {
          struct sm_event_ubx_msg_s const * const ubx_msg =
              (struct sm_event_ubx_msg_s *)event;
          struct ubx_msg_s const * const msg = ubx_msg->msg;

          if (msg->class_id == UBX_CLASS_NAV && msg->msg_id == UBX_NAV_PVT)
            {
              return ubgps_handle_nav_pvt(gps, msg);
            }
          else if (msg->class_id == UBX_CLASS_AID && msg->msg_id == UBX_AID_ALPSRV)
            {
              return ubgps_handle_aid_alpsrv(gps, msg);
            }
          else if (msg->class_id == UBX_CLASS_AID && msg->msg_id == UBX_AID_ALP)
            {
              return ubgps_handle_aid_alp(gps, msg);
            }

          dbg_sm("Unhandled UBX message, class:0x%02x, msg:0x%02x, len:%d.\n",
              ubx_msg->msg->class_id, ubx_msg->msg->msg_id, ubx_msg->msg->length);

          return OK;
        }

      case SM_EVENT_AID_STATUS:
        {
#ifdef CONFIG_UBGPS_ASSIST_UPDATER
          struct sm_event_aid_s const * const aid = (struct sm_event_aid_s *)event;
          struct timespec ts = {};
          uint32_t timeout = 0;
          dbg_sm("SM_EVENT_AID_STATUS\n");

          /* Check whether aiding has been enabled */

          if (!gps->assist)
            {
              return OK;
            }

          if (!gps->assist->alp_file)
            {
              /* Aiding file does not exist, start updater */

              ubgps_aid_updater_start(gps->assist);
              timeout = AID_STATUS_POLL_DELAY;
            }
          else if (aid->age < 0)
            {
              /* Status of aiding data not yet resolved */

              timeout = AID_STATUS_POLL_DELAY;
            }
          else if (aid->age < AID_VALIDITY_TIME_1D )
            {
              /* Aiding still valid, setup recheck timeout */

              timeout = AID_RECHECK_DELAY*1000;
            }
          else
            {
              /* Aiding data needs to be updated */

              clock_gettime(CLOCK_MONOTONIC, &ts);

              /* But first add nanoseconds to entropy pool. */

              add_time_randomness(ts.tv_nsec);

              if (gps->assist->update_time == 0 ||
                 (ts.tv_sec - gps->assist->update_time) > AID_RECHECK_DELAY)
                {
                  /* The first update attempt or retry after timeout */

                  dbg_sm("start aiding update, previous update: %ds\n",
                    ts.tv_sec - gps->assist->update_time);

                  gps->assist->update_time = ts.tv_sec;
                  ubgps_aid_updater_start(gps->assist);
                  timeout = AID_STATUS_POLL_DELAY;
                }
              else
                {
                  /* Set timeout for the next update attempt */

                  timeout = AID_RECHECK_DELAY*1000;
                }
            }

            if (gps->state.aid_timer_id >= 0)
              {
                __ubgps_remove_timer(gps, gps->state.aid_timer_id);
              }

            gps->state.aid_timer_id = __ubgps_set_timer(gps,
                                                       timeout,
                                                       ubgps_timeout,
                                                       gps);
#endif /* CONFIG_UBGPS_ASSIST_UPDATER */
          return OK;
        }

#ifdef CONFIG_UBGPS_PSM_MODE
      case SM_EVENT_PSM_STATE:
        {
          struct sm_event_psm_event_s const * const psm_event =
              (struct sm_event_psm_event_s *)event;
          dbg_sm("SM_EVENT_PSM_STATE -> %u\n", psm_event->enable);

          if (psm_event->enable)
            {
              /* Start SW controlled power save mode (PSM). */

              if (gps->state.navigation_rate >= CONFIG_UBGPS_PSM_MODE_THRESHOLD)
                {
                  struct timespec ts = {};

                  clock_gettime(CLOCK_MONOTONIC, &ts);
                  ts.tv_sec += gps->state.navigation_rate/1000;
                  gps->state.psm_timer_id = ts_core_timer_setup_date(&ts,
                      ubgps_psm_timer_cb, gps);

                  /* Update assist params */

                  gps->assist->use_time = true;
                  gps->assist->use_loc = true;
                  gps->assist->latitude = gps->location.latitude;
                  gps->assist->longitude = gps->location.longitude;
                  gps->assist->altitude = gps->location.height;
                  gps->assist->accuracy = gps->location.horizontal_accuracy;

                  dbg_sm("gps->state.psm_timer_id:%d, set POWER_OFF\n",
                      gps->state.psm_timer_id);
                  ubgps_set_new_state(gps, GPS_STATE_POWER_OFF);
                }
            }

          return OK;
        }
#endif /* CONFIG_UBGPS_PSM_MODE */

      default:
        return OK;
    }
}
Пример #4
0
static void handle_conman_events(enum conman_event_type_e event,
                                 void *payload, size_t payloadlen)
{
  /* Called from ts_core timer. */

  switch (event)
    {
      case CONMAN_EVENT_CELL_ENVIRONMENT:
        {
          cJSON *cell_env;

          exapp_dbg("%s event.\n", "CONMAN_EVENT_CELL_ENVIRONMENT");

          cell_env = parse_cell_env(payload, payloadlen);
          if (cell_env)
            {
              char *str = cJSON_Print(cell_env);

              exapp_dbg("\n%s\n", str);

              free(str);

              __exapp_main_report_cell_environment_results(cell_env);
            }
        }
        break;

      case CONMAN_EVENT_WIFI_SCAN:
        {
          cJSON *wifi_env;

          exapp_dbg("%s event.\n", "CONMAN_EVENT_WIFI_SCAN");

          wifi_env = parse_wifi_scan(payload, payloadlen);
          if (wifi_env)
            {
              char *str = cJSON_Print(wifi_env);

              exapp_dbg("\n%s\n", str);

              free(str);

              __exapp_main_report_wifi_scan_results(wifi_env);
            }
        }
        break;

      case CONMAN_EVENT_LOST_CONNECTION:
      case CONMAN_EVENT_CONNECTION_REQUEST_FAILED:
        {
          exapp_dbg("%s event.\n",
                 event == CONMAN_EVENT_LOST_CONNECTION ?
                     "CONMAN_EVENT_LOST_CONNECTION" :
                     "CONMAN_EVENT_CONNECTION_REQUEST_FAILED");

          if (g_retry_id < 0)
            {
              struct timespec ts;

              /* Lost connection. Poke conman to retry connection. */

              clock_gettime(CLOCK_MONOTONIC, &ts);
              ts.tv_sec += 1;

              g_retry_id = ts_core_timer_setup_date(&ts, retry_lost_connection,
                                                    NULL);
              DEBUGASSERT(g_retry_id >= 0);
            }
        }
        break;

      case CONMAN_EVENT_HW_ERROR_TOO_LOW_VOLTAGE:
        {
          exapp_dbg("%s event.\n", "CONMAN_EVENT_HW_ERROR_TOO_LOW_VOLTAGE");

          /* Modem cannot start-up, too low voltage level (battery
           * below ~3.3-3.35V). */

          if (g_conn_request_waiting)
            {
              /* At initial connection creation stage, main event loop not
               * started/running yet. Choose quick path to stand-by. */

              board_go_to_standby();
            }
        }
        break;

      default:
        break;
    }
}