示例#1
0
/******************************************************************************
**
**          MAIN PARSING FUNCTION
**
**
*******************************************************************************/
void bta_hf_client_at_parse(char *buf, unsigned int len)
{
    APPL_TRACE_DEBUG("%s offset: %u len: %u", __FUNCTION__, bta_hf_client_cb.scb.at_cb.offset, len);

    if (len + bta_hf_client_cb.scb.at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
        unsigned int tmp = bta_hf_client_cb.scb.at_cb.offset;
        unsigned int space_left = BTA_HF_CLIENT_AT_PARSER_MAX_LEN - bta_hf_client_cb.scb.at_cb.offset;
        char *tmp_buff = osi_malloc(BTA_HF_CLIENT_AT_PARSER_MAX_LEN);
        if (tmp_buff == NULL) {
            APPL_TRACE_ERROR("No mem %s", __FUNCTION__);
            return;
        }
        APPL_TRACE_DEBUG("%s overrun, trying to recover", __FUNCTION__);

        /* fill up parser buffer */
        memcpy(bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, buf, space_left);
        len -= space_left;
        buf += space_left;
        bta_hf_client_cb.scb.at_cb.offset += space_left;

        /* find end of last complete command before proceeding */
        while (bta_hf_client_check_at_complete() == FALSE) {
            if (bta_hf_client_cb.scb.at_cb.offset == 0) {
                APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");

                bta_hf_client_at_reset();
                bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
                osi_free(tmp_buff);
                return;
            }

            bta_hf_client_cb.scb.at_cb.offset--;
        }

        /* cut buffer to complete AT event and keep cut data */
        tmp += space_left - bta_hf_client_cb.scb.at_cb.offset;
        memcpy(tmp_buff, bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, tmp);
        bta_hf_client_cb.scb.at_cb.buf[bta_hf_client_cb.scb.at_cb.offset] = '\0';

        /* parse */
        bta_hf_client_at_parse_start();
        bta_hf_client_at_clear_buf();

        /* recover cut data */
        memcpy(bta_hf_client_cb.scb.at_cb.buf, tmp_buff, tmp);
        bta_hf_client_cb.scb.at_cb.offset += tmp;

        osi_free(tmp_buff);
    }

    memcpy(bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, buf, len);
    bta_hf_client_cb.scb.at_cb.offset += len;

    /* If last event is complete, parsing can be started */
    if (bta_hf_client_check_at_complete() == TRUE) {
        bta_hf_client_at_parse_start();
        bta_hf_client_at_clear_buf();
    }
}
static void bta_hf_client_at_parse_start(void)
{
    char *buf = bta_hf_client_cb.scb.at_cb.buf;

    APPL_TRACE_DEBUG("%s", __FUNCTION__);

#ifdef BTA_HF_CLIENT_AT_DUMP
    bta_hf_client_dump_at();
#endif

    while(*buf != '\0')
    {
        int i;
        char *tmp = NULL;

        for(i = 0; i < bta_hf_client_psraser_cb_count; i++)
        {
            tmp = bta_hf_client_parser_cb[i](buf);
            if (tmp == NULL)
            {
                APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
                tmp = bta_hf_client_skip_unknown(buf);
                break;
            }

            /* matched or unknown skipped, if unknown failed tmp is NULL so
               this is also handled */
            if (tmp != buf)
            {
                buf = tmp;
                break;
            }
        }

        /* could not skip unknown (received garbage?)... disconnect */
        if (tmp == NULL)
        {
            APPL_TRACE_ERROR("HFPCient: could not skip unknown AT event, disconnecting");
            bta_hf_client_at_reset();
            bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
            return;
        }

        buf = tmp;
    }
}
/*******************************************************************************
**
** Function         bta_hf_client_rfc_close
**
** Description      RFCOMM connection closed.
**
**
** Returns          void
**
*******************************************************************************/
void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
{
    UNUSED(p_data);

    /* reinitialize stuff */
    bta_hf_client_cb.scb.peer_features = 0;
    bta_hf_client_cb.scb.chld_features = 0;
    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    bta_hf_client_cb.scb.svc_conn = FALSE;
    bta_hf_client_cb.scb.send_at_reply = FALSE;
    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;

    bta_hf_client_at_reset();

    bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);

    /* call close cback */
    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);

    /* if not deregistering reopen server */
    if (bta_hf_client_cb.scb.deregister == FALSE)
    {
        /* Clear peer bd_addr so instance can be reused */
        bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);

        /* start server as it might got closed on open*/
        bta_hf_client_start_server();

        bta_hf_client_cb.scb.conn_handle = 0;

        /* Make sure SCO is shutdown */
        bta_hf_client_sco_shutdown(NULL);

        bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    }
    /* else close port and deallocate scb */
    else
    {
        bta_hf_client_close_server();
        bta_hf_client_scb_disable();
    }
}
/*******************************************************************************
**
** Function         bta_hf_client_rfc_fail
**
** Description      RFCOMM connection failed.
**
**
** Returns          void
**
*******************************************************************************/
void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
{
    UNUSED(p_data);

    /* reinitialize stuff */
    bta_hf_client_cb.scb.conn_handle = 0;
    bta_hf_client_cb.scb.peer_features = 0;
    bta_hf_client_cb.scb.chld_features = 0;
    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    bta_hf_client_cb.scb.svc_conn = FALSE;
    bta_hf_client_cb.scb.send_at_reply = FALSE;
    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;

    bta_hf_client_at_reset();

    /* reopen server */
    bta_hf_client_start_server();

    /* call open cback w. failure */
    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
}
示例#5
0
void bta_hf_client_at_init(void)
{
    memset(&bta_hf_client_cb.scb.at_cb, 0, sizeof(tBTA_HF_CLIENT_AT_CB));
    bta_hf_client_at_reset();
}