void OBD2Task(void *pvParameters)
{
    pr_info("Start OBD2 task\r\n");
    size_t max_obd2_samplerate = msToTicks((TICK_RATE_HZ / MAX_OBD2_SAMPLE_RATE));
    LoggerConfig *config = getWorkingLoggerConfig();
    OBD2Config *oc = &config->OBD2Configs;
    while(1) {
        while(oc->enabled && oc->enabledPids > 0) {
            for (size_t i = 0; i < oc->enabledPids; i++) {
                PidConfig *pidCfg = &oc->pids[i];
                int value;
                unsigned char pid = pidCfg->pid;
                if (OBD2_request_PID(pid, &value, OBD2_PID_DEFAULT_TIMEOUT_MS)) {
                    OBD2_set_current_PID_value(i, value);
                    if (TRACE_LEVEL) {
                        pr_trace("read OBD2 PID ");
                        pr_trace_int(pid);
                        pr_trace("=")
                        pr_trace_int(value);
                        pr_trace("\r\n");
                    }
                } else {
                    pr_warning_int_msg("OBD2: PID read fail: ", pid);
                }
                delayTicks(max_obd2_samplerate);
            }
        }
        delayMs(OBD2_FEATURE_DISABLED_DELAY_MS);
    }
}
Example #2
0
int process_api(Serial *serial, char *buffer, size_t bufferSize)
{
    jsmn_init(&g_jsonParser);
    memset(g_json_tok, 0, sizeof(g_json_tok));

    int r = jsmn_parse(&g_jsonParser, buffer, g_json_tok, JSON_TOKENS);
    if (r == JSMN_SUCCESS) {
        return execute_api(serial, g_json_tok);
    } else {
        pr_warning_int_msg("API Error: ", r);
        return API_ERROR_MALFORMED;
    }
}
static bool sim900_disconnect(struct serial_buffer *sb,
                              struct cellular_info *ci,
                              struct telemetry_info *ti)
{
        if (!sim900_stop_direct_mode(sb)) {
                /* Then we don't know if can issue commands */
                pr_warning("[sim900] Failed to escape Direct Mode\r\n");
                return false;
        }

        if (!sim900_close_tcp_socket(sb, ti->socket)) {
                pr_warning_int_msg("[sim900] Failed to close socket ",
                                   ti->socket);
                return false;
        }

