Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc706d7a authored by Hemant Gupta's avatar Hemant Gupta
Browse files

Submitted on behalf of 3rd party copied from external/bluetooth/bluedroid

Initial commit for HFP Client

Change-Id: I26b7d49b76ab28b019314ddb514e8f46b3bc4772
parent 7a2e05aa
Loading
Loading
Loading
Loading
+876 −0

File added.

Preview size limit exceeded, changes collapsed.

+323 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright (C) 2003-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This is the implementation of the API for the audio gateway (AG)
 *  subsystem of BTA, Broadcom's Bluetooth application layer for mobile
 *  phones.
 *
 ******************************************************************************/

#include "bta_api.h"
#include "bd.h"
#include "bta_sys.h"
#include "bta_ag_api.h"
#include "bta_ag_int.h"
#include "gki.h"
#include <string.h>

/*****************************************************************************
**  Constants
*****************************************************************************/

static const tBTA_SYS_REG bta_ag_reg =
{
    bta_ag_hdl_event,
    BTA_AgDisable
};

/*******************************************************************************
**
** Function         BTA_AgEnable
**
** Description      Enable the audio gateway service. When the enable
**                  operation is complete the callback function will be
**                  called with a BTA_AG_ENABLE_EVT. This function must
**                  be called before other function in the AG API are
**                  called.
**
** Returns          BTA_SUCCESS if OK, BTA_FAILURE otherwise.
**
*******************************************************************************/
tBTA_STATUS BTA_AgEnable(tBTA_AG_PARSE_MODE parse_mode, tBTA_AG_CBACK *p_cback)
{
    tBTA_AG_API_ENABLE  *p_buf;
    UINT8       idx;

    /* Error if AG is already enabled, or AG is in the middle of disabling. */
    for (idx = 0; idx < BTA_AG_NUM_SCB; idx++)
    {
        if (bta_ag_cb.scb[idx].in_use)
        {
            APPL_TRACE_ERROR0 ("BTA_AgEnable: FAILED, AG already enabled.");
            return BTA_FAILURE;
        }
    }

    /* register with BTA system manager */
    GKI_sched_lock();
    bta_sys_register(BTA_ID_AG, &bta_ag_reg);
    GKI_sched_unlock();

    if ((p_buf = (tBTA_AG_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AG_API_ENABLE))) != NULL)
    {
        p_buf->hdr.event = BTA_AG_API_ENABLE_EVT;
        p_buf->parse_mode = parse_mode;
        p_buf->p_cback = p_cback;
        bta_sys_sendmsg(p_buf);
    }

    return BTA_SUCCESS;

}

