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); } }
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); } }