/******************************************************************************
**
** Function         AVRC_AddRecord
**
** Description      This function is called to build an AVRCP SDP record.
**                  Prior to calling this function the application must
**                  call SDP_CreateRecord() to create an SDP record.
**
**                  Input Parameters:
**                      service_uuid:  Indicates TG(UUID_SERVCLASS_AV_REM_CTRL_TARGET)
**                                            or CT(UUID_SERVCLASS_AV_REMOTE_CONTROL)
**
**                      p_service_name:  Pointer to a null-terminated character
**                      string containing the service name.
**                      If service name is not used set this to NULL.
**
**                      p_provider_name:  Pointer to a null-terminated character
**                      string containing the provider name.
**                      If provider name is not used set this to NULL.
**
**                      categories:  Supported categories.
**
**                      sdp_handle:  SDP handle returned by SDP_CreateRecord().
**
**                  Output Parameters:
**                      None.
**
** Returns          AVRC_SUCCESS if successful.
**                  AVRC_NO_RESOURCES if not enough resources to build the SDP record.
**
******************************************************************************/
UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name,
                char *p_provider_name, UINT16 categories, UINT32 sdp_handle)
{
    UINT16      browse_list[1];
    BOOLEAN     result = TRUE;
    UINT8       temp[8];
    UINT8       *p;
    UINT16      count = 1;
    UINT16      class_list[2];


    AVRC_TRACE_API1("AVRC_AddRecord uuid: %x", service_uuid);

    if( service_uuid != UUID_SERVCLASS_AV_REM_CTRL_TARGET && service_uuid != UUID_SERVCLASS_AV_REMOTE_CONTROL )
        return AVRC_BAD_PARAM;

    /* add service class id list */
    class_list[0] = service_uuid;
    result &= SDP_AddServiceClassIdList(sdp_handle, count, class_list);

    /* add protocol descriptor list   */
    result &= SDP_AddProtocolList(sdp_handle, AVRC_NUM_PROTO_ELEMS, (tSDP_PROTOCOL_ELEM *)avrc_proto_list);

    /* add profile descriptor list   */
#if AVRC_METADATA_INCLUDED == TRUE
    result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_3);
#else
    result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_0);