/*******************************************************************************
**
** Function         BTA_AgDisable
**
** Description      Disable the audio gateway service
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgDisable(void)
{
    BT_HDR  *p_buf;

    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_buf->event = BTA_AG_API_DISABLE_EVT;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgRegister
**
** Description      Register an Audio Gateway service.
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_SEC sec_mask,tBTA_AG_FEAT features,
                  char * p_service_names[], UINT8 app_id)
{
    tBTA_AG_API_REGISTER    *p_buf;
    int                     i;

    if ((p_buf = (tBTA_AG_API_REGISTER *) GKI_getbuf(sizeof(tBTA_AG_API_REGISTER))) != NULL)
    {
        p_buf->hdr.event = BTA_AG_API_REGISTER_EVT;
        p_buf->features = features;
        p_buf->sec_mask = sec_mask;
        p_buf->services = services;
        p_buf->app_id = app_id;
        for (i = 0; i < BTA_AG_NUM_IDX; i++)
        {
            if(p_service_names[i])
            {
                BCM_STRNCPY_S(p_buf->p_name[i], BTA_SERVICE_NAME_LEN+1, p_service_names[i], BTA_SERVICE_NAME_LEN);
                p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = 0;
            }
            else
            {
                p_buf->p_name[i][0] = 0;
            }
        }
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgDeregister
**
** Description      Deregister an audio gateway service.
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgDeregister(UINT16 handle)
{
    BT_HDR  *p_buf;

    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_buf->event = BTA_AG_API_DEREGISTER_EVT;
        p_buf->layer_specific = handle;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgOpen
**
** Description      Opens a connection to a headset or hands-free device.
**                  When connection is open callback function is called
**                  with a BTA_AG_OPEN_EVT. Only the data connection is
**                  opened. The audio connection is not opened.
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask, tBTA_SERVICE_MASK services)
{
    tBTA_AG_API_OPEN  *p_buf;

    if ((p_buf = (tBTA_AG_API_OPEN *) GKI_getbuf(sizeof(tBTA_AG_API_OPEN))) != NULL)
    {
        p_buf->hdr.event = BTA_AG_API_OPEN_EVT;
        p_buf->hdr.layer_specific = handle;
        bdcpy(p_buf->bd_addr, bd_addr);
        p_buf->services = services;
        p_buf->sec_mask = sec_mask;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgClose
**
** Description      Close the current connection to a headset or a handsfree
**                  Any current audio connection will also be closed.
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgClose(UINT16 handle)
{
    BT_HDR  *p_buf;

    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_buf->event = BTA_AG_API_CLOSE_EVT;
        p_buf->layer_specific = handle;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgAudioOpen
**
** Description      Opens an audio connection to the currently connected
**                  headset or hnadsfree.
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgAudioOpen(UINT16 handle)
{
    BT_HDR  *p_buf;

    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_buf->event = BTA_AG_API_AUDIO_OPEN_EVT;
        p_buf->layer_specific = handle;
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgAudioClose
**
** Description      Close the currently active audio connection to a headset
**                  or hnadsfree. The data connection remains open
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgAudioClose(UINT16 handle)
{
    BT_HDR  *p_buf;

    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_buf->event = BTA_AG_API_AUDIO_CLOSE_EVT;
        p_buf->layer_specific = handle;
        bta_sys_sendmsg(p_buf);
    }
}


/*******************************************************************************
**
** Function         BTA_AgResult
**
** Description      Send an AT result code to a headset or hands-free device.
**                  This function is only used when the AG parse mode is set
**                  to BTA_AG_PARSE.
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data)
{
    tBTA_AG_API_RESULT  *p_buf;

    if ((p_buf = (tBTA_AG_API_RESULT *) GKI_getbuf(sizeof(tBTA_AG_API_RESULT))) != NULL)
    {
        p_buf->hdr.event = BTA_AG_API_RESULT_EVT;
        p_buf->hdr.layer_specific = handle;
        p_buf->result = result;
        if(p_data)
        {
            memcpy(&p_buf->data, p_data, sizeof(p_buf->data));
        }
        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         BTA_AgSetCodec
**
** Description      Specify the codec type to be used for the subsequent
**                  audio connection.
**
**
**
** Returns          void
**
*******************************************************************************/
void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec)
{
    tBTA_AG_API_SETCODEC    *p_buf;

    if ((p_buf = (tBTA_AG_API_SETCODEC *) GKI_getbuf(sizeof(tBTA_AG_API_SETCODEC))) != NULL)
    {
        p_buf->hdr.event = BTA_AG_API_SETCODEC_EVT;
        p_buf->hdr.layer_specific = handle;
        p_buf->codec = codec;
        bta_sys_sendmsg(p_buf);
    }
}
+243 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright (C) 2004-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  BTA AG AT command interpreter.
 *
 ******************************************************************************/

#include <string.h>
#include "gki.h"
#include "bta_ag_at.h"
#include "utl.h"

/*****************************************************************************
**  Constants
*****************************************************************************/

/******************************************************************************
**
** Function         bta_ag_at_init
**
** Description      Initialize the AT command parser control block.
**
**
** Returns          void
**
******************************************************************************/
void bta_ag_at_init(tBTA_AG_AT_CB *p_cb)
{
    p_cb->p_cmd_buf = NULL;
    p_cb->cmd_pos = 0;
}

