Beispiel #1
0
//*****************************************************************************
//
//!  HCI data command builder.
//!
//!  \param  usOpcode    command operation code
//!  \param  ucPayload   pointer to the data buffer
//!  \param  usLength    buffer length
//!
//!  \return none
//!
//!  \brief              Initiate an HCI data write operation
//
//*****************************************************************************
long
hci_data_send(unsigned char ucOpcode, 
                           unsigned char *ucArgs,
                           unsigned short usArgsLength, 
                           unsigned short usDataLength,
                           const unsigned char *ucTail,
                           unsigned short usTailLength)
{
	unsigned char *stream;
 
	stream = ((ucArgs) + SPI_HEADER_SIZE);
	
	UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
	UINT8_TO_STREAM(stream, ucOpcode);
	UINT8_TO_STREAM(stream, usArgsLength);
	stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength);

	//
	// Send the packet over the SPI
	//
    SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength);

    return(ESUCCESS);
}
/*******************************************************************************
**
** Function         HAL_NfcSetSnoozeMode
**
** Description      Set snooze mode
**                  snooze_mode
**                      NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
**                      NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
**                      NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
**
**                  idle_threshold_dh/idle_threshold_nfcc
**                      Idle Threshold Host in 100ms unit
**
**                  nfc_wake_active_mode/dh_wake_active_mode
**                      NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
**                      NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting
**
**                  p_snooze_cback
**                      Notify status of operation
**
** Returns          tHAL_NFC_STATUS
**
*******************************************************************************/
tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode,
                                      UINT8 idle_threshold_dh,
                                      UINT8 idle_threshold_nfcc,
                                      UINT8 nfc_wake_active_mode,
                                      UINT8 dh_wake_active_mode,
                                      tHAL_NFC_STATUS_CBACK *p_snooze_cback)
{
    UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH];
    UINT8 *p;

    HAL_TRACE_API1 ("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode);

    nfc_hal_cb.dev_cb.new_snooze_mode      = snooze_mode;
    nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode;
    nfc_hal_cb.dev_cb.p_prop_cback         = p_snooze_cback;

    p = cmd;

    /* Add the HCI command */
    UINT16_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE);
    UINT8_TO_STREAM  (p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);

    memset (p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);

    UINT8_TO_STREAM  (p, snooze_mode);          /* Sleep Mode               */

    UINT8_TO_STREAM  (p, idle_threshold_dh);    /* Idle Threshold Host      */
    UINT8_TO_STREAM  (p, idle_threshold_nfcc);  /* Idle Threshold HC        */
    UINT8_TO_STREAM  (p, nfc_wake_active_mode); /* BT Wake Active Mode      */
    UINT8_TO_STREAM  (p, dh_wake_active_mode);  /* Host Wake Active Mode    */

    nfc_hal_dm_send_bt_cmd (cmd,
                            NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
                            nfc_hal_dm_set_snooze_mode_cback);
    return (NCI_STATUS_OK);
}
Beispiel #3
0
/*******************************************************************************
**
** Function         l2c_bcst_msg
**
** Description
**
** Returns          void
**
*******************************************************************************/
void l2c_bcst_msg( BT_HDR *p_buf, UINT16 psm )
{
    UINT8       *p;

    /* Ensure we have enough space in the buffer for the L2CAP and HCI headers */
    if (p_buf->offset < L2CAP_BCST_MIN_OFFSET) {
        L2CAP_TRACE_ERROR ("L2CAP - cannot send buffer, offset: %d", p_buf->offset);
        GKI_freebuf (p_buf);
        return;
    }

    /* Step back some bytes to add the headers */
    p_buf->offset -= (HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD);
    p_buf->len    += L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD;

    /* Set the pointer to the beginning of the data */
    p = (UINT8 *)(p_buf + 1) + p_buf->offset;

    /* First, the HCI transport header */
    UINT16_TO_STREAM (p, 0x0050 | (L2CAP_PKT_START << 12) | (2 << 14));

    uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic();
    /* The HCI transport will segment the buffers. */
    if (p_buf->len > acl_data_size) {
        UINT16_TO_STREAM (p, acl_data_size);
    } else {
        UINT16_TO_STREAM (p, p_buf->len);
    }

    /* Now the L2CAP header */
    UINT16_TO_STREAM (p, p_buf->len - L2CAP_PKT_OVERHEAD);
    UINT16_TO_STREAM (p, L2CAP_CONNECTIONLESS_CID);
    UINT16_TO_STREAM (p, psm);

    p_buf->len += HCI_DATA_PREAMBLE_SIZE;

    if (p_buf->len <= controller_get_interface()->get_acl_packet_size_classic()) {
        //counter_add("l2cap.ch2.tx.bytes", p_buf->len);
        //counter_add("l2cap.ch2.tx.pkts", 1);

        bte_main_hci_send(p_buf, BT_EVT_TO_LM_HCI_ACL);
    }
}
Beispiel #4
0
/*******************************************************************************
**
**  Function        L2CA_UcdDataWrite
**
**  Description     Send UCD to remote device
**
**  Parameters:     PSM
**                  BD Address of remote
**                  Pointer to buffer of type BT_HDR
**                  flags : L2CAP_FLUSHABLE_CH_BASED
**                          L2CAP_FLUSHABLE_PKT
**                          L2CAP_NON_FLUSHABLE_PKT
**
** Return value     L2CAP_DW_SUCCESS, if data accepted
**                  L2CAP_DW_FAILED,  if error
**
*******************************************************************************/
UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 flags)
{
    tL2C_LCB        *p_lcb;
    tL2C_CCB        *p_ccb;
    tL2C_RCB        *p_rcb;
    UINT8           *p;

    L2CAP_TRACE_API ("L2CA_UcdDataWrite()  PSM: 0x%04x  BDA: %08x%04x", psm,
                     (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
                     (rem_bda[4] << 8) + rem_bda[5]);

    /* Fail if the PSM is not registered */
    if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
            || ( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED )) {
        L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDataWrite, PSM: 0x%04x", psm);
        osi_free (p_buf);
        return (L2CAP_DW_FAILED);
    }

    /* First, see if we already have a link to the remote */
    /*  then find the channel control block for UCD */
    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
            || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) {
        if ( l2c_ucd_connect (rem_bda) == FALSE ) {
            osi_free (p_buf);
            return (L2CAP_DW_FAILED);
        }

        /* If we still don't have lcb and ccb after connect attempt, then can't proceed */
        if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
                || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)) {
            osi_free (p_buf);
            return (L2CAP_DW_FAILED);
        }
    }

    /* write PSM */
    p_buf->offset -= L2CAP_UCD_OVERHEAD;
    p_buf->len += L2CAP_UCD_OVERHEAD;
    p = (UINT8 *)(p_buf + 1) + p_buf->offset;

    UINT16_TO_STREAM (p, psm);

    /* UCD MTU check */
    if ((p_lcb->ucd_mtu) && (p_buf->len > p_lcb->ucd_mtu)) {
        L2CAP_TRACE_WARNING ("L2CAP - Handle: 0x%04x  UCD bigger than peer's UCD mtu size cannot be sent", p_lcb->handle);
        osi_free (p_buf);
        return (L2CAP_DW_FAILED);
    }

    /* If already congested, do not accept any more packets */
    if (p_ccb->cong_sent) {
        L2CAP_TRACE_ERROR ("L2CAP - Handle: 0x%04x UCD cannot be sent, already congested count: %u  buff_quota: %u",
                           p_lcb->handle,
                           (fixed_queue_length(p_ccb->xmit_hold_q) +
                            fixed_queue_length(p_lcb->ucd_out_sec_pending_q)),
                           p_ccb->buff_quota);

        osi_free (p_buf);
        return (L2CAP_DW_FAILED);
    }

    /* channel based, packet based flushable or non-flushable */
    p_buf->layer_specific = flags;

    l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_buf);

    if (p_ccb->cong_sent) {
        return (L2CAP_DW_CONGESTED);
    } else {
        return (L2CAP_DW_SUCCESS);
    }
}
Beispiel #5
0
long
wlan_add_profile(unsigned long ulSecType,
                 unsigned char* ucSsid,
                 unsigned long ulSsidLen,
                 unsigned char *ucBssid,
                 unsigned long ulPriority,
                 unsigned long ulPairwiseCipher_Or_TxKeyLen,
                 unsigned long ulGroupCipher_TxKeyIndex,
                 unsigned long ulKeyMgmt,
                 unsigned char* ucPf_OrKey,
                 unsigned long ulPassPhraseLen)
{
    unsigned short arg_len;
    long ret;
    unsigned char *ptr;
    long i = 0;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    args = UINT32_TO_STREAM(args, ulSecType);

    // Setup arguments in accordance with the security type
    switch (ulSecType)
    {
    //OPEN
    case WLAN_SEC_UNSEC:
    {
        args = UINT32_TO_STREAM(args, 0x00000014);
        args = UINT32_TO_STREAM(args, ulSsidLen);
        args = UINT16_TO_STREAM(args, 0);
        if(ucBssid)
        {
            ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
        }
        else
        {
            ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
        }
        args = UINT32_TO_STREAM(args, ulPriority);
        ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

        arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen;
    }
    break;

    //WEP
    case WLAN_SEC_WEP:
    {
        args = UINT32_TO_STREAM(args, 0x00000020);
        args = UINT32_TO_STREAM(args, ulSsidLen);
        args = UINT16_TO_STREAM(args, 0);
        if(ucBssid)
        {
            ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
        }
        else
        {
            ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
        }
        args = UINT32_TO_STREAM(args, ulPriority);
        args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen);
        args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
        args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
        ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

        for(i = 0; i < 4; i++)
        {
            unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen];

            ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen);
        }

        arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen +
                  ulPairwiseCipher_Or_TxKeyLen * 4;

    }
    break;

    //WPA
    //WPA2
    case WLAN_SEC_WPA:
    case WLAN_SEC_WPA2:
    {
        args = UINT32_TO_STREAM(args, 0x00000028);
        args = UINT32_TO_STREAM(args, ulSsidLen);
        args = UINT16_TO_STREAM(args, 0);
        if(ucBssid)
        {
            ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
        }
        else
        {
            ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
        }
        args = UINT32_TO_STREAM(args, ulPriority);
        args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
        args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
        args = UINT32_TO_STREAM(args, ulKeyMgmt);
        args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen);
        args = UINT32_TO_STREAM(args, ulPassPhraseLen);
        ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
        ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen);

        arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen;
    }

    break;
    }

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE,
                     ptr, arg_len);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);

    return(ret);
}
Beispiel #6
0
/*******************************************************************************
**
** Function         hw_config_cback
**
** Description      Callback function for controller configuration
**
** Returns          None
**
*******************************************************************************/
void hw_config_cback(void *p_mem)
{
    HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    char        *p_name, *p_tmp;
    uint8_t     *p, status;
    uint16_t    opcode;
    HC_BT_HDR  *p_buf=NULL;
    uint8_t     is_proceeding = FALSE;
    int         i;
#if (USE_CONTROLLER_BDADDR == TRUE)
    const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
#endif

    status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
    p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
    STREAM_TO_UINT16(opcode,p);

    /* Ask a new buffer big enough to hold any HCI commands sent in here */
    if ((status == 0) && bt_vendor_cbacks)
        p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
                                                       HCI_CMD_MAX_LEN);

	ALOGI("[Atmel %s] rcvd cb with state: %d!!,status:%d,op_code:%x",__func__, hw_cfg_cb.state,status,opcode);
	if (p_buf != NULL)
	{
		p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
		p_buf->offset = 0;
		p_buf->len = 0;
		p_buf->layer_specific = 0;

        p = (uint8_t *) (p_buf + 1);

        switch (hw_cfg_cb.state)
        {
            case HW_CFG_SET_UART_BAUD_1:
                /* update baud rate of host's UART port */
                ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
                userial_vendor_set_baud( \
                    line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
                );

                /* read local name */
                UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
                *p = 0; /* parameter length */

                p_buf->len = HCI_CMD_PREAMBLE_SIZE;
                hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;

                is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
                                                    p_buf, hw_config_cback);
                break;

            case HW_CFG_READ_LOCAL_NAME:
                p_tmp = p_name = (char *) (p_evt_buf + 1) + \
                         HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;

                for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++)
                    *(p_name+i) = toupper(*(p_name+i));

                if ((p_name = strstr(p_name, "BCM")) != NULL)
                {
                    strncpy(hw_cfg_cb.local_chip_name, p_name, \
                            LOCAL_NAME_BUFFER_LEN-1);
                }
                else
                {
                    strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \
                            LOCAL_NAME_BUFFER_LEN-1);
                    p_name = p_tmp;
                }

                hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0;

                BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name);

                if ((status = hw_config_findpatch(p_name)) == TRUE)
                {
                    if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1)
                    {
                        ALOGE("vendor lib preload failed to open [%s]", p_name);
                    }
                    else
                    {
                    #if 0
                        /* vsc_download_minidriver */
                        UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
                        *p = 0; /* parameter length */

                        p_buf->len = HCI_CMD_PREAMBLE_SIZE;
                        hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;

                        is_proceeding = bt_vendor_cbacks->xmit_cb( \
                                            HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
                                            hw_config_cback);
					#endif	
                    }
                }
                else
                {
                    ALOGE( \
                    "vendor lib preload failed to locate firmware patch file" \
                    );
                }

                if (is_proceeding == FALSE)
                {
                    //is_proceeding = hw_config_set_bdaddr(p_buf);
                }
                break;

            case HW_CFG_DL_MINIDRIVER:
                /* give time for placing firmware in download mode */
                ms_delay(50);
                hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
                /* fall through intentionally */
            case HW_CFG_DL_FW_PATCH:
                p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
                if (p_buf->len > 0)
                {
                #if 0
                    if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \
                        (opcode == HCI_VSC_LAUNCH_RAM))
                    {
                        ALOGW("firmware patch file might be altered!");
                    }
                    else
                    {
                        p_buf->len += read(hw_cfg_cb.fw_fd, \
                                           p+HCI_CMD_PREAMBLE_SIZE,\
                                           *(p+HCD_REC_PAYLOAD_LEN_BYTE));
                        STREAM_TO_UINT16(opcode,p);
                        is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
                                                p_buf, hw_config_cback);
                        break;
                    }
				#endif
                }

                close(hw_cfg_cb.fw_fd);
                hw_cfg_cb.fw_fd = -1;

                /* Normally the firmware patch configuration file
                 * sets the new starting baud rate at 115200.
                 * So, we need update host's baud rate accordingly.
                 */
                ALOGI("bt vendor lib: set UART baud 115200");
                userial_vendor_set_baud(USERIAL_BAUD_115200);

                /* Next, we would like to boost baud rate up again
                 * to desired working speed.
                 */
                hw_cfg_cb.f_set_baud_2 = TRUE;

                /* Check if we need to pause a few hundred milliseconds
                 * before sending down any HCI command.
                 */
                ms_delay(look_up_fw_settlement_delay());

                /* fall through intentionally */
            case HW_CFG_START:
                if (UART_TARGET_BAUD_RATE > 3000000)
                {
                #if 1
                    /* set UART clock to 48MHz */
                    UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
                    *p++ = 1; /* parameter length */
                    *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */

                    p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1;
                    hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;

                    is_proceeding = bt_vendor_cbacks->xmit_cb( \
                                        HCI_VSC_WRITE_UART_CLOCK_SETTING, \
                                        p_buf, hw_config_cback);
                    break;
				#endif
                }
                /* fall through intentionally */
            case HW_CFG_SET_UART_CLOCK:
                /* set controller's UART baud rate to 3M */
                UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
                *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
                *p++ = 0; /* encoded baud rate */
                *p++ = 0; /* use encoded form */
                UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);

                p_buf->len = HCI_CMD_PREAMBLE_SIZE + \
                             UPDATE_BAUDRATE_CMD_PARAM_SIZE;
                hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
                            HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;

                is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
                                                    p_buf, hw_config_cback);
                break;

            case HW_CFG_SET_UART_BAUD_2:
                /* update baud rate of host's UART port */
                ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
                userial_vendor_set_baud( \
                    line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
                );

