1dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie/******************************************************************************
2dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
3dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  Copyright (C) 1999-2013 Broadcom Corporation
4dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
5dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  Licensed under the Apache License, Version 2.0 (the "License");
6dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  you may not use this file except in compliance with the License.
7dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  You may obtain a copy of the License at:
8dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
9dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  http://www.apache.org/licenses/LICENSE-2.0
10dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
11dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  Unless required by applicable law or agreed to in writing, software
12dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  distributed under the License is distributed on an "AS IS" BASIS,
13dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  See the License for the specific language governing permissions and
15dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *  limitations under the License.
16dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie *
17dbba0e652e0ce23dd691df3c03979ec6e32c8db3Matthew Xie ******************************************************************************/
182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "bt_target.h"
202e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "gatt_api.h"
222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "gatt_int.h"
232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "srvc_eng_int.h"
242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#include "srvc_dis_int.h"
252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#if BLE_INCLUDED == TRUE
272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define DIS_UUID_TO_ATTR_MASK(x)   (UINT16)(1 << ((x) - GATT_UUID_SYSTEM_ID))
292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
302e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define DIS_MAX_NUM_INC_SVR       0
312e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define DIS_MAX_CHAR_NUM          9
322e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define DIS_MAX_ATTR_NUM          (DIS_MAX_CHAR_NUM * 2 + DIS_MAX_NUM_INC_SVR + 1)
332e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
342e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#ifndef DIS_ATTR_DB_SIZE
352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define DIS_ATTR_DB_SIZE      GATT_DB_MEM_SIZE(DIS_MAX_NUM_INC_SVR, DIS_MAX_CHAR_NUM, 0)
362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#endif
372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
382e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define UINT64_TO_STREAM(p, u64) {*(p)++ = (UINT8)(u64);       *(p)++ = (UINT8)((u64) >> 8);*(p)++ = (UINT8)((u64) >> 16); *(p)++ = (UINT8)((u64) >> 24); \
392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                                    *(p)++ = (UINT8)((u64) >> 32); *(p)++ = (UINT8)((u64) >> 40);*(p)++ = (UINT8)((u64) >> 48); *(p)++ = (UINT8)((u64) >> 56);}
402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#define STREAM_TO_UINT64(u64, p) {u64 = (((UINT64)(*(p))) + ((((UINT64)(*((p) + 1)))) << 8) + ((((UINT64)(*((p) + 2)))) << 16) + ((((UINT64)(*((p) + 3)))) << 24) \
422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                                  + ((((UINT64)(*((p) + 4)))) << 32) + ((((UINT64)(*((p) + 5)))) << 40) + ((((UINT64)(*((p) + 6)))) << 48) + ((((UINT64)(*((p) + 7)))) << 56)); (p) += 8;}
432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
462e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbachstatic const UINT16  dis_attr_uuid[DIS_MAX_CHAR_NUM] =
472e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_SYSTEM_ID,
492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_MODEL_NUMBER_STR,
502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_SERIAL_NUMBER_STR,
512e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_FW_VERSION_STR,
522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_HW_VERSION_STR,
532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_SW_VERSION_STR,
542e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_MANU_NAME,
552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_IEEE_DATA,
562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_UUID_PNP_ID
572e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach};
582e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
592e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachtDIS_CB dis_cb;
602e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
612e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**   dis_valid_handle_range
622e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
632e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**   validate a handle to be a DIS attribute handle or not.
642e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
652e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachBOOLEAN dis_valid_handle_range(UINT16 handle)
662e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (handle >= dis_cb.service_handle && handle <= dis_cb.max_handle)
682e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return TRUE;
692e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    else
702e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return FALSE;
712e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
722e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
732e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**   dis_write_attr_value
742e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
752e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**   Process write DIS attribute request.
762e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
772e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachUINT8 dis_write_attr_value(tGATT_WRITE_REQ * p_data, tGATT_STATUS *p_status)
782e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
792e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    *p_status = GATT_WRITE_NOT_PERMIT;
802e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    return SRVC_ACT_RSP;
812e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
822e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
832e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**   DIS Attributes Database Server Request callback
842e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
852e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachUINT8 dis_read_attr_value (UINT8 clcb_idx, UINT16 handle, tGATT_VALUE *p_value,
862e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                           BOOLEAN is_long, tGATT_STATUS *p_status)
872e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
882e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tDIS_DB_ENTRY   *p_db_attr = dis_cb.dis_attr;
892e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT8           *p = p_value->value, i, *pp;
902e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT16          offset = p_value->offset;
912e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT8           act = SRVC_ACT_RSP;
922e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tGATT_STATUS    st = GATT_NOT_FOUND;
932e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
942e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    for (i = 0; i < DIS_MAX_CHAR_NUM; i ++, p_db_attr ++)
952e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
962e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        if (handle == p_db_attr->handle)
972e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        {
982e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            if ((p_db_attr->uuid == GATT_UUID_PNP_ID || p_db_attr->uuid == GATT_UUID_SYSTEM_ID)&&
992e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                is_long == TRUE)
1002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            {
1012e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                st = GATT_NOT_LONG;
1022e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                break;
1032e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            }
1042e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            st = GATT_SUCCESS;
1052e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1062e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            switch (p_db_attr->uuid)
1072e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            {
1082e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_MANU_NAME:
1092e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_MODEL_NUMBER_STR:
1102e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_SERIAL_NUMBER_STR:
1112e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_FW_VERSION_STR:
1122e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_HW_VERSION_STR:
1132e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_SW_VERSION_STR:
1142e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_IEEE_DATA:
1152e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    pp = dis_cb.dis_value.data_string[p_db_attr->uuid - GATT_UUID_MODEL_NUMBER_STR];
1162e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    if (pp != NULL)
1172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    {
1182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        if (strlen ((char *)pp) > GATT_MAX_ATTR_LEN)
1192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                            p_value->len = GATT_MAX_ATTR_LEN;
1202e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        else
1212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                            p_value->len = (UINT16)strlen ((char *)pp);
1222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    }
1232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    else
1242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        p_value->len = 0;
1252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    if (offset > p_value->len)
1272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    {
1282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        st = GATT_INVALID_OFFSET;
1292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        break;
1302e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    }
1312e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    else
1322e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    {
1332e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        p_value->len -= offset;
1342e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        pp += offset;
1352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        ARRAY_TO_STREAM(p, pp, p_value->len);
1362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        GATT_TRACE_EVENT1("GATT_UUID_MANU_NAME len=0x%04x", p_value->len);
1372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    }
1382e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    break;
1392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case GATT_UUID_SYSTEM_ID:
1422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    UINT64_TO_STREAM(p, dis_cb.dis_value.system_id); /* int_min */
1432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    p_value->len = DIS_SYSTEM_ID_SIZE;
1442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    break;
1452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1462e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                case  GATT_UUID_PNP_ID:
1472e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    UINT8_TO_STREAM(p, dis_cb.dis_value.pnp_id.vendor_id_src);
1482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    UINT16_TO_STREAM(p, dis_cb.dis_value.pnp_id.vendor_id);
1492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    UINT16_TO_STREAM(p, dis_cb.dis_value.pnp_id.product_id);
1502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    UINT16_TO_STREAM(p, dis_cb.dis_value.pnp_id.product_version);
1512e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    p_value->len = DIS_PNP_ID_SIZE;
1522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    break;
1532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1542e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            }
1552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            break;
1562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        }
1572e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
1582e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    *p_status = st;
1592e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    return act;
1602e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
1612e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1622e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
1632e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1642e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Function         dis_gatt_c_read_dis_value_cmpl
1652e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1662e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Description      Client read DIS database complete callback.
1672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1682e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Returns          void
1692e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1702e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
1712e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbachvoid dis_gatt_c_read_dis_value_cmpl(UINT16 conn_id)
1722e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
1732e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tSRVC_CLCB *p_clcb =  srvc_eng_find_clcb_by_conn_id(conn_id);
1742e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1752e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.dis_read_uuid_idx = 0xff;
1762e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1772e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    srvc_eng_release_channel(conn_id);
1782e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1792e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (dis_cb.p_read_dis_cback && p_clcb)
1802e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
1812e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        GATT_TRACE_ERROR1("dis_gatt_c_read_dis_value_cmpl: attr_mask = 0x%04x", p_clcb->dis_value.attr_mask);
1822e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        GATT_TRACE_EVENT0("calling p_read_dis_cbackd");
1832e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1842e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        (*dis_cb.p_read_dis_cback)(p_clcb->bda, &p_clcb->dis_value);
1852e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_cb.p_read_dis_cback=NULL;
1862e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
1872e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1882e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
1892e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
1902e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
1912e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1922e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Function         dis_gatt_c_read_dis_req
1932e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1942e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Description      Read remote device DIS attribute request.
1952e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1962e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Returns          void
1972e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
1982e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
1992e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachBOOLEAN dis_gatt_c_read_dis_req(UINT16 conn_id)
2002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
2012e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tGATT_READ_PARAM   param;
2022e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2032e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    memset(&param, 0, sizeof(tGATT_READ_PARAM));
2042e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2052e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    param.service.uuid.len       = LEN_UUID_16;
2062e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    param.service.s_handle       = 1;
2072e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    param.service.e_handle       = 0xFFFF;
2082e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    param.service.auth_req       = 0;
2092e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2102e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    while (dis_cb.dis_read_uuid_idx < DIS_MAX_CHAR_NUM)
2112e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
2122e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        param.service.uuid.uu.uuid16 = dis_attr_uuid[dis_cb.dis_read_uuid_idx];
2132e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2142e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, &param) == GATT_SUCCESS)
2152e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        {
2162e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            return(TRUE);
2172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        }
2182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        else
2192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        {
2202e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            GATT_TRACE_ERROR1 ("Read DISInfo: 0x%04x GATT_Read Failed", param.service.uuid.uu.uuid16);
2212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            dis_cb.dis_read_uuid_idx ++;
2222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        }
2232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
2242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_gatt_c_read_dis_value_cmpl(conn_id);
2262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    return(FALSE);
2282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
2292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2302e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
2312e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
2322e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Function         dis_c_cmpl_cback
2332e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
2342e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Description      Client operation complete callback.
2352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
2362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Returns          void
2372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
2382e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
2392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbachvoid dis_c_cmpl_cback (tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op,
2402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                              tGATT_STATUS status, tGATT_CL_COMPLETE *p_data)
2412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
2422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT16      read_type = dis_attr_uuid[dis_cb.dis_read_uuid_idx];
2432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT8       *pp = NULL, *p_str;
2442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT16      conn_id = p_clcb->conn_id;
2452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2462e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_TRACE_EVENT3 ("dis_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x  \
2472e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                        read_type: 0x%04x", op, status, read_type);
2482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (op != GATTC_OPTYPE_READ)
2502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return;
2512e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (p_data != NULL && status == GATT_SUCCESS)
2532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
2542e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        pp = p_data->att_value.value;
2552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        switch (read_type)
2572e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        {
2582e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_SYSTEM_ID:
2592e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                GATT_TRACE_EVENT0 ("DIS_ATTR_SYS_ID_BIT");
2602e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                if (p_data->att_value.len == DIS_SYSTEM_ID_SIZE)
2612e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                {
2622e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    p_clcb->dis_value.attr_mask |= DIS_ATTR_SYS_ID_BIT;
2632e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    /* save system ID*/
2642e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    STREAM_TO_UINT64 (p_clcb->dis_value.system_id, pp);
2652e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                }
2662e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                break;
2672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2682e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_PNP_ID:
2692e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                if (p_data->att_value.len == DIS_PNP_ID_SIZE)
2702e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                {
2712e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    p_clcb->dis_value.attr_mask |= DIS_ATTR_PNP_ID_BIT;
2722e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    STREAM_TO_UINT8 (p_clcb->dis_value.pnp_id.vendor_id_src, pp);
2732e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    STREAM_TO_UINT16 (p_clcb->dis_value.pnp_id.vendor_id, pp);
2742e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    STREAM_TO_UINT16 (p_clcb->dis_value.pnp_id.product_id, pp);
2752e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    STREAM_TO_UINT16 (p_clcb->dis_value.pnp_id.product_version, pp);
2762e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                }
2772e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                break;
2782e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2792e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_MODEL_NUMBER_STR:
2802e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_SERIAL_NUMBER_STR:
2812e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_FW_VERSION_STR:
2822e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_HW_VERSION_STR:
2832e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_SW_VERSION_STR:
2842e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_MANU_NAME:
2852e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            case GATT_UUID_IEEE_DATA:
2862e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                p_str = p_clcb->dis_value.data_string[read_type - GATT_UUID_MODEL_NUMBER_STR];
2872e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                if (p_str != NULL)
2882e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    GKI_freebuf(p_str);
2892e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                if ((p_str = (UINT8 *)GKI_getbuf((UINT16)(p_data->att_value.len + 1))) != NULL)
2902e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                {
2912e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    memset(p_str, 0, p_data->att_value.len + 1);
2922e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    p_clcb->dis_value.attr_mask |= DIS_UUID_TO_ATTR_MASK (read_type);
2932e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    memcpy(p_str, p_data->att_value.value, p_data->att_value.len);
2942e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                }
2952e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                break;
2962e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
2972e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            default:
2982e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    break;
2992e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                break;
3012e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        }/* end switch */
3022e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }/* end if */
3032e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3042e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.dis_read_uuid_idx ++;
3052e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3062e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_gatt_c_read_dis_req(conn_id);
3072e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3082e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3092e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3102e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
3112e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
3122e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Function         DIS_SrInit
3132e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
3142e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Description      Initializa the Device Information Service Server.
3152e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
3162e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
3172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachtDIS_STATUS DIS_SrInit (tDIS_ATTR_MASK dis_attr_mask)
3182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
3192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tBT_UUID          uuid = {LEN_UUID_16, {UUID_SERVCLASS_DEVICE_INFO}};
3202e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT16            i = 0;
3212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tGATT_STATUS      status;
3222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tDIS_DB_ENTRY        *p_db_attr = &dis_cb.dis_attr[0];
3232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (dis_cb.enabled)
3252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
3262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        GATT_TRACE_ERROR0("DIS already initalized");
3272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return DIS_SUCCESS;
3282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
3292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3302e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    memset(&dis_cb, 0, sizeof(tDIS_CB));
3312e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3322e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.service_handle = GATTS_CreateService (srvc_eng_cb.gatt_if , &uuid, 0, DIS_MAX_ATTR_NUM, TRUE);
3332e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3342e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (dis_cb.service_handle == 0)
3352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
3362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        GATT_TRACE_ERROR0("Can not create service, DIS_Init failed!");
3372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return GATT_ERROR;
3382e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
3392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.max_handle = dis_cb.service_handle + DIS_MAX_ATTR_NUM;
3402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    while (dis_attr_mask != 0 && i < DIS_MAX_CHAR_NUM)
3422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
3432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        /* add Manufacturer name
3442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        */
3452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        uuid.uu.uuid16 = p_db_attr->uuid = dis_attr_uuid[i];
3462e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        p_db_attr->handle  = GATTS_AddCharacteristic(dis_cb.service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ);
3472e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        GATT_TRACE_DEBUG2 ("DIS_SrInit:  handle of new attribute 0x%04 = x%d", uuid.uu.uuid16, p_db_attr->handle  );
3482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        p_db_attr ++;
3492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        i ++;
3502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_attr_mask >>= 1;
3512e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
3522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    /* start service
3542e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    */
3552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    status = GATTS_StartService (srvc_eng_cb.gatt_if, dis_cb.service_handle, GATT_TRANSPORT_LE_BR_EDR);
3562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3572e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.enabled = TRUE;
3582e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3592e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    return (tDIS_STATUS) status;
3602e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
3612e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
3622e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
3632e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Function         DIS_SrUpdate
3642e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
3652e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Description      Update the DIS server attribute values
3662e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
3672e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
3682e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachtDIS_STATUS DIS_SrUpdate(tDIS_ATTR_BIT dis_attr_bit, tDIS_ATTR *p_info)
3692e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
3702e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT8           i = 1;
3712e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    tDIS_STATUS     st = DIS_SUCCESS;
3722e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3732e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (dis_attr_bit & DIS_ATTR_SYS_ID_BIT)
3742e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
3752e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_cb.dis_value.system_id = p_info->system_id;
3762e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
3772e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    else if (dis_attr_bit & DIS_ATTR_PNP_ID_BIT)
3782e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
3792e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_cb.dis_value.pnp_id.vendor_id         = p_info->pnp_id.vendor_id;
3802e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_cb.dis_value.pnp_id.vendor_id_src     = p_info->pnp_id.vendor_id_src;
3812e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_cb.dis_value.pnp_id.product_id        = p_info->pnp_id.product_id;
3822e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        dis_cb.dis_value.pnp_id.product_version   = p_info->pnp_id.product_version;
3832e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
3842e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    else
3852e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
3862e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        st = DIS_ILLEGAL_PARAM;
3872e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
3882e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        while (dis_attr_bit && i < (DIS_MAX_CHAR_NUM -1 ))
3892e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        {
3902e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            if (dis_attr_bit & (UINT16)(1 << i))
3912e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            {
3922e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                if (dis_cb.dis_value.data_string[i - 1] != NULL)
3932e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    GKI_freebuf(dis_cb.dis_value.data_string[i]);
3942e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/* coverity[OVERRUN-STATIC] False-positive : when i = 8, (1 << i) == DIS_ATTR_PNP_ID_BIT, and it will never come down here
3952e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachCID 49902: Out-of-bounds read (OVERRUN_STATIC)
3962e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachOverrunning static array "dis_cb.dis_value.data_string", with 7 elements, at position 7 with index variable "i".
3972e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*/
3982e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                if ((dis_cb.dis_value.data_string[i - 1] = (UINT8 *)GKI_getbuf((UINT16)(p_info->data_str.len + 1))) != NULL)
3992e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                {
4002e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    memset(dis_cb.dis_value.data_string[i - 1], 0, p_info->data_str.len + 1); /* make sure null terminate */
4012e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    memcpy(dis_cb.dis_value.data_string[i - 1], p_info->data_str.p_data, p_info->data_str.len);
4022e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    st = DIS_SUCCESS;
4032e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                }
4042e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                else
4052e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                    st = DIS_NO_RESOURCES;
4062e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4072e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                break;
4082e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            }
4092e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach            i ++;
4102e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        }
4112e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
4122e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    return st;
4132e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
4142e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach/*******************************************************************************
4152e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
4162e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Function         DIS_ReadDISInfo
4172e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
4182e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Description      Read remote device DIS information.
4192e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
4202e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach** Returns          void
4212e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach**
4222e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach*******************************************************************************/
4232e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre EisenbachBOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback)
4242e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach{
4252e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    UINT16             conn_id;
4262e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4272e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    /* For now we only handle one at a time */
4282e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (dis_cb.dis_read_uuid_idx != 0xff)
4292e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return(FALSE);
4302e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4312e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (p_cback == NULL)
4322e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return(FALSE);
4332e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4342e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.p_read_dis_cback = p_cback;
4352e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    /* Mark currently active operation */
4362e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    dis_cb.dis_read_uuid_idx = 0;
4372e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4382e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_TRACE_EVENT3 ("DIS_ReadDISInfo() - BDA: %08x%04x  cl_read_uuid: 0x%04x",
4392e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                      (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3],
4402e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach                      (peer_bda[4]<<8)+peer_bda[5], dis_attr_uuid[dis_cb.dis_read_uuid_idx]);
4412e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4422e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4432e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id);
4442e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4452e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    /* need to enhance it as multiple service is needed */
4462e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    srvc_eng_request_channel(peer_bda, SRVC_ID_DIS);
4472e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4482e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    if (conn_id == GATT_INVALID_CONN_ID)
4492e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    {
4502e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach        return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE);
4512e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    }
4522e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4532e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach    return dis_gatt_c_read_dis_req(conn_id);
4542e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4552e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach}
4562e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach#endif  /* BLE_INCLUDED */
4572e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
4582e7fa68bfd9723b7ec7b6b0b128d89f31a2e06eeAndre Eisenbach
459