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);
    }
}
Ejemplo n.º 2
0
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;
}