#if (USE_CONTROLLER_BDADDR == TRUE)
                if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
                    break;
#else
               // if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
                //    break;
#endif
                /* fall through intentionally */
            case HW_CFG_SET_BD_ADDR:
                ALOGI("vendor lib fwcfg completed");
                bt_vendor_cbacks->dealloc(p_buf);
                bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);

                hw_cfg_cb.state = 0;

                if (hw_cfg_cb.fw_fd != -1)
                {
                    close(hw_cfg_cb.fw_fd);
                    hw_cfg_cb.fw_fd = -1;
                }

                is_proceeding = TRUE;
                break;

#if (USE_CONTROLLER_BDADDR == TRUE)
            case HW_CFG_READ_BD_ADDR:
                p_tmp = (char *) (p_evt_buf + 1) + \
                         HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY;

                if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0)
                {
                    // Controller does not have a valid OTP BDADDR!
                    // Set the BTIF initial BDADDR instead.
                   // if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
                   //     break;
                }
                else
                {
                    ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X",
                        *(p_tmp+5), *(p_tmp+4), *(p_tmp+3),
                        *(p_tmp+2), *(p_tmp+1), *p_tmp);
                }

                ALOGI("vendor lib fwcfg completed");
                bt_vendor_cbacks->dealloc(p_buf);
                bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);

				hw_cfg_cb.state = 0;

                if (hw_cfg_cb.fw_fd != -1)
                {
                    close(hw_cfg_cb.fw_fd);
                    hw_cfg_cb.fw_fd = -1;
                }

                is_proceeding = TRUE;
                break;
