/*******************************************************************************
**
** Function         bta_ma_parse_envelope
**
** Description      Parses a <bmessage-envelope> from the stream into a
**                  generic tBTA_MA_BMSG_ENVELOPE structure.  This will parse text
**                  until we see "END:BENV" at the start of a line.
**
** Parameters       p_envelope - pointer to generic envelope structure.
**                  p_stream - Input stream.
**
** Returns          BTA_MA_STATUS_OK if successful.  BTA_MA_STATUS_FAIL if not.
**
*******************************************************************************/
tBTA_MA_STATUS bta_ma_parse_envelope(tBTA_MA_BMSG_ENVELOPE * p_envelope,
                                     tBTA_MA_STREAM * p_stream)
{
    char sz[BTA_MA_MAX_SIZE];
    tBTA_MA_STATUS status = BTA_MA_STATUS_FAIL;
    tBTA_MA_BMSG_VCARD * p_vcard = NULL;
    tBTA_MA_BMSG_ENVELOPE * p_new_envelope = NULL;
    tBTA_MA_BMSG_BODY * p_body = NULL;

    while ( bta_ma_get_tag(p_stream, sz, BTA_MA_MAX_SIZE) )
    {
        if ( strcmp(sz, "BEGIN") == 0 )
        {
            bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE);

            if ( strcmp(sz, "VCARD") == 0 )
            {
                p_vcard = BTA_MaBmsgAddRecipToEnv(p_envelope);
                bta_ma_parse_vcard(p_vcard, p_stream);
            }
            else if ( strcmp(sz, "BENV") == 0 )
            {
                p_new_envelope = BTA_MaBmsgAddEnvToEnv(p_envelope);
                bta_ma_parse_envelope(p_new_envelope, p_stream);
            }
            else if ( strcmp(sz, "BBODY") == 0 )
            {
                p_body = BTA_MaBmsgAddBodyToEnv(p_envelope);
                bta_ma_parse_body(p_body, p_stream);
            }
            else
            {
                APPL_TRACE_ERROR1("bta_ma_parse_envelope - Invalid BEGIN: '%s'", sz);
            }

        }
        else if ( strcmp(sz, "END") == 0 )
        {
            bta_ma_get_value(p_stream, sz, BTA_MA_MAX_SIZE);
            status = BTA_MA_STATUS_OK;
            break;
        }
        else
        {
            APPL_TRACE_ERROR1("bta_ma_parse_envelope - Invalid tag: '%s'", sz);
        }
    }

    return( status );
}
Пример #2
0
int socket_server_open(char *socket_name)
{
    int sock = -1;
    struct sockaddr_un server_address;
    int status;
    char errorstring[80];

    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock < 0) 
    {
        strerror_r(errno, errorstring, sizeof(errorstring));
        APPL_TRACE_ERROR1("socket_server_open: socket failed(%s) \n", errorstring);
        return -1;
    }

    memset((char *) &server_address, 0 , sizeof(server_address));
    server_address.sun_family = AF_UNIX;
    server_address.sun_path[0] = 0;

    strncat(server_address.sun_path, (char*)socket_name, sizeof(server_address.sun_path)-1-strlen(server_address.sun_path));

     /* Remove old socket (if previous server closed without removing it) */
    if (unlink(server_address.sun_path) == 0)
    {
        APPL_TRACE_WARNING1("socket_server_open: removed old file:%s \n", socket_name);
    }

    
    if (bind(sock, (struct sockaddr *) &server_address,
            sizeof(server_address)) < 0)
    {
        strerror_r(errno, errorstring, sizeof(errorstring));
        APPL_TRACE_ERROR1("socket_server_open: bind failed(%s) \n", errorstring);
        close(sock);
        return -1;
    }

    /* Set up queue for incoming connections. */
    status = listen(sock, LISTEN_BACKLOG);
    if (status < 0)
    {
        strerror_r(errno, errorstring, sizeof(errorstring));
        APPL_TRACE_ERROR1("socket_server_open: listen failed(%s) \n", errorstring);
        close(sock);
        return -1;
    }

    return sock;
}
Пример #3
0
int btsock_thread_wakeup(int h)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR1("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR1("thread handle:%d, cmd socket is not created", h);
        return FALSE;
    }
    sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0};
    return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
}
Пример #4
0
static char *bta_hf_client_parse_binp(char *buffer)
{
    /* HFP only supports phone number as BINP data */
    /* phone number is 32 chars plus one for \0*/
    char numstr[33];
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+BINP:");

    res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
    if(res < 1)
    {
        return NULL;
    }

    /* Abort in case offset not set because of format error */
    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_binp: Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    /* some phones might sent type as well, just skip it */
    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_binp(numstr);
    return buffer;
}
Пример #5
0
static char *bta_hf_client_parse_cops(char *buffer)
{
    UINT8 mode;
    /* spec forces 16 chars max, plus \0 here */
    char opstr[17];
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+COPS:");

    /* TODO: Not sure if operator string actually can contain escaped " char inside */
    res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
    if(res < 2)
    {
        return NULL;
    }
    /* Abort in case offset not set because of format error */
    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_cops: Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_cops(opstr, mode);
    return buffer;
}
Пример #6
0
/* in HFP context there is no difference between ccwa and clip */
static char *bta_hf_client_parse_ccwa(char *buffer)
{
    /* ac to spec 32 chars max, plus \0 here */
    char number[33];
    UINT32 type = 0;
    int res ;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+CCWA:");

    /* there might be something more after %lu but HFP doesn't care */
    res = sscanf(buffer, "\"%32[^\"]\",%lu%n", number, &type, &offset);
    if(res < 2)
    {
        return NULL;
    }

    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_ccwa : Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ccwa(number, type);
    return buffer;
}
Пример #7
0
static char *bta_hf_client_parse_ciev(char *buffer)
{
    UINT32 index, value;
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+CIEV:");

    res = sscanf(buffer, "%lu,%lu%n", &index, &value, &offset);
    if(res < 2)
    {
        return NULL;
    }

    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_ciev : Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ciev(index, value);
    return buffer;
}
Пример #8
0
static int process_cmd_sock(int h)
{
    sock_cmd_t cmd = {-1, 0, 0, 0, 0};
    int fd = ts[h].cmd_fdr;
    if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
    {
        APPL_TRACE_ERROR1("recv cmd errno:%d", errno);
        return FALSE;
    }
    APPL_TRACE_DEBUG1("cmd.id:%d", cmd.id);
    switch(cmd.id)
    {
        case CMD_ADD_FD:
            add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id);
            break;
        case CMD_WAKEUP:
            break;
        case CMD_USER_PRIVATE:
            asrt(ts[h].cmd_callback);
            if(ts[h].cmd_callback)
                ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id);
            break;
        case CMD_EXIT:
            return FALSE;
        default:
            APPL_TRACE_DEBUG1("unknown cmd: %d", cmd.id);
             break;
    }
    return TRUE;
}
Пример #9
0
static char *bta_hf_client_parse_cnum(char *buffer)
{
    char numstr[33];     /* spec forces 32 chars, plus one for \0*/
    UINT16 type;
    UINT16 service = 0; /* 0 in case this optional parameter is not being sent */
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+CNUM:");

    res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service, &offset);
    if(res < 0)
    {
        return NULL;
    }

    if (res == 0)
    {
        res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
        if (res < 0)
        {
            return NULL;
        }

        /* numstr is not matched in second attempt, correct this */
        res++;
        numstr[0] = '\0';
    }

    if (res < 3)
    {
        return NULL;
    }

    /* Abort in case offset not set because of format error */
    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_cnum: Format Error %s", buffer);
        return NULL;
    }

    buffer += offset;

    AT_CHECK_RN(buffer);

    /* service is optional */
    if(res == 2)
    {
        bta_hf_client_handle_cnum(numstr, type, service);
        return buffer;
    }

    if (service != 4 && service != 5)
    {
        return NULL;
    }

    bta_hf_client_handle_cnum(numstr, type, service);
    return buffer;
}
Пример #10
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_peer_supports_codec
 **
 ** Description      Check if a connection supports the codec config
 **
 ** Returns          TRUE if the connection supports this codec, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT8 *p_snk_index)
{
    int index;
    UINT8 codec_type;
    FUNC_TRACE();

    /* Configure the codec type to look for */
    codec_type = bta_av_co_cb.codec_cfg.id;


    for (index = 0; index < p_peer->num_sup_snks; index++)
    {
        if (p_peer->snks[index].codec_type == codec_type)
        {
            switch (bta_av_co_cb.codec_cfg.id)
            {
            case BTIF_AV_CODEC_SBC:
                if (p_snk_index) *p_snk_index = index;
                return bta_av_co_audio_codec_match(p_peer->snks[index].codec_caps);
                break;


            default:
                APPL_TRACE_ERROR1("bta_av_co_audio_peer_supports_codec: unsupported codec id %d", bta_av_co_cb.codec_cfg.id);
                return FALSE;
                break;
            }
        }
    }
    return FALSE;
}
Пример #11
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_codec_build_config
 **
 ** Description      Build the codec configuration
 **
 ** Returns          TRUE if the codec was built successfully, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg)
{
    FUNC_TRACE();

    memset(p_codec_cfg, 0, AVDT_CODEC_SIZE);

    switch (bta_av_co_cb.codec_cfg.id)
    {
    case BTIF_AV_CODEC_SBC:
        /*  only copy the relevant portions for this codec to avoid issues when
            comparing codec configs covering larger codec sets than SBC (7 bytes) */
        memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg.info, BTA_AV_CO_SBC_MAX_BITPOOL_OFF+1);

        /* Update the bit pool boundaries with the codec capabilities */
        p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF];
        p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF];

        APPL_TRACE_EVENT2("bta_av_co_audio_codec_build_config : bitpool min %d, max %d",
                    p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
                    p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
        break;
    default:
        APPL_TRACE_ERROR1("bta_av_co_audio_codec_build_config: unsupported codec id %d", bta_av_co_cb.codec_cfg.id);
        return FALSE;
        break;
    }
    return TRUE;
}
Пример #12
0
static char *bta_hf_client_parse_cind_list(char *buffer)
{
    int offset = 0;
    char name[129];
    UINT32 min, max;
    UINT32 index = 0;
    int res;

    while ((res = sscanf(buffer, "(\"%128[^\"]\",(%lu%*[-,]%lu))%n", name, &min, &max, &offset)) > 2)
    {
        bta_hf_client_handle_cind_list_item(name, min, max, index);
        if (offset == 0)
        {
            APPL_TRACE_ERROR1("bta_hf_client_parse_cind_list : Format Error %s", buffer);
            return NULL;
        }
        buffer += offset;
        index++;

        if (*buffer != ',')
        {
            break;
        }

        buffer++;
    }

    if (res > 2)
    {
        AT_CHECK_RN(buffer);
        return buffer;
    }

    return NULL;
}
Пример #13
0
int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR1("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR0("cmd socket is not created. socket thread may not initialized");
        return FALSE;
    }
    sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id};
    APPL_TRACE_DEBUG3("post cmd type:%d, size:%d, h:%d, ", type, size, h);
    sock_cmd_t* cmd_send = &cmd;
    int size_send = sizeof(cmd);
    if(data && size)
    {
        size_send = sizeof(cmd) + size;
        cmd_send = (sock_cmd_t*)alloca(size_send);
        if(cmd_send)
        {
            *cmd_send = cmd;
            memcpy(cmd_send + 1, data, size);
        }
        else
        {
            APPL_TRACE_ERROR3("alloca failed at h:%d, cmd type:%d, size:%d", h, type, size_send);
            return FALSE;
        }
    }
    return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send;
}
Пример #14
0
static inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id)
{
    asrt(fd != -1);
    int i;
    int empty = -1;
    poll_slot_t* ps = ts[h].ps;

    for(i = 0; i < MAX_POLL; i++)
    {
        if(ps[i].pfd.fd == fd)
        {
            asrt(ts[h].poll_count < MAX_POLL);

            set_poll(&ps[i], fd, type, flags | ps[i].flags, user_id);
            return;
        }
        else if(empty < 0 && ps[i].pfd.fd == -1)
            empty = i;
    }
    if(empty >= 0)
    {
        asrt(ts[h].poll_count < MAX_POLL);
        set_poll(&ps[empty], fd, type, flags, user_id);
        ++ts[h].poll_count;
        return;
    }
    APPL_TRACE_ERROR1("exceeded max poll slot:%d!", MAX_POLL);
}
Пример #15
0
int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR1("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR0("cmd socket is not created. socket thread may not initialized");
        return FALSE;
    }
    if(flags & SOCK_THREAD_ADD_FD_SYNC)
    {
        //must executed in socket poll thread
        if(ts[h].thread_id == pthread_self())
        {
            //cleanup one-time flags
            flags &= ~SOCK_THREAD_ADD_FD_SYNC;
            add_poll(h, fd, type, flags, user_id);
            return TRUE;
        }
        APPL_TRACE_DEBUG0("THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async");
    }
    sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};
    APPL_TRACE_DEBUG2("adding fd:%d, flags:0x%x", fd, flags);
    return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
}
Пример #16
0
static void free_thread_slot(int h)
{
    if(0 <= h && h < MAX_THREAD)
    {
        close_cmd_fd(h);
        ts[h].used = 0;
    }
    else APPL_TRACE_ERROR1("invalid thread handle:%d", h);
}
Пример #17
0
static inline void set_socket_blocking(int s, int blocking)
{
    int opts;
    opts = fcntl(s, F_GETFL);
    if (opts<0) APPL_TRACE_ERROR1("set blocking (%s)", strerror(errno));
    if(blocking)
        opts &= ~O_NONBLOCK;
    else opts |= O_NONBLOCK;
    fcntl(s, F_SETFL, opts);
}
/*******************************************************************************
**
** Function         bta_gattc_hdl_event
**
** Description      GATT client main event handling function.
**
**
** Returns          void
**
*******************************************************************************/
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
{
    tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
    tBTA_GATTC_CLCB *p_clcb = NULL;

#if BTA_GATT_DEBUG == TRUE
    APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
#endif
    switch (p_msg->event)
    {
        case BTA_GATTC_API_REG_EVT:
            bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_INT_START_IF_EVT:
            bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_DEREG_EVT:
            bta_gattc_deregister(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_INT_DEREG_EVT:
            bta_gattc_int_deregister(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_OPEN_EVT:
            bta_gattc_process_api_open(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_CANCEL_OPEN_EVT:
            bta_gattc_process_api_open_cancel(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_REFRESH_EVT:
            bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        default:
            if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific))
                != NULL)
            {
                bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
            }
            else
            {
                APPL_TRACE_ERROR1("Unknown conn ID: %d", p_msg->layer_specific);
            }

            break;
    }


    return(TRUE);
}
void * bta_ma_bmsg_alloc(size_t cb)
{
    void * p_buf;

    /* For MMS, the size can be greater than UINT16. This was causing overflow error. Changed this to UINT32 */
    if ((p_buf = GKI_getbuf((UINT32) cb)) == NULL )
    {
        APPL_TRACE_ERROR1("Unable to allocate buffer for size=%d", (UINT16) cb);
    }
    return(p_buf);
}
Пример #20
0
/* create dummy socket pair used to wake up select loop */
static inline void init_cmd_fd(int h)
{
    asrt(ts[h].cmd_fdr == -1 && ts[h].cmd_fdw == -1);
    if(socketpair(AF_UNIX, SOCK_STREAM, 0, &ts[h].cmd_fdr) < 0)
    {
        APPL_TRACE_ERROR1("socketpair failed: %s", strerror(errno));
        return;
    }
    APPL_TRACE_DEBUG3("h:%d, cmd_fdr:%d, cmd_fdw:%d", h, ts[h].cmd_fdr, ts[h].cmd_fdw);
    //add the cmd fd for read & write
    add_poll(h, ts[h].cmd_fdr, 0, SOCK_THREAD_FD_RD, 0);
}
/*******************************************************************************
**
** Function         bta_av_alloc_scb
**
** Description      allocate stream control block,
**                  register the service to stack
**                  create SDP record
**
** Returns          void
**
*******************************************************************************/
static tBTA_AV_SCB * bta_av_alloc_scb(tBTA_AV_CHNL chnl)
{
    tBTA_AV_SCB *p_ret = NULL;
    int         xx;
    tBTA_AV_STATUS sts = BTA_AV_SUCCESS;

    if(chnl == BTA_AV_CHNL_VIDEO)
    {
        if(p_bta_av_cfg->p_act_tbl == NULL || p_bta_av_cfg->p_reg == NULL)
        {
            APPL_TRACE_ERROR0("Video streaming not supported");
            sts = BTA_AV_FAIL;
        }
        else
        {
            /* allow only one Video channel */
            if(bta_av_cb.reg_video)
            {
                APPL_TRACE_ERROR0("Already registered");
                sts = BTA_AV_FAIL;
            }
        }
    }
    else if(chnl != BTA_AV_CHNL_AUDIO)
    {
        APPL_TRACE_ERROR1("bad channel: %d", chnl);
        sts = BTA_AV_FAIL;
    }

    if(sts == BTA_AV_SUCCESS)
    {
        for(xx=0; xx<BTA_AV_NUM_STRS; xx++)
        {
            if(bta_av_cb.p_scb[xx] == NULL)
            {
                /* found an empty spot */
                p_ret = (tBTA_AV_SCB *)GKI_getbuf(sizeof(tBTA_AV_SCB));
                if(p_ret)
                {
                    memset(p_ret, 0, sizeof(tBTA_AV_SCB));
                    p_ret->rc_handle = BTA_AV_RC_HANDLE_NONE;
                    p_ret->chnl = chnl;
                    p_ret->hndl = (tBTA_AV_HNDL)((xx + 1) | chnl);
                    p_ret->hdi  = xx;
                    bta_av_cb.p_scb[xx] = p_ret;
                }
                break;
            }
        }
    }
    return p_ret;
}
Пример #22
0
static inline pthread_t create_thread(void *(*start_routine)(void *), void * arg)
{
    pthread_attr_t thread_attr;
    pthread_attr_init(&thread_attr);
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
    pthread_t thread_id = -1;
    if( pthread_create(&thread_id, &thread_attr, start_routine, arg)!=0 )
    {
        APPL_TRACE_ERROR1("pthread_create : %s", strerror(errno));
        return -1;
    }
    return thread_id;
}
Пример #23
0
/*******************************************************************************
 **
 ** Function         bta_av_co_get_peer
 **
 ** Description      find the peer entry for a given handle
 **
 ** Returns          the control block
 **
 *******************************************************************************/
static tBTA_AV_CO_PEER *bta_av_co_get_peer(tBTA_AV_HNDL hndl)
{
    UINT8 index;
    FUNC_TRACE();

    index = BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl);

    /* Sanity check */
    if (index >= BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers))
    {
        APPL_TRACE_ERROR1("bta_av_co_get_peer peer index out of bounds:%d", index);
        return NULL;
    }

    return &bta_av_co_cb.peers[index];
}
Пример #24
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_src_data_path
 **
 ** Description      This function is called to manage data transfer from
 **                  the audio codec to AVDTP.
 **
 ** Returns          Pointer to the GKI buffer to send, NULL if no buffer to send
 **
 *******************************************************************************/