/******************************************************************************
**
** Function         bta_ag_at_reinit
**
** Description      Re-initialize the AT command parser control block.  This
**                  function resets the AT command parser state and frees
**                  any GKI buffer.
**
**
** Returns          void
**
******************************************************************************/
void bta_ag_at_reinit(tBTA_AG_AT_CB *p_cb)
{
    if (p_cb->p_cmd_buf != NULL)
    {
        GKI_freebuf(p_cb->p_cmd_buf);
        p_cb->p_cmd_buf = NULL;
    }
    p_cb->cmd_pos = 0;
}
/******************************************************************************
**
** Function         bta_ag_process_at
**
** Description      Parse AT commands.  This function will take the input
**                  character string and parse it for AT commands according to
**                  the AT command table passed in the control block.
**
**
** Returns          void
**
******************************************************************************/
void bta_ag_process_at(tBTA_AG_AT_CB *p_cb)
{
    UINT16      idx;
    UINT8       arg_type;
    char        *p_arg;
    INT16       int_arg = 0;
    /* loop through at command table looking for match */
    for (idx = 0; p_cb->p_at_tbl[idx].p_cmd[0] != 0; idx++)
    {
        if (!utl_strucmp(p_cb->p_at_tbl[idx].p_cmd, p_cb->p_cmd_buf))
        {
            break;
        }
    }

    /* if there is a match; verify argument type */
    if (p_cb->p_at_tbl[idx].p_cmd[0] != 0)
    {
        /* start of argument is p + strlen matching command */
        p_arg = p_cb->p_cmd_buf + strlen(p_cb->p_at_tbl[idx].p_cmd);

        /* if no argument */
        if (p_arg[0] == 0)
        {
            arg_type = BTA_AG_AT_NONE;
        }
        /* else if arg is '?' and it is last character */
        else if (p_arg[0] == '?' && p_arg[1] == 0)
        {
            /* we have a read */
            arg_type = BTA_AG_AT_READ;
        }
        /* else if arg is '=' */
        else if (p_arg[0] == '=' && p_arg[1] != 0)
        {
            if (p_arg[1] == '?' && p_arg[2] == 0)
            {
                /* we have a test */
                arg_type = BTA_AG_AT_TEST;
            }
            else
            {
                /* we have a set */
                arg_type = BTA_AG_AT_SET;

                /* skip past '=' */
                p_arg++;
            }
        }
        else
        /* else it is freeform argument */
        {
            arg_type = BTA_AG_AT_FREE;
        }

        /* if arguments match command capabilities */
        if ((arg_type & p_cb->p_at_tbl[idx].arg_type) != 0)
        {
            /* if it's a set integer check max, min range */
            if (arg_type == BTA_AG_AT_SET &&
                p_cb->p_at_tbl[idx].fmt == BTA_AG_AT_INT)
            {
                int_arg = utl_str2int(p_arg);
                if (int_arg < (INT16) p_cb->p_at_tbl[idx].min ||
                    int_arg > (INT16) p_cb->p_at_tbl[idx].max)
                {
                    /* arg out of range; error */
                    (*p_cb->p_err_cback)(p_cb->p_user, FALSE, NULL);
                }
                else
                {

                    (*p_cb->p_cmd_cback)(p_cb->p_user, idx, arg_type, p_arg, int_arg);
                }
            }
            else
            {
                (*p_cb->p_cmd_cback)(p_cb->p_user, idx, arg_type, p_arg, int_arg);
            }
        }
        /* else error */
        else
        {
            (*p_cb->p_err_cback)(p_cb->p_user, FALSE, NULL);
        }
    }
    /* else no match call error callback */
    else
    {
        (*p_cb->p_err_cback)(p_cb->p_user, TRUE, p_cb->p_cmd_buf);
    }
}

/******************************************************************************
**
** Function         bta_ag_at_parse
**
** Description      Parse AT commands.  This function will take the input
**                  character string and parse it for AT commands according to
**                  the AT command table passed in the control block.
**
**
** Returns          void
**
******************************************************************************/
void bta_ag_at_parse(tBTA_AG_AT_CB *p_cb, char *p_buf, UINT16 len)
{
    int i = 0;
    char* p_save;

    if (p_cb->p_cmd_buf == NULL)
    {
        p_cb->p_cmd_buf = (char *) GKI_getbuf(p_cb->cmd_max_len);
        p_cb->cmd_pos = 0;
    }

    for (i = 0; i < len;)
    {
        while (p_cb->cmd_pos < p_cb->cmd_max_len-1 && i < len)
        {
            /* Skip null characters between AT commands. */
            if ((p_cb->cmd_pos == 0) && (p_buf[i] == 0))
            {
                i++;
                continue;
            }

            p_cb->p_cmd_buf[p_cb->cmd_pos] = p_buf[i++];
            if ( p_cb->p_cmd_buf[p_cb->cmd_pos] == '\r' || p_cb->p_cmd_buf[p_cb->cmd_pos] == '\n')
            {
                p_cb->p_cmd_buf[p_cb->cmd_pos] = 0;
                if ((p_cb->cmd_pos > 2)                                      &&
                    (p_cb->p_cmd_buf[0] == 'A' || p_cb->p_cmd_buf[0] == 'a') &&
                    (p_cb->p_cmd_buf[1] == 'T' || p_cb->p_cmd_buf[1] == 't'))
                {
                    p_save = p_cb->p_cmd_buf;
                    p_cb->p_cmd_buf += 2;
                    bta_ag_process_at(p_cb);
                    p_cb->p_cmd_buf = p_save;
                }

                p_cb->cmd_pos = 0;

            }
            else if( p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1A || p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1B )
            {
                p_cb->p_cmd_buf[++p_cb->cmd_pos] = 0;
                (*p_cb->p_err_cback)(p_cb->p_user, TRUE, p_cb->p_cmd_buf);
                p_cb->cmd_pos = 0;
            }
            else
            {
                ++p_cb->cmd_pos;
            }
        }

        if (i < len)
            p_cb->cmd_pos = 0;
    }
}
+121 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright (C) 2004-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  Interface file for BTA AG AT command interpreter.
 *
 ******************************************************************************/