#endif // (USE_CONTROLLER_BDADDR == TRUE)
        } // switch(hw_cfg_cb.state)
    } // if (p_buf != NULL)

    /* Free the RX event buffer */
    if (bt_vendor_cbacks)
        bt_vendor_cbacks->dealloc(p_evt_buf);

    if (is_proceeding == FALSE)
    {
        ALOGE("vendor lib fwcfg aborted!!!");
        if (bt_vendor_cbacks)
        {
            if (p_buf != NULL)
                bt_vendor_cbacks->dealloc(p_buf);

            bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
        }

        if (hw_cfg_cb.fw_fd != -1)
        {
            close(hw_cfg_cb.fw_fd);
            hw_cfg_cb.fw_fd = -1;
        }

        hw_cfg_cb.state = 0;
    }
}
Beispiel #7
0
static void reassemble_and_dispatch(BT_HDR *packet)
{
    LOG_DEBUG("reassemble_and_dispatch\n");

    if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {
        uint8_t *stream = packet->data + packet->offset;
        uint16_t handle;
        uint16_t l2cap_length;
        uint16_t acl_length;

        STREAM_TO_UINT16(handle, stream);
        STREAM_TO_UINT16(acl_length, stream);
        STREAM_TO_UINT16(l2cap_length, stream);

        assert(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);

        uint8_t boundary_flag = GET_BOUNDARY_FLAG(handle);
        handle = handle & HANDLE_MASK;

        BT_HDR *partial_packet = (BT_HDR *)hash_map_get(partial_packets, (void *)(uintptr_t)handle);

        if (boundary_flag == START_PACKET_BOUNDARY) {
            if (partial_packet) {
                LOG_WARN("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__);
                hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
                buffer_allocator->free(partial_packet);
            }

            uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
            if (full_length <= packet->len) {
                if (full_length < packet->len) {
                    LOG_WARN("%s found l2cap full length %d less than the hci length %d.\n", __func__, l2cap_length, packet->len);
                }

                callbacks->reassembled(packet);
                return;
            }

            partial_packet = (BT_HDR *)buffer_allocator->alloc(full_length + sizeof(BT_HDR));
            partial_packet->event = packet->event;
            partial_packet->len = full_length;
            partial_packet->offset = packet->len;

            memcpy(partial_packet->data, packet->data + packet->offset, packet->len);

            // Update the ACL data size to indicate the full expected length
            stream = partial_packet->data;
            STREAM_SKIP_UINT16(stream); // skip the handle
            UINT16_TO_STREAM(stream, full_length - HCI_ACL_PREAMBLE_SIZE);

            hash_map_set(partial_packets, (void *)(uintptr_t)handle, partial_packet);
            // Free the old packet buffer, since we don't need it anymore
            buffer_allocator->free(packet);
        } else {
            if (!partial_packet) {
                LOG_ERROR("%s got continuation for unknown packet. Dropping it.\n", __func__);
                buffer_allocator->free(packet);
                return;
            }

            packet->offset += HCI_ACL_PREAMBLE_SIZE; // skip ACL preamble
            packet->len -= HCI_ACL_PREAMBLE_SIZE;
            uint16_t projected_offset = partial_packet->offset + packet->len;
            if (projected_offset > partial_packet->len) { // len stores the expected length
                LOG_ERROR("%s got packet which would exceed expected length of %d. Truncating.\n", __func__, partial_packet->len);
                packet->len = partial_packet->len - partial_packet->offset;
                projected_offset = partial_packet->len;
            }

            memcpy(
                partial_packet->data + partial_packet->offset,
                packet->data + packet->offset,
                packet->len
            );

            // Free the old packet buffer, since we don't need it anymore
            buffer_allocator->free(packet);
            partial_packet->offset = projected_offset;

            if (partial_packet->offset == partial_packet->len) {
                hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
                partial_packet->offset = 0;
                callbacks->reassembled(partial_packet);
            }
        }
    } else {
        callbacks->reassembled(packet);
    }
}
Beispiel #8
0
/*******************************************************************************
 **
 ** Function         btusb_lite_hci_write_acl_header
 **
 ** Description      Write HCI ACL Header (HCI_Type, Connection Handle, Length)
 **
 ** Returns          New buffer location
 **
 *******************************************************************************/
static UINT8 *btusb_lite_hci_write_acl_header(UINT8 *p_data, UINT16 con_hdl, UINT16 length)
{
    UINT16_TO_STREAM(p_data, con_hdl);              /* Connection Handle */
    UINT16_TO_STREAM(p_data, length);               /* Length */
    return p_data;
}
Beispiel #9
0
/*******************************************************************************
 **
 ** Function        btusb_lite_hci_nocp_event_hdlr
 **
 ** Description     Check if the received HCI Event is A NumberOfdComplete Evt
 **                 sub opcode for a Started BAV stream.
 **
 ** Returns         status: <> 0 if the event must be send to user space (BSA)
 **                         0 if the event is handled
 **
 *******************************************************************************/
static int btusb_lite_hci_nocp_event_hdlr(struct btusb *p_dev, UINT8 *p_data, int length)
{
    UINT8 nb_handle;
    UINT16 con_hdl;
    UINT16 num_cplt_pck;
    UINT8 byte;
    UINT8 *p_save;
    int send_to_user;
    UINT16 num_cplt_pck_caugth;

    /* We are waiting for an Event of, at least, 7 bytes */
    if (length < BTUSB_LITE_HCI_NOCP_HCI_LEN)
    {
        return 1;   /* This is not a NOCP. Send this event to user space */
    }

    /* Extract Event */
    STREAM_TO_UINT8(byte, p_data);

    /* Check if it's a NumberOfCompletePacket Event */
    if (byte != HCI_NUM_COMPL_DATA_PKTS_EVT)
    {
        return 1;   /* This is not a NOCP. Send this event to user space */
    }

    /* Extract Parameter Length */
    STREAM_TO_UINT8(byte, p_data);

    /* Extract Number Of Handle */
    STREAM_TO_UINT8(nb_handle, p_data);

    /* Sanity */
    if (byte != (1 + (2 + 2) * nb_handle))
    {
        BTUSB_ERR("Unexpected Evt Size=%d vs.NumberOfHandle=%d\n", byte, nb_handle);
        return 1;   /* This is not a NOCP. Send this event to user space */
    }

    send_to_user = 0;         /* For the moment, no Complete Packet sent to user */

    /* For every Handle */
    while(nb_handle--)
    {
        /* Extract the Connection Handle */
        STREAM_TO_UINT16(con_hdl, p_data);

        /* Save the current pointer position (to overwrite number of packet) */
        p_save = p_data;

        /* Extract the Number Of Complete Packet */
        STREAM_TO_UINT16(num_cplt_pck, p_data);

        /* Call the L2CAP NumberOfcompletePacket Handler */
        num_cplt_pck_caugth = btusb_lite_l2c_nocp_hdlr(p_dev, con_hdl, num_cplt_pck);

        /* If L2CAP "caught"at least one nocp packet */
        if (num_cplt_pck_caugth)
        {
            /* Overwrite the Number Of Complete Packet */
            UINT16_TO_STREAM(p_save, num_cplt_pck - num_cplt_pck_caugth);

            /* If at least one Number Of Complete Packet remains */
            if (num_cplt_pck - num_cplt_pck_caugth)
            {
                /* Send the event to user space */
                send_to_user = 1;
            }
        }
        else
        {
            /* Don't update the number but send the event to user space */
            send_to_user = 1;
        }
    }

    return send_to_user;
}
Beispiel #10
0
/*******************************************************************************
 **
 ** Function        btusb_lite_hci_event_filter
 **
 ** Description     Filter HCI Events received from BT Controller.
 **
 ** Returns         status: <> 0 if the event must be send to user space (BSA)
 **                         0 if the event is handled
 **
 *******************************************************************************/
int btusb_lite_hci_event_filter(struct btusb *p_dev, UINT8 *p_data, int length)
{
#if 0
    BT_HDR *p_msg;
    UINT8 *p;
    UINT16 size;
#endif

    /* Check if HCI is over IPC */
    if (btusb_lite_is_hci_over_ipc(p_dev) == 0)
    {
        /* If it is not, the event have to be sent through regular HCI */
        return 1;
    }

    /* Check if the Event is a NumberOfCompletePacket Event */
    if (btusb_lite_hci_nocp_event_hdlr(p_dev, p_data, length) == 0)
    {
        return 0;  /* Do not Send this event to user space (we handled it) */
    }

    /* TODO: check if CSB VSE */

    return 1;

#if 0

    /* Add size of both UIPC Length and Event header */
    size = length + sizeof(UINT16) + sizeof(UINT16);

    /* Get a buffer from the pool */
    p_msg = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + size);
    if(unlikely(p_msg == NULL))
    {
        BTUSB_ERR("Unable to get GKI buffer\n");
        return 0;
    }

    if (unlikely(dbgflags & BTUSB_GKI_CHK_MSG) &&
        unlikely(GKI_buffer_status(p_msg) != BUF_STATUS_UNLINKED))
    {
        BTUSB_ERR("buffer != BUF_STATUS_UNLINKED 0x%p\n", p_msg);
        return;
    }

    p_msg->offset = 0;
    p_msg->event = 0;
    p_msg->len = size;

    p = (UINT8 *)(p_msg + 1) + p_msg->offset;

    UINT16_TO_STREAM(p, length + sizeof(UINT16));   /* UIPC Length */
    UINT16_TO_STREAM(p, BT_EVT_TO_BTU_HCI_EVT);     /* UIPC Event */
    UINT8_TO_STREAM(p, hci_event);  /* Write back the HCI Event (we already read it) */
    ARRAY_TO_STREAM(p, p_data, length - 1);         /* Copy Event data */

    /* Send message to User Space */
    btusb_lite_ipc_sent_to_user(p_dev, p_msg);

    return 0;   /* Event handled by the Stack Lite. No need to send it to HCI */
#endif
}
Beispiel #11
0
int32_t cc3000_wlan::add_profile(uint32_t sec_type,
                      uint8_t* ssid,
                      uint32_t ssid_length,
                      uint8_t *b_ssid,
                      uint32_t priority,
                      uint32_t pairwise_cipher_or_tx_key_len,
                      uint32_t group_cipher_tx_key_index,
                      uint32_t key_mgmt,
                      uint8_t* pf_or_key,
                      uint32_t pass_phrase_len) {
    uint16_t arg_len = 0x00;
    int32_t ret;
    uint8_t *ptr;
    int32_t i = 0;
    uint8_t *args;
    uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ptr = _simple_link.get_transmit_buffer();
    args = (ptr + HEADERS_SIZE_CMD);

    args = UINT32_TO_STREAM(args, sec_type);

    // Setup arguments in accordance with the security type
    switch (sec_type)
    {
        //OPEN
    case WLAN_SEC_UNSEC:
        {
            args = UINT32_TO_STREAM(args, 0x00000014);
            args = UINT32_TO_STREAM(args, ssid_length);
            args = UINT16_TO_STREAM(args, 0);
            if(b_ssid)
            {
                ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, priority);
            ARRAY_TO_STREAM(args, ssid, ssid_length);

            arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length;
        }
        break;

        //WEP
    case WLAN_SEC_WEP:
        {
            args = UINT32_TO_STREAM(args, 0x00000020);
            args = UINT32_TO_STREAM(args, ssid_length);
            args = UINT16_TO_STREAM(args, 0);
            if(b_ssid)
            {
                ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, priority);
            args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length);
            args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
            args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
            ARRAY_TO_STREAM(args, ssid, ssid_length);

            for(i = 0; i < 4; i++)
            {
                uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len];

                ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len);
            }

            arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length +
                pairwise_cipher_or_tx_key_len * 4;

        }
        break;

        //WPA
        //WPA2
    case WLAN_SEC_WPA:
    case WLAN_SEC_WPA2:
        {
            args = UINT32_TO_STREAM(args, 0x00000028);
            args = UINT32_TO_STREAM(args, ssid_length);
            args = UINT16_TO_STREAM(args, 0);
            if(b_ssid)
            {
                ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, priority);
            args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
            args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
            args = UINT32_TO_STREAM(args, key_mgmt);
            args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length);
            args = UINT32_TO_STREAM(args, pass_phrase_len);
            ARRAY_TO_STREAM(args, ssid, ssid_length);
            ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len);

            arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len;
        }

        break;
    }

    // Initiate a HCI command
    _hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len);

    // Wait for command complete event
    _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);

    return(ret);
}
Beispiel #12
0
//*****************************************************************************
//
//!  Initiate an HCI Patch Transfer.
//!
//!  \param  usOpcode     command operation code
//!  \param  ucArgs       pointer to the command's arguments buffer
//!  \param  ucArgsLength length of the arguments
//!
//!  \return              ESUCCESS if command transfer complete,EFAIL otherwise.
//!
//!  \brief               Initiate an HCI cmnd.
//
//*****************************************************************************
void
hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength)
{ 
 	unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE);
	unsigned short usTransLength;

	unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
	
	UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
	UINT8_TO_STREAM(stream, ucOpcode);
	stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);

	
	

	if (usDataLength <= SL_PATCH_PORTION_SIZE)
	{
		UINT16_TO_STREAM(stream, usDataLength);
		stream = UINT16_TO_STREAM(stream, usDataLength);
		
		
		
		memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength);

		
		//
		// Update the opcode of the event we will be waiting for
		//
		SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE);
	}
	else
	{
		
        usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE);
		UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
	    stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
		
		
		memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE);
		usDataLength -= SL_PATCH_PORTION_SIZE;
		patch += SL_PATCH_PORTION_SIZE;
		
		//
		// Update the opcode of the event we will be waiting for
		//
		SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);

		while (usDataLength)
		{
			if (usDataLength <= SL_PATCH_PORTION_SIZE)
			{
				usTransLength = usDataLength;
				usDataLength = 0;
				
			}
			else
			{
				usTransLength = SL_PATCH_PORTION_SIZE;
				usDataLength -= usTransLength;
			}

			*(unsigned short *)data_ptr = usTransLength;
			memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
			patch += usTransLength;

			 //
			 // Update the opcode of the event we will be waiting for
			 //
		    SpiWrite((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength));
		}
	}
}
Beispiel #13
0
/*******************************************************************************
 **
 ** Function        app_3dtv_set_beacon
 **
 ** Description     Configure 3DTV Beacon parameters (Broadcasted)
 **
 ** Parameters      p_req: pointer to the tAPP_3DTV_SET_BEACON
 **
 ** Returns         0 if successful, -1 in case of error
 **
 *******************************************************************************/