BTA_API void * bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, UINT32 *p_len,
        UINT32 *p_timestamp)
{
    BT_HDR *p_buf;
    FUNC_TRACE();

    p_buf = btif_media_aa_readbuf();
    if (p_buf != NULL)
    {
        switch (codec_type)
        {
        case BTA_AV_CODEC_SBC:
            /* In media packet SBC, the following information is available:
             * p_buf->layer_specific : number of SBC frames in the packet
             * p_buf->word[0] : timestamp
             */
            /* Retrieve the timestamp information from the media packet */
            *p_timestamp = *((UINT32 *) (p_buf + 1));

            /* Set up packet header */
            bta_av_sbc_bld_hdr(p_buf, p_buf->layer_specific);
            break;


        default:
            APPL_TRACE_ERROR1("bta_av_co_audio_src_data_path Unsupported codec type (%d)", codec_type);
            break;
        }
#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
        {
            UINT8 *p;
            if (bta_av_co_cp_is_active())
            {
                p_buf->len++;
                p_buf->offset--;
                p = (UINT8 *)(p_buf + 1) + p_buf->offset;
                *p = bta_av_co_cp_get_flag();
            }
        }
#endif
    }
    return p_buf;
}
Пример #25
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_media_supports_config
 **
 ** Description      Check if the media source supports a given configuration
 **
 ** Returns          TRUE if the media source supports this config, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UINT8 *p_codec_cfg)
{
    FUNC_TRACE();

    switch (codec_type)
    {
    case BTA_AV_CODEC_SBC:
        if (bta_av_sbc_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_SBC_CIE *)&bta_av_co_sbc_caps))
        {
            return FALSE;
        }
        break;


    default:
        APPL_TRACE_ERROR1("bta_av_co_audio_media_supports_config unsupported codec type %d", codec_type);
        return FALSE;
        break;
    }
    return TRUE;
}
static int create_server_sdp_record(rfc_slot_t* rs)
{
    int scn = rs->scn;
    if(rs->scn > 0)
    {
        if(BTM_TryAllocateSCN(rs->scn) == FALSE)
        {
            APPL_TRACE_ERROR1("rfc channel:%d already in use", scn);
            return FALSE;
        }
    }
    else if((rs->scn = BTM_AllocateSCN()) == 0)
    {
        APPL_TRACE_ERROR0("run out of rfc channels");
        return FALSE;
    }
    if((rs->sdp_handle = add_rfc_sdp_rec(rs->service_name, rs->service_uuid, rs->scn)) <= 0)
    {
        return FALSE;
    }
    return TRUE;
}
Пример #27
0
int btsock_thread_exit(int h)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR1("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR0("cmd socket is not created");
        return FALSE;
    }
    sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0};
    if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd))
    {
        pthread_join(ts[h].thread_id, 0);
        lock_slot(&thread_slot_lock);
        free_thread_slot(h);
        unlock_slot(&thread_slot_lock);
        return TRUE;
    }
    return FALSE;
}
Пример #28
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_codec_cfg_matches_caps
 **
 ** Description      Check if a codec config matches a codec capabilities
 **
 ** Returns          TRUE if it codec config is supported, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id, const UINT8 *p_codec_caps, const UINT8 *p_codec_cfg)
{
    FUNC_TRACE();

    switch(codec_id)
    {
    case BTIF_AV_CODEC_SBC:

        APPL_TRACE_EVENT4("bta_av_co_audio_codec_cfg_matches_caps : min %d/%d max %d/%d",
           p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
           p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
           p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF],
           p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);

        /* Must match all items exactly except bitpool boundaries which can be adjusted */
        if (!((p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF] & p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF]) &&
              (p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF] & p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF])))
        {
            APPL_TRACE_EVENT4("FALSE %x %x %x %x",
                    p_codec_caps[BTA_AV_CO_SBC_FREQ_CHAN_OFF],
                    p_codec_cfg[BTA_AV_CO_SBC_FREQ_CHAN_OFF],
                    p_codec_caps[BTA_AV_CO_SBC_BLOCK_BAND_OFF],
                    p_codec_cfg[BTA_AV_CO_SBC_BLOCK_BAND_OFF]);
            return FALSE;
        }
        break;


    default:
        APPL_TRACE_ERROR1("bta_av_co_audio_codec_cfg_matches_caps: unsupported codec id %d", codec_id);
        return FALSE;
        break;
    }
    APPL_TRACE_EVENT0("TRUE");

    return TRUE;
}
static rfc_slot_t* alloc_rfc_slot(const bt_bdaddr_t *addr, const char* name, const uint8_t* uuid, int channel, int flags, BOOLEAN server)
{
    int security = 0;
    if(flags & BTSOCK_FLAG_ENCRYPT)
        security |= server ? BTM_SEC_IN_ENCRYPT : BTM_SEC_OUT_ENCRYPT;
    if(flags & BTSOCK_FLAG_AUTH)
        security |= server ? BTM_SEC_IN_AUTHENTICATE : BTM_SEC_OUT_AUTHENTICATE;

    rfc_slot_t* rs = find_free_slot();
    if(rs)
    {
        int fds[2] = {-1, -1};
        if(socketpair(AF_LOCAL, SOCK_STREAM, 0, fds))
        {
            APPL_TRACE_ERROR1("socketpair failed, errno:%d", errno);
            return NULL;
        }
        rs->fd = fds[0];
        rs->app_fd = fds[1];
        rs->security = security;
        rs->scn = channel;
        if(uuid)
            memcpy(rs->service_uuid, uuid, sizeof(rs->service_uuid));
        else memset(rs->service_uuid, 0, sizeof(rs->service_uuid));
        if(name && *name)
            strncpy(rs->service_name, name, sizeof(rs->service_name) -1);
        if(addr)
            rs->addr = *addr;
        ++rfc_slot_id;
        if(rfc_slot_id == 0)
            rfc_slot_id = 1; //skip 0 when wrapped
        rs->id = rfc_slot_id;
        rs->f.server = server;
    }
    return rs;
}
static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
    uint32_t id = (uint32_t)user_data;
    APPL_TRACE_DEBUG2("jv_dm_cback: event:%d, slot id:%d", event, id);
    switch(event)
    {
        case BTA_JV_CREATE_RECORD_EVT:
            {
                lock_slot(&slot_lock);
                rfc_slot_t* rs = find_rfc_slot_by_id(id);
                if(rs && create_server_sdp_record(rs))
                {
                    //now start the rfcomm server after sdp & channel # assigned
                    BTA_JvRfcommStartServer(rs->security, rs->role, rs->scn, MAX_RFC_SESSION, rfcomm_cback,
                                            (void*)rs->id);
                }
                else if(rs)
                {
                    APPL_TRACE_ERROR1("jv_dm_cback: cannot start server, slot found:%p", rs);
                    cleanup_rfc_slot(rs);
                }
                unlock_slot(&slot_lock);
                break;
            }
        case BTA_JV_DISCOVERY_COMP_EVT:
            {
                rfc_slot_t* rs = NULL;
                lock_slot(&slot_lock);
                if(p_data->disc_comp.status == BTA_JV_SUCCESS && p_data->disc_comp.scn)
                {
                    APPL_TRACE_DEBUG3("BTA_JV_DISCOVERY_COMP_EVT, slot id:%d, status:%d, scn:%d",
                                      id, p_data->disc_comp.status, p_data->disc_comp.scn);

                    rs = find_rfc_slot_by_id(id);
                    if(rs && rs->f.doing_sdp_request)
                    {
                        if(BTA_JvRfcommConnect(rs->security, rs->role, p_data->disc_comp.scn, rs->addr.address,
                                    rfcomm_cback, (void*)rs->id) == BTA_JV_SUCCESS)
                        {
                            rs->scn = p_data->disc_comp.scn;
                            rs->f.doing_sdp_request = FALSE;
                            if(!send_app_scn(rs))
                                cleanup_rfc_slot(rs);
                        }
                        else cleanup_rfc_slot(rs);
                    }
                    else if(rs)
                    {
                        APPL_TRACE_ERROR3("DISCOVERY_COMP_EVT no pending sdp request, slot id:%d, \
                                flag sdp pending:%d, flag sdp doing:%d",
                                id, rs->f.pending_sdp_request, rs->f.doing_sdp_request);
                    }
                }
                else
                {
                    APPL_TRACE_ERROR3("DISCOVERY_COMP_EVT slot id:%d, failed to find channle, \
                                      status:%d, scn:%d", id, p_data->disc_comp.status,
                                      p_data->disc_comp.scn);
                    rs = find_rfc_slot_by_id(id);
                    if(rs)
                        cleanup_rfc_slot(rs);
                }
                rs = find_rfc_slot_by_pending_sdp();
                if(rs)
                {
                    APPL_TRACE_DEBUG0("BTA_JV_DISCOVERY_COMP_EVT, start another pending scn sdp request");
                    tSDP_UUID sdp_uuid;
                    sdp_uuid.len = 16;
                    memcpy(sdp_uuid.uu.uuid128, rs->service_uuid, sizeof(sdp_uuid.uu.uuid128));
                    BTA_JvStartDiscovery((UINT8*)rs->addr.address, 1, &sdp_uuid, (void*)rs->id);
                    rs->f.pending_sdp_request = FALSE;
                    rs->f.doing_sdp_request = TRUE;
                }
                unlock_slot(&slot_lock);
                break;
            }