Ejemplo n.º 1
0
/*******************************************************************************
**
** Function         avdt_ccb_chan_open
**
** Description      This function calls avdt_ad_open_req() to
**                  initiate a signaling channel connection.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    UNUSED(p_data);

    BTM_SetOutService(p_ccb->peer_addr, BTM_SEC_SERVICE_AVDTP, AVDT_CHAN_SIG);
    avdt_ad_open_req(AVDT_CHAN_SIG, p_ccb, NULL, AVDT_INT);
}
/*******************************************************************************
**
** Function         sdp_conn_originate
**
** Description      This function is called from the API to originate a
**                  connection.
**
** Returns          void
**
*******************************************************************************/
tCONN_CB* sdp_conn_originate (UINT8 *p_bd_addr)
{
    tCONN_CB              *p_ccb;
    UINT16                cid;

    /* Allocate a new CCB. Return if none available. */
    if ((p_ccb = sdpu_allocate_ccb()) == NULL)
    {
        SDP_TRACE_WARNING0 ("SDP - no spare CCB for orig");
        return (NULL);
    }

    SDP_TRACE_EVENT0 ("SDP - Originate started");

    /* We are the originator of this connection */
    p_ccb->con_flags |= SDP_FLAGS_IS_ORIG;

    /* Save the BD Address and Channel ID. */
    memcpy (&p_ccb->device_address[0], p_bd_addr, sizeof (BD_ADDR));

    /* Transition to the next appropriate state, waiting for connection confirm. */
    p_ccb->con_state = SDP_STATE_CONN_SETUP;

// btla-specific ++
#ifndef ANDROID_APP_INCLUDED  /* Skip for Android: Do not need to set out_service for sdp, since sdp does not use sec. Prevents over-writing service_rec of a connection already in progress */
    BTM_SetOutService(p_bd_addr, BTM_SEC_SERVICE_SDP_SERVER, 0);
#endif
// btla-specific --

    cid = L2CA_ConnectReq (SDP_PSM, p_bd_addr);

    /* Check if L2CAP started the connection process */
    if (cid != 0)
    {
        p_ccb->connection_id = cid;

        return (p_ccb);
    }
    else
    {
        SDP_TRACE_WARNING0 ("SDP - Originate failed");
        sdpu_release_ccb (p_ccb);
        return (NULL);
    }
}
/*******************************************************************************
**
** Function         PAN_Connect
**
** Description      This function is called by the application to initiate a
**                  connection to the remote device
**
** Parameters:      rem_bda     - BD Addr of the remote device
**                  src_role    - Role of the local device for the connection
**                  dst_role    - Role of the remote device for the connection
**                                      PAN_ROLE_CLIENT is for PANU role
**                                      PAN_ROLE_GN_SERVER is for GN role
**                                      PAN_ROLE_NAP_SERVER is for NAP role
**                  *handle     - Pointer for returning Handle to the connection
**
** Returns          PAN_SUCCESS      - if the connection is initiated successfully
**                  PAN_NO_RESOURCES - resources are not sufficent
**                  PAN_FAILURE      - if the connection cannot be initiated
**                                           this can be because of the combination of
**                                           src and dst roles may not be valid or
**                                           allowed at that point of time
**
*******************************************************************************/
tPAN_RESULT PAN_Connect (BD_ADDR rem_bda, UINT8 src_role, UINT8 dst_role, UINT16 *handle)
{
    tPAN_CONN       *pcb;
    tBNEP_RESULT    result;
    tBT_UUID        src_uuid, dst_uuid;
    UINT8           service_id;
    UINT32 mx_chan_id;

    /*
    ** Initialize the handle so that in case of failure return values
    ** the profile will not get confused
    */
    *handle = BNEP_INVALID_HANDLE;

    /* Check if PAN is active or not */
    if (!(pan_cb.role & src_role))
    {
        PAN_TRACE_ERROR1 ("PAN is not active for the role %d", src_role);
        return PAN_FAILURE;
    }

    /* Validate the parameters before proceeding */
    if ((src_role != PAN_ROLE_CLIENT && src_role != PAN_ROLE_GN_SERVER && src_role != PAN_ROLE_NAP_SERVER) ||
        (dst_role != PAN_ROLE_CLIENT && dst_role != PAN_ROLE_GN_SERVER && dst_role != PAN_ROLE_NAP_SERVER))
    {
        PAN_TRACE_ERROR2 ("Either source %d or destination role %d is invalid", src_role, dst_role);
        return PAN_FAILURE;
    }

    /* Check if connection exists for this remote device */
    pcb = pan_get_pcb_by_addr (rem_bda);

    /* If we are PANU for this role validate destination role */
    if (src_role == PAN_ROLE_CLIENT)
    {
        if ((pan_cb.num_conns > 1) || (pan_cb.num_conns && (!pcb)))
        {
            /*
            ** If the request is not for existing connection reject it
            ** because if there is already a connection we cannot accept
            ** another connection in PANU role
            */
            PAN_TRACE_ERROR0 ("Cannot make PANU connections when there are more than one connection");
            return PAN_INVALID_SRC_ROLE;
        }

        src_uuid.uu.uuid16 = UUID_SERVCLASS_PANU;
        if (dst_role == PAN_ROLE_CLIENT)
        {
            service_id = BTM_SEC_SERVICE_BNEP_PANU;
            dst_uuid.uu.uuid16 = UUID_SERVCLASS_PANU;
        }
        else if (dst_role == PAN_ROLE_GN_SERVER)
        {
            service_id = BTM_SEC_SERVICE_BNEP_GN;
            dst_uuid.uu.uuid16 = UUID_SERVCLASS_GN;
        }
        else
        {
            service_id = BTM_SEC_SERVICE_BNEP_NAP;
            dst_uuid.uu.uuid16 = UUID_SERVCLASS_NAP;
        }
        mx_chan_id = dst_uuid.uu.uuid16;
    }
    /* If destination is PANU role validate source role */
    else if (dst_role == PAN_ROLE_CLIENT)
    {
        if (pan_cb.num_conns && pan_cb.active_role == PAN_ROLE_CLIENT && !pcb)
        {
            PAN_TRACE_ERROR0 ("Device already have a connection in PANU role");
            return PAN_INVALID_SRC_ROLE;
        }

        dst_uuid.uu.uuid16 = UUID_SERVCLASS_PANU;
        if (src_role == PAN_ROLE_GN_SERVER)
        {
            service_id = BTM_SEC_SERVICE_BNEP_GN;
            src_uuid.uu.uuid16 = UUID_SERVCLASS_GN;
        }
        else
        {
            service_id = BTM_SEC_SERVICE_BNEP_NAP;
            src_uuid.uu.uuid16 = UUID_SERVCLASS_NAP;
        }
        mx_chan_id = src_uuid.uu.uuid16;
    }
    /* The role combination is not valid */
    else
    {
        PAN_TRACE_ERROR2 ("Source %d and Destination roles %d are not valid combination",
            src_role, dst_role);
        return PAN_FAILURE;
    }

    /* Allocate control block and initiate connection */
    if (!pcb)
        pcb = pan_allocate_pcb (rem_bda, BNEP_INVALID_HANDLE);
    if (!pcb)
    {
        PAN_TRACE_ERROR0 ("PAN Connection failed because of no resources");
        return PAN_NO_RESOURCES;
    }
    BTM_SetOutService(rem_bda, BTM_SEC_SERVICE_BNEP_PANU, mx_chan_id);

    PAN_TRACE_API6 ("PAN_Connect() for BD Addr %x.%x.%x.%x.%x.%x",
        rem_bda[0], rem_bda[1], rem_bda[2], rem_bda[3], rem_bda[4], rem_bda[5]);
    if (pcb->con_state == PAN_STATE_IDLE)
    {
        pan_cb.num_conns++;
    }
    else if (pcb->con_state == PAN_STATE_CONNECTED)
    {
        pcb->con_flags |= PAN_FLAGS_CONN_COMPLETED;
    }
    else
        /* PAN connection is still in progress */
        return PAN_WRONG_STATE;

    pcb->con_state = PAN_STATE_CONN_START;
    pcb->prv_src_uuid = pcb->src_uuid;
    pcb->prv_dst_uuid = pcb->dst_uuid;

    pcb->src_uuid     = src_uuid.uu.uuid16;
    pcb->dst_uuid     = dst_uuid.uu.uuid16;

    src_uuid.len      = 2;
    dst_uuid.len      = 2;

    result = BNEP_Connect (rem_bda, &src_uuid, &dst_uuid, &(pcb->handle));
    if (result != BNEP_SUCCESS)
    {
        pan_release_pcb (pcb);
        return result;
    }

    PAN_TRACE_DEBUG1 ("PAN_Connect() current active role set to %d", src_role);
    pan_cb.prv_active_role = pan_cb.active_role;
    pan_cb.active_role = src_role;
    *handle = pcb->handle;
    return PAN_SUCCESS;
}