int app_3dtv_set_beacon(tAPP_3DTV_SET_BEACON *p_req)
{
    tBSA_TM_VSC bsa_vsc;
    tBSA_STATUS bsa_status;
    UINT8 *p_data;

    if (p_req == NULL)
    {
        APP_ERROR0("Null p_req parameter");
        return -1;
    }

    APP_DEBUG1("LeftOpen:%d LeftClose:%d RightOpen:%d RightClose:%d Delay:%d",
            p_req->left_open, p_req->left_close,
            p_req->right_open, p_req->right_close,
            p_req->delay);

    /* Prepare VSC Parameters */
    bsa_status = BSA_TmVscInit(&bsa_vsc);
    bsa_vsc.opcode = BRCM_HCI_VSC_3D_SET_OFFSET; /* 3D Offset and Delay */
    p_data = bsa_vsc.data;
#ifdef APP_3DTV_OLD_OFFSET_VSC
    bsa_vsc.length = sizeof(UINT16) * 5; /* 5 words of 16 bits */
    UINT16_TO_STREAM(p_data, p_req->left_open);
    UINT16_TO_STREAM(p_data, p_req->left_close);
    UINT16_TO_STREAM(p_data, p_req->right_open);
    UINT16_TO_STREAM(p_data, p_req->right_close);
    UINT16_TO_STREAM(p_data, p_req->delay);
#else
    APP_DEBUG1("DisplayId:%d DualView:%d", p_req->display_id, p_req->dual_view_mode);

    bsa_vsc.length = 12;

    /* DisplayId */
    UINT8_TO_STREAM(p_data, p_req->display_id);

    /* Left Open Offset */
    UINT16_TO_STREAM(p_data, p_req->left_open);

    /* Left Close Offset */
    UINT16_TO_STREAM(p_data, p_req->left_close);

    /* Right Open Offset */
    UINT16_TO_STREAM(p_data, p_req->right_open);

    /* Right Close Offset */
    UINT16_TO_STREAM(p_data, p_req->right_close);

    /* Delay */
    UINT16_TO_STREAM(p_data, p_req->delay);

    /* DualView */
    UINT8_TO_STREAM(p_data, p_req->dual_view_mode);

#endif
    bsa_status = BSA_TmVsc(&bsa_vsc);
    if (bsa_status != BSA_SUCCESS)
    {
        APP_ERROR1("BSA_TmVsc failed status:%d", bsa_status);
        return(-1);
    }

    if ((bsa_vsc.status != BSA_SUCCESS) || (bsa_vsc.data[0] != HCI_SUCCESS))
    {
        APP_ERROR1("Unable to Set 3D offsets status:%d hic_status:%d",
                bsa_vsc.status, bsa_vsc.data[0]);
        return -1;
    }
    return 0;
}
Beispiel #14
0
/*******************************************************************************
**   DIS Attributes Database Server Request callback
*******************************************************************************/
UINT8 dis_read_attr_value (UINT8 clcb_idx, UINT16 handle, tGATT_VALUE *p_value,
                           BOOLEAN is_long, tGATT_STATUS *p_status)
{
    tDIS_DB_ENTRY   *p_db_attr = dis_cb.dis_attr;
    UINT8           *p = p_value->value, i, *pp;
    UINT16          offset = p_value->offset;
    UINT8           act = SRVC_ACT_RSP;
    tGATT_STATUS    st = GATT_NOT_FOUND;
    UNUSED(clcb_idx);

    for (i = 0; i < DIS_MAX_CHAR_NUM; i ++, p_db_attr ++)
    {
        if (handle == p_db_attr->handle)
        {
            if ((p_db_attr->uuid == GATT_UUID_PNP_ID || p_db_attr->uuid == GATT_UUID_SYSTEM_ID)&&
                is_long == TRUE)
            {
                st = GATT_NOT_LONG;
                break;
            }
            st = GATT_SUCCESS;

            switch (p_db_attr->uuid)
            {
                case GATT_UUID_MANU_NAME:
                case GATT_UUID_MODEL_NUMBER_STR:
                case GATT_UUID_SERIAL_NUMBER_STR:
                case GATT_UUID_FW_VERSION_STR:
                case GATT_UUID_HW_VERSION_STR:
                case GATT_UUID_SW_VERSION_STR:
                case GATT_UUID_IEEE_DATA:
                    pp = dis_cb.dis_value.data_string[p_db_attr->uuid - GATT_UUID_MODEL_NUMBER_STR];
                    if (pp != NULL)
                    {
                        if (strlen ((char *)pp) > GATT_MAX_ATTR_LEN)
                            p_value->len = GATT_MAX_ATTR_LEN;
                        else
                            p_value->len = (UINT16)strlen ((char *)pp);
                    }
                    else
                        p_value->len = 0;

                    if (offset > p_value->len)
                    {
                        st = GATT_INVALID_OFFSET;
                        break;
                    }
                    else
                    {
                        p_value->len -= offset;
                        pp += offset;
                        ARRAY_TO_STREAM(p, pp, p_value->len);
                        GATT_TRACE_EVENT("GATT_UUID_MANU_NAME len=0x%04x", p_value->len);
                    }
                    break;

                case GATT_UUID_SYSTEM_ID:
                    UINT64_TO_STREAM(p, dis_cb.dis_value.system_id); /* int_min */
                    p_value->len = DIS_SYSTEM_ID_SIZE;
                    break;

                case  GATT_UUID_PNP_ID:
                    UINT8_TO_STREAM(p, dis_cb.dis_value.pnp_id.vendor_id_src);
                    UINT16_TO_STREAM(p, dis_cb.dis_value.pnp_id.vendor_id);
                    UINT16_TO_STREAM(p, dis_cb.dis_value.pnp_id.product_id);
                    UINT16_TO_STREAM(p, dis_cb.dis_value.pnp_id.product_version);
                    p_value->len = DIS_PNP_ID_SIZE;
                    break;

            }
            break;
        }
    }
    *p_status = st;
    return act;
}