static bool sim900_get_ip_address(struct serial_buffer *sb) { const char *msgs[1]; const size_t msgs_len = ARRAY_LEN(msgs); serial_buffer_reset(sb); serial_buffer_append(sb, "AT+CIFSR"); const size_t count = cellular_exec_cmd(sb, READ_TIMEOUT, msgs, msgs_len); const bool status = is_rsp(msgs, count, "ERROR"); if (status) { pr_warning("[sim900] Failed to read IP\r\n"); return false; } pr_info_str_msg("[sim900] IP address: ", msgs[0]); return true; }
static void open_log_file(struct logging_status *ls) { pr_info("Logging: Opening log file\r\n"); ls->writing_status = WRITING_INACTIVE; const int rc = InitFS(); if (0 != rc) { pr_error_int_msg("Logging: FS init error: ", rc); return; } pr_debug("Logging: FS init success. Opening file...\r\n"); // Open a file if one is set, else create a new one. ls->writing_status = ls->name[0] ? open_existing_log_file(ls) : open_new_log_file(ls); if (WRITING_INACTIVE == ls->writing_status) { pr_warning_str_msg("Logging: Failed to open: ", ls->name); return; } pr_info_str_msg("Logging: Opened " , ls->name); ls->flush_tick = xTaskGetTickCount(); }
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); } }
static bool sim900_setup_pdp(struct serial_buffer *sb, struct cellular_info *ci, const CellularConfig *cc) { /* Check GPRS attached */ bool gprs_attached; for (size_t tries = GPRS_ATTACH_ATTEMPTS; tries; --tries) { gprs_attached = sim900_is_gprs_attached(sb); if (gprs_attached) break; /* Wait before trying again. Arbitrary backoff */ delayMs(GPRS_ATTACH_BACKOFF_MS); } pr_info_str_msg("[sim900] GPRS Attached: ", gprs_attached ? "yes" : "no"); if (!gprs_attached) return false; /* Setup APN */ const bool status = sim900_put_pdp_config(sb, 0, cc->apnHost, cc->apnUser, cc->apnPass); if (!status) { pr_warning("[sim900] APN config failed\r\n"); return false; } bool gprs_active; for (size_t tries = GPRS_ACTIVATE_PDP_ATTEMPTS; tries; --tries) { gprs_active = sim900_activate_pdp(sb, 0); if (gprs_active) break; /* Wait before trying again. Arbitrary backoff */ delayMs(GPRS_ACTIVATE_PDP_BACKOFF_MS); } if (!gprs_active) { pr_warning("[sim900] Failed connect GPRS\r\n"); return false; } pr_debug("[sim900] GPRS connected\r\n"); /* Wait to get the IP */ bool has_ip = false; for (size_t tries = 5; tries && !has_ip; --tries) { has_ip = sim900_get_ip_address(sb); delayMs(1000); } if (!has_ip) return false; pr_debug("[sim900] IP acquired\r\n"); if (!sim900_put_dns_config(sb, cc->dns1, cc->dns2)) { /* NON-Fatal */ pr_warning("[sim900] DNS config failed\r\n"); } return true; }