#endif


    /* add supported categories */
    p = temp;
    UINT16_TO_BE_STREAM(p, categories);
    result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
              (UINT32)2, (UINT8*)temp);

    /* add provider name */
    if (p_provider_name != NULL)
    {
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
                    (UINT32)(strlen(p_provider_name)+1), (UINT8 *) p_provider_name);
    }

    /* add service name */
    if (p_service_name != NULL)
    {
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
                    (UINT32)(strlen(p_service_name)+1), (UINT8 *) p_service_name);
    }

    /* add browse group list */
    browse_list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);


    return (result ? AVRC_SUCCESS : AVRC_FAIL);
}
Example #2
0
/*****************************************************************************
**
**  Function:    bta_hl_sdp_register
**
**  Purpose:     Register an HDP application with SDP
**
**  Parameters:  p_cb           - Pointer to MA instance control block
**               p_service_name - MA server name
**               inst_id        - MAS instance ID
**               msg_type       - Supported message type(s)
**
**
**  Returns:     void
**
*****************************************************************************/
tBTA_HL_STATUS bta_hl_sdp_register (UINT8 app_idx)
{
    UINT16                          svc_class_id_list[BTA_HL_NUM_SVC_ELEMS];
    tSDP_PROTOCOL_ELEM              proto_elem_list[BTA_HL_NUM_PROTO_ELEMS];
    tSDP_PROTO_LIST_ELEM            add_proto_list;
    tBTA_HL_SUP_FEATURE_LIST_ELEM   sup_feature_list;
    UINT16                          browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
    UINT8                           i,j, cnt,mdep_id, mdep_role;
    UINT8                           data_exchange_spec = BTA_HL_SDP_IEEE_11073_20601;
    UINT8                           mcap_sup_proc = BTA_HL_MCAP_SUP_PROC_MASK;
    UINT16                          profile_uuid = UUID_SERVCLASS_HDP_PROFILE;
    UINT16                          version = BTA_HL_VERSION_01_00;
    UINT8                           num_services=1;
    tBTA_HL_APP_CB                  *p_cb = BTA_HL_GET_APP_CB_PTR(app_idx);
    BOOLEAN                         result = TRUE;
    tBTA_HL_STATUS                  status = BTA_HL_STATUS_OK;

#if BTA_HL_DEBUG == TRUE
    APPL_TRACE_DEBUG("bta_hl_sdp_register app_idx=%d",app_idx);
#endif

    if ((p_cb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE) &&
        (!p_cb->sup_feature.advertize_source_sdp))
    {
        return BTA_HL_STATUS_OK;
    }

    if ((p_cb->sdp_handle  = SDP_CreateRecord()) == 0)
    {
        return BTA_HL_STATUS_SDP_NO_RESOURCE;
    }

    num_services=1;
    svc_class_id_list[0]= UUID_SERVCLASS_HDP_SOURCE;
    if (p_cb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SINK)
    {
        svc_class_id_list[0]= UUID_SERVCLASS_HDP_SINK;
    }
    else
    {
        if (p_cb->sup_feature.app_role_mask != BTA_HL_MDEP_ROLE_MASK_SOURCE)
        {
            /* dual role */
            num_services=2;
            svc_class_id_list[1]= UUID_SERVCLASS_HDP_SINK;
        }
    }
    result &= SDP_AddServiceClassIdList(p_cb->sdp_handle, num_services, svc_class_id_list);

    if (result)
    {
        /* add the protocol element sequence */
        proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
        proto_elem_list[0].num_params = 1;
        proto_elem_list[0].params[0] = p_cb->ctrl_psm;
        proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_MCAP_CTRL;
        proto_elem_list[1].num_params = 1;
        proto_elem_list[1].params[0] = version;
        result &= SDP_AddProtocolList(p_cb->sdp_handle, BTA_HL_NUM_PROTO_ELEMS, proto_elem_list);

        result &= SDP_AddProfileDescriptorList(p_cb->sdp_handle, profile_uuid, version);
    }

    if (result)
    {
        add_proto_list.num_elems = BTA_HL_NUM_ADD_PROTO_ELEMS;
        add_proto_list.list_elem[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
        add_proto_list.list_elem[0].num_params = 1;
        add_proto_list.list_elem[0].params[0] = p_cb->data_psm;
        add_proto_list.list_elem[1].protocol_uuid = UUID_PROTOCOL_MCAP_DATA;
        add_proto_list.list_elem[1].num_params = 0;
        result &= SDP_AddAdditionProtoLists(p_cb->sdp_handle, BTA_HL_NUM_ADD_PROTO_LISTS,
                                            (tSDP_PROTO_LIST_ELEM *)&add_proto_list);
    }

    if (result)
    {
        if (p_cb->srv_name[0] )
        {
            result &= SDP_AddAttribute(p_cb->sdp_handle,
                                       (UINT16)ATTR_ID_SERVICE_NAME,
                                       (UINT8)TEXT_STR_DESC_TYPE,
                                       (UINT32)(strlen(p_cb->srv_name) + 1),
                                       (UINT8 *)p_cb->srv_name);
        } /* end of setting optional service name */
    }

    if (result)
    {
        if (p_cb->srv_desp[0] )
        {
            result &= SDP_AddAttribute(p_cb->sdp_handle,
                                       (UINT16)ATTR_ID_SERVICE_DESCRIPTION,
                                       (UINT8)TEXT_STR_DESC_TYPE,
                                       (UINT32)(strlen(p_cb->srv_desp) + 1),
                                       (UINT8 *)p_cb->srv_desp);

        } /* end of setting optional service description */

    }

    if (result)
    {
        if (p_cb->provider_name[0] )
        {
            result &= SDP_AddAttribute(p_cb->sdp_handle,
                                       (UINT16)ATTR_ID_PROVIDER_NAME,
                                       (UINT8)TEXT_STR_DESC_TYPE,
                                       (UINT32)(strlen(p_cb->provider_name) + 1),
                                       (UINT8 *)p_cb->provider_name);
        } /* end of setting optional provider name */
    }

    /* add supported feture list */

    if (result)
    {
        cnt=0;
        for (i=1; i<= p_cb->sup_feature.num_of_mdeps; i++)
        {
            mdep_id = (UINT8)p_cb->sup_feature.mdep[i].mdep_id;
            mdep_role = (UINT8)p_cb->sup_feature.mdep[i].mdep_cfg.mdep_role;

            for (j=0; j<p_cb->sup_feature.mdep[i].mdep_cfg.num_of_mdep_data_types; j++)
            {
                sup_feature_list.list_elem[cnt].mdep_id = mdep_id;
                sup_feature_list.list_elem[cnt].mdep_role = mdep_role;
                sup_feature_list.list_elem[cnt].data_type = p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].data_type;
                if (p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].desp[0] != '\0')
                {
                    sup_feature_list.list_elem[cnt].p_mdep_desp = p_cb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].desp;
                }
                else
                {
                    sup_feature_list.list_elem[cnt].p_mdep_desp = NULL;
                }

                cnt++;
                if (cnt==BTA_HL_NUM_SUP_FEATURE_ELEMS)
                {
                    result = FALSE;
                    break;
                }
            }
        }
        sup_feature_list.num_elems = cnt;
        result &=   bta_hl_add_sup_feature_list (p_cb->sdp_handle,
                                                 sup_feature_list.num_elems,
                                                 sup_feature_list.list_elem);
    }
    if (result)
    {
        result &= SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_HDP_DATA_EXCH_SPEC, UINT_DESC_TYPE,
                                   (UINT32)1, (UINT8*)&data_exchange_spec);
    }

    if (result)
    {

        result &= SDP_AddAttribute(p_cb->sdp_handle, ATTR_ID_HDP_MCAP_SUP_PROC, UINT_DESC_TYPE,
                                   (UINT32)1, (UINT8*)&mcap_sup_proc);
    }

    if (result)
    {
        result &= SDP_AddUuidSequence(p_cb->sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
    }

    if (result)
    {
        for(i=0; i < num_services; i++)
        {
            bta_sys_add_uuid(svc_class_id_list[i]);
            APPL_TRACE_DEBUG("dbg bta_sys_add_uuid i=%d uuid=0x%x", i, svc_class_id_list[i]); //todo
        }
    }
    else
    {
        if (p_cb->sdp_handle)
        {
            SDP_DeleteRecord(p_cb->sdp_handle);
            p_cb->sdp_handle = 0;
        }
        status = BTA_HL_STATUS_SDP_FAIL;
    }
#if BTA_HL_DEBUG == TRUE
    APPL_TRACE_DEBUG("bta_hl_sdp_register status=%s", bta_hl_status_code(status));
#endif
    return status;
}
Example #3
0
/******************************************************************************
**
** Function         bta_hf_client_add_record
**
** Description      This function is called by a server application to add
**                  HFP Client information to an SDP record.  Prior to
**                  calling this function the application must call
**                  SDP_CreateRecord() to create an SDP record.
**
** Returns          TRUE if function execution succeeded,
**                  FALSE if function execution failed.
**
******************************************************************************/
BOOLEAN bta_hf_client_add_record(char *p_service_name, UINT8 scn,
                                 tBTA_HF_CLIENT_FEAT features, UINT32 sdp_handle)
{
    tSDP_PROTOCOL_ELEM  proto_elem_list[BTA_HF_CLIENT_NUM_PROTO_ELEMS];
    UINT16              svc_class_id_list[BTA_HF_CLIENT_NUM_SVC_ELEMS];
    UINT16              browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
    UINT16              version;
    UINT16              profile_uuid;
    BOOLEAN             result = TRUE;
    UINT8               buf[2];
    UINT16              sdp_features = 0;

    APPL_TRACE_DEBUG("bta_hf_client_add_record");

    memset( proto_elem_list, 0 , BTA_HF_CLIENT_NUM_PROTO_ELEMS * sizeof(tSDP_PROTOCOL_ELEM));

    /* add the protocol element sequence */
    proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    proto_elem_list[0].num_params = 0;
    proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    proto_elem_list[1].num_params = 1;
    proto_elem_list[1].params[0] = scn;
    result &= SDP_AddProtocolList(sdp_handle, BTA_HF_CLIENT_NUM_PROTO_ELEMS, proto_elem_list);

    /* add service class id list */
    svc_class_id_list[0] = UUID_SERVCLASS_HF_HANDSFREE;
    svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
    result &= SDP_AddServiceClassIdList(sdp_handle, BTA_HF_CLIENT_NUM_SVC_ELEMS, svc_class_id_list);

    /* add profile descriptor list */
    profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
    version = HFP_VERSION_1_6;

    result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);

    /* add service name */
    if (p_service_name != NULL && p_service_name[0] != 0) {
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
                                   (UINT32)(strlen(p_service_name) + 1), (UINT8 *) p_service_name);
    }

    /* add features */
    if (features & BTA_HF_CLIENT_FEAT_ECNR) {
        sdp_features |= BTA_HF_CLIENT_FEAT_ECNR;
    }

    if (features & BTA_HF_CLIENT_FEAT_3WAY) {
        sdp_features |= BTA_HF_CLIENT_FEAT_3WAY;
    }

    if (features & BTA_HF_CLIENT_FEAT_CLI) {
        sdp_features |= BTA_HF_CLIENT_FEAT_CLI;
    }

    if (features & BTA_HF_CLIENT_FEAT_VREC) {
        sdp_features |= BTA_HF_CLIENT_FEAT_VREC;
    }

    if (features & BTA_HF_CLIENT_FEAT_VOL) {
        sdp_features |= BTA_HF_CLIENT_FEAT_VOL;
    }

    /* Codec bit position is different in SDP (bit 5) and in BRSF (bit 7) */
    if (features & BTA_HF_CLIENT_FEAT_CODEC) {
        sdp_features |= 0x0020;
    }

    UINT16_TO_BE_FIELD(buf, sdp_features);
    result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);

    /* add browse group list */
    result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);

    return result;
}
/******************************************************************************
**
** Function         bta_ag_add_record
**
** Description      This function is called by a server application to add
**                  HSP or HFP information to an SDP record.  Prior to
**                  calling this function the application must call
**                  SDP_CreateRecord() to create an SDP record.
**
** Returns          TRUE if function execution succeeded,
**                  FALSE if function execution failed.
**
******************************************************************************/
BOOLEAN bta_ag_add_record(UINT16 service_uuid, char *p_service_name, UINT8 scn,
                          tBTA_AG_FEAT features, UINT32 sdp_handle)
{
    tSDP_PROTOCOL_ELEM  proto_elem_list[BTA_AG_NUM_PROTO_ELEMS];
    UINT16              svc_class_id_list[BTA_AG_NUM_SVC_ELEMS];
    UINT16              browse_list[] = {UUID_SERVCLASS_PUBLIC_BROWSE_GROUP};
    UINT16              version;
    UINT16              profile_uuid;
    UINT8               network;
    BOOLEAN             result = TRUE;
    BOOLEAN             codec_supported = FALSE;
    UINT8               buf[2];

    APPL_TRACE_DEBUG1("bta_ag_add_record uuid: %x", service_uuid);

    memset( proto_elem_list, 0 , BTA_AG_NUM_PROTO_ELEMS*sizeof(tSDP_PROTOCOL_ELEM));

    /* add the protocol element sequence */
    proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
    proto_elem_list[0].num_params = 0;
    proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
    proto_elem_list[1].num_params = 1;
    proto_elem_list[1].params[0] = scn;
    result &= SDP_AddProtocolList(sdp_handle, BTA_AG_NUM_PROTO_ELEMS, proto_elem_list);

    /* add service class id list */
    svc_class_id_list[0] = service_uuid;
    svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
    result &= SDP_AddServiceClassIdList(sdp_handle, BTA_AG_NUM_SVC_ELEMS, svc_class_id_list);

    /* add profile descriptor list */
    if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE)
    {
        profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
        version = HFP_VERSION_1_6;
    }
    else
    {
        profile_uuid = UUID_SERVCLASS_HEADSET;
        version = HSP_VERSION_1_2;
    }
    result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);

    /* add service name */
    if (p_service_name != NULL && p_service_name[0] != 0)
    {
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
                    (UINT32)(strlen(p_service_name)+1), (UINT8 *) p_service_name);
    }

    /* add features and network */
    if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE)
    {
        network = (features & BTA_AG_FEAT_REJECT) ? 1 : 0;
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_DATA_STORES_OR_NETWORK,
                    UINT_DESC_TYPE, 1, &network);

        if (features & BTA_AG_FEAT_CODEC)
            codec_supported = TRUE;

        features &= BTA_AG_SDP_FEAT_SPEC;

        /* Codec bit position is different in SDP and in BRSF */
        if (codec_supported)
            features |= 0x0020;

        UINT16_TO_BE_FIELD(buf, features);
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);
    }

    /* add browse group list */
    result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);

    return result;
}