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 void * RxReaderFunc(void *param) { RilClientPrv *client_prv = (RilClientPrv *)param; int maxfd = 0; int token = 0; void *p_record = NULL; size_t recordlen = 0; int ret = 0; int n; if (client_prv == NULL) return NULL; maxfd = max(client_prv->sock, client_prv->pipefd[0]) + 1; printf("[*] %s() b_connect=%d, maxfd=%d\n", __FUNCTION__, client_prv->b_connect, maxfd); while (client_prv->b_connect) { FD_ZERO(&(client_prv->sock_rfds)); FD_SET(client_prv->sock, &(client_prv->sock_rfds)); FD_SET(client_prv->pipefd[0], &(client_prv->sock_rfds)); if (DBG) ALOGD("[*] %s() b_connect=%d\n", __FUNCTION__, client_prv->b_connect); if (select(maxfd, &(client_prv->sock_rfds), NULL, NULL, NULL) > 0) { if (FD_ISSET(client_prv->sock, &(client_prv->sock_rfds))) { // Read incoming data for (;;) { // loop until EAGAIN/EINTR, end of stream, or other error ret = record_stream_get_next(client_prv->p_rs, &p_record, &recordlen); if (ret == 0 && p_record == NULL) { // end-of-stream break; } else if (ret < 0) { break; } else if (ret == 0) { // && p_record != NULL n = processRxBuffer(client_prv, p_record, recordlen); if (n != RIL_CLIENT_ERR_SUCCESS) { ALOGE("%s: processRXBuffer returns %d", __FUNCTION__, n); } } else { printf("[*] %s()\n", __FUNCTION__); } } if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) { // fatal error or end-of-stream if (client_prv->sock > 0) { close(client_prv->sock); client_prv->sock = -1; client_prv->b_connect = 0; } if (client_prv->p_rs) record_stream_free(client_prv->p_rs); // EOS if (client_prv->err_cb) { client_prv->err_cb(client_prv->err_cb_data, RIL_CLIENT_ERR_CONNECT); return NULL; } break; } } if (FD_ISSET(client_prv->pipefd[0], &(client_prv->sock_rfds))) { char end_cmd[10]; if (DBG) ALOGD("%s(): close\n", __FUNCTION__); if (read(client_prv->pipefd[0], end_cmd, sizeof(end_cmd)) > 0) { close(client_prv->sock); close(client_prv->pipefd[0]); close(client_prv->pipefd[1]); client_prv->sock = -1; client_prv->b_connect = 0; } } } } return NULL; }