#ifndef BTA_AG_AT_H
#define BTA_AG_AT_H

/*****************************************************************************
**  Constants
*****************************************************************************/

/* AT command argument capabilities */
#define BTA_AG_AT_NONE          0x01        /* no argument */
#define BTA_AG_AT_SET           0x02        /* set value */
#define BTA_AG_AT_READ          0x04        /* read value */
#define BTA_AG_AT_TEST          0x08        /* test value range */
#define BTA_AG_AT_FREE          0x10        /* freeform argument */

/* AT command argument format */
#define BTA_AG_AT_STR           0           /* string */
#define BTA_AG_AT_INT           1           /* integer */

/*****************************************************************************
**  Data types
*****************************************************************************/

/* AT command table element */
typedef struct
{
    const char  *p_cmd;         /* AT command string */
    UINT8       arg_type;       /* allowable argument type syntax */
    UINT8       fmt;            /* whether arg is int or string */
    UINT8       min;            /* minimum value for int arg */
    INT16       max;            /* maximum value for int arg */
} tBTA_AG_AT_CMD;

/* callback function executed when command is parsed */
typedef void (tBTA_AG_AT_CMD_CBACK)(void *p_user, UINT16 cmd, UINT8 arg_type,
                                    char *p_arg, INT16 int_arg);

/* callback function executed to send "ERROR" result code */
typedef void (tBTA_AG_AT_ERR_CBACK)(void *p_user, BOOLEAN unknown, char *p_arg);

/* AT command parsing control block */
typedef struct
{
    tBTA_AG_AT_CMD          *p_at_tbl;      /* AT command table */
    tBTA_AG_AT_CMD_CBACK    *p_cmd_cback;   /* command callback */
    tBTA_AG_AT_ERR_CBACK    *p_err_cback;   /* error callback */
    void                    *p_user;        /* user-defined data */
    char                    *p_cmd_buf;     /* temp parsing buffer */
    UINT16                  cmd_pos;        /* position in temp buffer */
    UINT16                  cmd_max_len;    /* length of temp buffer to allocate */
    UINT8                   state;          /* parsing state */
} tBTA_AG_AT_CB;

/*****************************************************************************
**  Function prototypes
*****************************************************************************/

/*****************************************************************************
**
** Function         bta_ag_at_init
**
** Description      Initialize the AT command parser control block.
**
**
** Returns          void
**
*****************************************************************************/
extern void bta_ag_at_init(tBTA_AG_AT_CB *p_cb);

/*****************************************************************************
**
** Function         bta_ag_at_reinit
**
** Description      Re-initialize the AT command parser control block.  This
**                  function resets the AT command parser state and frees
**                  any GKI buffer.
**
**
** Returns          void
**
*****************************************************************************/
extern void bta_ag_at_reinit(tBTA_AG_AT_CB *p_cb);

/*****************************************************************************
**
** Function         bta_ag_at_parse
**
** Description      Parse AT commands.  This function will take the input
**                  character string and parse it for AT commands according to
**                  the AT command table passed in the control block.
**
**
** Returns          void
**
*****************************************************************************/
extern void bta_ag_at_parse(tBTA_AG_AT_CB *p_cb, char *p_buf, UINT16 len);

#endif /* BTA_AG_AT_H */
+1843 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading