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

Commit 6e6f22cd authored by Mike Lockwood's avatar Mike Lockwood Committed by Android Partner Code Review
Browse files

Merge "Submitted on behalf of 3rd party copied from...

Merge "Submitted on behalf of 3rd party copied from external/bluetooth/bluedroid" into klp-wireless-dev
parents 0b3268b8 bc706d7a
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