        ti->socket = -1;
        return true;
}
static bool sim900_connect_rcl_telem(struct serial_buffer *sb,
                              struct cellular_info *ci,
                              struct telemetry_info *ti,
                              const TelemetryConfig *tc)
{

        if (!sim900_connect_tcp_socket(sb, tc->telemetryServerHost,
                                       tc->telemetry_port)) {
                pr_warning("[sim900] Failed to connect to ");
                pr_warning(tc->telemetryServerHost);
                pr_warning_int_msg(":", tc->telemetry_port);

                return false;
        }
        /*
         * If here, then set a fake socket value because this
         * is how we know if we have created a socket or not.
         */
        ti->socket = 0;
        serial_buffer_reset(sb);
        return true;
}
void connectivityTask(void *params)
{

    char * buffer = (char *)portMalloc(BUFFER_SIZE);
    size_t rxCount = 0;

    ConnParams *connParams = (ConnParams*)params;
    LoggerMessage msg;

    Serial *serial = get_serial(connParams->serial);

    xQueueHandle sampleQueue = connParams->sampleQueue;
    uint32_t connection_timeout = connParams->connection_timeout;

    DeviceConfig deviceConfig;
    deviceConfig.serial = serial;
    deviceConfig.buffer = buffer;
    deviceConfig.length = BUFFER_SIZE;

    const LoggerConfig *logger_config = getWorkingLoggerConfig();

    bool logging_enabled = false;

    while (1) {
        bool should_stream = logging_enabled ||
                             logger_config->ConnectivityConfigs.telemetryConfig.backgroundStreaming ||
                             connParams->always_streaming;

        while (should_stream && connParams->init_connection(&deviceConfig) != DEVICE_INIT_SUCCESS) {
            pr_info("conn: not connected. retrying\r\n");
            vTaskDelay(INIT_DELAY);
        }

        serial->flush();
        rxCount = 0;
        size_t badMsgCount = 0;
        size_t tick = 0;
        size_t last_message_time = getUptimeAsInt();
        bool should_reconnect = false;

        while (1) {
            if ( should_reconnect )
                break; /*break out and trigger the re-connection if needed */

            should_stream =
                    logging_enabled ||
                    connParams->always_streaming ||
                    logger_config->ConnectivityConfigs.telemetryConfig.backgroundStreaming;

            const char res = receive_logger_message(sampleQueue, &msg,
                                                    IDLE_TIMEOUT);

            /*///////////////////////////////////////////////////////////
            // Process a pending message from logger task, if exists
            ////////////////////////////////////////////////////////////*/
            if (pdFALSE != res) {
                switch(msg.type) {
                case LoggerMessageType_Start: {
                    api_sendLogStart(serial);
                    put_crlf(serial);
                    tick = 0;
                    logging_enabled = true;
                    /* If we're not already streaming trigger a re-connect */
                    if (!should_stream)
                        should_reconnect = true;
                    break;
                }
                case LoggerMessageType_Stop: {
                    api_sendLogEnd(serial);
                    put_crlf(serial);
                    if (! (logger_config->ConnectivityConfigs.telemetryConfig.backgroundStreaming ||
                           connParams->always_streaming))
                        should_reconnect = true;
                    logging_enabled = false;
                    break;
                }
                case LoggerMessageType_Sample: {
                        if (!should_stream)
                                break;

                        const int send_meta = tick == 0 ||
                                (connParams->periodicMeta &&
                                 (tick % METADATA_SAMPLE_INTERVAL == 0));
                        api_send_sample_record(serial, msg.sample, tick, send_meta);

                        if (connParams->isPrimary)
                                toggle_connectivity_indicator();

                        put_crlf(serial);
                        tick++;
                        break;
                }
                default:
                    break;
                }
            }

            /*//////////////////////////////////////////////////////////
            // Process incoming message, if available
            ////////////////////////////////////////////////////////////
            //read in available characters, process message as necessary*/
            int msgReceived = processRxBuffer(serial, buffer, &rxCount);
            /*check the latest contents of the buffer for something that might indicate an error condition*/
            if (connParams->check_connection_status(&deviceConfig) != DEVICE_STATUS_NO_ERROR) {
                pr_info("conn: disconnected\r\n");
                break;
            }
            /*now process a complete message if available*/
            if (msgReceived) {
                last_message_time = getUptimeAsInt();
                pr_debug(connParams->connectionName);
                pr_debug_str_msg(": rx: ", buffer);
                int msgRes = process_api(serial, buffer, BUFFER_SIZE);

                int msgError = (msgRes == API_ERROR_MALFORMED);
                if (msgError) {
                    pr_debug("(failed)\r\n");
                }
                if (msgError) {
                    badMsgCount++;
                } else {
                    badMsgCount = 0;
                }
                if (badMsgCount >= BAD_MESSAGE_THRESHOLD) {
                    pr_warning_int_msg("re-connecting- empty/bad msgs :", badMsgCount );
                    break;
                }
                rxCount = 0;
            }

            /*disconnect if a timeout is configured and
            // we haven't heard from the other side for a while */
            const size_t timeout = getUptimeAsInt() - last_message_time;
            if (connection_timeout && timeout > connection_timeout ) {
                pr_info_str_msg(connParams->connectionName, ": timeout");
                should_reconnect = true;
            }
        }
        clear_connectivity_indicator();
        connParams->disconnect(&deviceConfig);
    }
}