| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794 | 
/** *  \file mesh_services.c * *  Generic Module to handle both *  - Mesh Provisioning Service :: 0x1827 *  - Mesh Proxy Service        :: 0x1828 *//* *  Copyright (C) 2018. Mindtree Limited. *  All rights reserved. */#include "mesh_services.h"/********************************************************************* * GLOBAL VARIABLES *//* Mesh Prov Service UUID: 0x1827 */CONST uint8 mesh_prov_UUID[ATT_BT_UUID_SIZE] ={  LO_UINT16(MESH_PROV_SERVICE_UUID), HI_UINT16(MESH_PROV_SERVICE_UUID)};/* Mesh Prov Data IN UUID: 0x2ADB */CONST uint8 mesh_prov_data_in_UUID[ATT_BT_UUID_SIZE] ={  LO_UINT16(MESH_PROV_DATA_IN_UUID), HI_UINT16(MESH_PROV_DATA_IN_UUID)};/* Mesh Prov Data OUT UUID: 0x2ADC */CONST uint8 mesh_prov_data_out_UUID[ATT_BT_UUID_SIZE] ={  LO_UINT16(MESH_PROV_DATA_OUT_UUID), HI_UINT16(MESH_PROV_DATA_OUT_UUID)};/* Mesh Proxy Service UUID: 0x1828 */CONST uint8 mesh_proxy_UUID[ATT_BT_UUID_SIZE] ={  LO_UINT16(MESH_PROXY_SERVICE_UUID), HI_UINT16(MESH_PROXY_SERVICE_UUID)};/* Mesh Proxy Data IN UUID: 0x2ADD */CONST uint8 mesh_proxy_data_in_UUID[ATT_BT_UUID_SIZE] ={  LO_UINT16(MESH_PROXY_DATA_IN_UUID), HI_UINT16(MESH_PROXY_DATA_IN_UUID)};/* Mesh Proxy Data OUT UUID: 0x2ADE */CONST uint8 mesh_proxy_data_out_UUID[ATT_BT_UUID_SIZE] ={  LO_UINT16(MESH_PROXY_DATA_OUT_UUID), HI_UINT16(MESH_PROXY_DATA_OUT_UUID)};/********************************************************************* * EXTERNAL VARIABLES *//********************************************************************* * EXTERNAL FUNCTIONS *//********************************************************************* * LOCAL VARIABLES *//* Mesh Provisioning Service Related Callbacks */static mesh_prov_cb   * prov_cb;/* Mesh Proxy Service Related Callbacks */static mesh_proxy_cb  * proxy_cb;/********************************************************************* * Profile Attributes - variables *//* Mesh Provisioning Service */static CONST gattAttrType_t mesh_prov_service =            {ATT_BT_UUID_SIZE, mesh_prov_UUID};/* Mesh Prov Data IN Properties */static uint8 mesh_prov_data_in_props = GATT_PROP_WRITE_NO_RSP;/* Mesh Prov Data IN Value */static uint8 mesh_prov_data_in_val[20];/* Mesh Prov Data OUT Properties */static uint8 mesh_prov_data_out_props = GATT_PROP_NOTIFY;/* Mesh Prov Data OUT Value */static uint8 mesh_prov_data_out_val[20];/* Mesh Prov Data OUT CCCD value array */static gattCharCfg_t mesh_prov_data_out_cccd[GATT_MAX_NUM_CONN];/* Mesh Proxy Service */static CONST gattAttrType_t mesh_proxy_service =            {ATT_BT_UUID_SIZE, mesh_proxy_UUID};/* Mesh Proxy Data IN Properties */static uint8 mesh_proxy_data_in_props = GATT_PROP_WRITE_NO_RSP;/* Mesh Proxy Data IN Value */static uint8 mesh_proxy_data_in_val[20];/* Mesh Proxy Data OUT Properties */static uint8 mesh_proxy_data_out_props = GATT_PROP_NOTIFY;/* Mesh Proxy Data OUT Value */static uint8 mesh_proxy_data_out_val[20];/* Mesh Proxy Data OUT CCCD value array */static gattCharCfg_t mesh_proxy_data_out_cccd[GATT_MAX_NUM_CONN];/********************************************************************* * Profile Attributes - Table *//* Mesh Provisioning Service Attribute Table */static gattAttribute_t mesh_prov_attr_tbl[MESH_PROV_IDX_NB] ={    /* Mesh Provisioning Service Declaration */    {        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */        GATT_PERMIT_READ,                         /* permissions */        0,                                        /* handle */        (uint8 *)&mesh_prov_service               /* pValue */    },    /* Mesh Prov Data IN Characteristic Declaration */    {        { ATT_BT_UUID_SIZE, characterUUID },        GATT_PERMIT_READ,        0,        &mesh_prov_data_in_props    },    /* Mesh Prov Data IN Characteristic Value */    {        { ATT_BT_UUID_SIZE, mesh_prov_data_in_UUID },        GATT_PERMIT_WRITE,        0,        &mesh_prov_data_in_val[0]    },    /* Mesh Prov Data OUT Characteristic Declaration */    {        { ATT_BT_UUID_SIZE, characterUUID },        GATT_PERMIT_READ,        0,        &mesh_prov_data_out_props    },    /* Mesh Prov Data OUT Characteristic Value */    {        { ATT_BT_UUID_SIZE, mesh_prov_data_out_UUID },        0,        0,        &mesh_prov_data_out_val[0]    },    /* Mesh Prov Data OUT CCCD */    {        { ATT_BT_UUID_SIZE, clientCharCfgUUID },        GATT_PERMIT_READ | GATT_PERMIT_WRITE,        0,        (uint8 *) &mesh_prov_data_out_cccd    },};/* Mesh Proxy Service Attribute Table */static gattAttribute_t mesh_proxy_attr_tbl[MESH_PROXY_IDX_NB] ={    /* Mesh Proxy Service Declaration */    {        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */        GATT_PERMIT_READ,                         /* permissions */        0,                                        /* handle */        (uint8 *)&mesh_proxy_service               /* pValue */    },    /* Mesh Proxy Data IN Characteristic Declaration */    {        { ATT_BT_UUID_SIZE, characterUUID },        GATT_PERMIT_READ,        0,        &mesh_proxy_data_in_props    },    /* Mesh Proxy Data IN Characteristic Value */    {        { ATT_BT_UUID_SIZE, mesh_proxy_data_in_UUID },        GATT_PERMIT_WRITE,        0,        &mesh_proxy_data_in_val[0]    },    /* Mesh Proxy Data OUT Characteristic Declaration */    {        { ATT_BT_UUID_SIZE, characterUUID },        GATT_PERMIT_READ,        0,        &mesh_proxy_data_out_props    },    /* Mesh Proxy Data OUT Characteristic Value */    {        { ATT_BT_UUID_SIZE, mesh_proxy_data_out_UUID },        0,        0,        &mesh_proxy_data_out_val[0]    },    /* Mesh Proxy Data OUT CCCD */    {        { ATT_BT_UUID_SIZE, clientCharCfgUUID },        GATT_PERMIT_READ | GATT_PERMIT_WRITE,        0,        (uint8 *) &mesh_proxy_data_out_cccd    },};/********************************************************************* * LOCAL FUNCTIONS */static bStatus_t mesh_prov_write_cb                 (                     uint16 connHandle,                     gattAttribute_t *pAttr,                     uint8 *pValue,                     uint8 len,                     uint16 offset                 );static bStatus_t mesh_proxy_write_cb                 (                     uint16 connHandle,                     gattAttribute_t *pAttr,                     uint8 *pValue,                     uint8 len,                     uint16 offset                 );static void mesh_prov_handle_conn            (                uint16 connHandle,                uint8 changeType            );static void mesh_proxy_handle_conn            (                uint16 connHandle,                uint8 changeType            );/********************************************************************* * PROFILE CALLBACKS *//* Mesh Provisioning Service Internal Callbacks */CONST gattServiceCBs_t mesh_prov_internal_cbs ={  NULL,               // Read callback function pointer  mesh_prov_write_cb, // Write callback function pointer  NULL                // Authorization callback function pointer};/* Mesh Proxy Service Internal Callbacks */CONST gattServiceCBs_t mesh_proxy_internal_cbs ={  NULL,                // Read callback function pointer  mesh_proxy_write_cb, // Write callback function pointer  NULL                 // Authorization callback function pointer};/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_prov_init(mesh_prov_cb *cb) * ---------------------------------------------------------------------------- * Description   : Send request to add Mesh Provisioning Service[0x1827] *                 into the attribute database. *                 Defines the different access functions.*                 (setter/getter commands to access the different *                 characteristic attributes). * Inputs        : Pointer to mesh_prov_cb. * Outputs       : bStatus_t : SUCCESS or failure reasons * Assumptions   : None * ------------------------------------------------------------------------- */bStatus_t mesh_prov_init(mesh_prov_cb *cb){    uint8 status = FAILURE;    /* Initialize Client Characteristic Configuration attributes */    GATTServApp_InitCharCfg    (        INVALID_CONNHANDLE,        mesh_prov_data_out_cccd    );    /* Register with Link DB to receive link status change callback */    VOID linkDB_Register(mesh_prov_handle_conn);    /* Register GATT attribute list and CBs with GATT Server App */    status = GATTServApp_RegisterService             (                 mesh_prov_attr_tbl,                 GATT_NUM_ATTRS(mesh_prov_attr_tbl),                 &mesh_prov_internal_cbs             );    /* Save the Callback Provided */    prov_cb = cb;    return (status);}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_proxy_init(mesh_proxy_cb *cb) * ---------------------------------------------------------------------------- * Description   : Send request to add Mesh Proxy Service[0x1828] *                 into the attribute database. *                 Defines the different access functions.*                 (setter/getter commands to access the different *                 characteristic attributes). * Inputs        : Pointer to mesh_proxy_cb. * Outputs       : bStatus_t : SUCCESS or failure reasons * Assumptions   : None * ------------------------------------------------------------------------- */bStatus_t mesh_proxy_init(mesh_proxy_cb *cb){    uint8 status = FAILURE;    /* Initialize Client Characteristic Configuration attributes */    GATTServApp_InitCharCfg    (        INVALID_CONNHANDLE,        mesh_proxy_data_out_cccd    );    /* Register with Link DB to receive link status change callback */    VOID linkDB_Register(mesh_proxy_handle_conn);    /* Register GATT attribute list and CBs with GATT Server App */    status = GATTServApp_RegisterService             (                 mesh_proxy_attr_tbl,                 GATT_NUM_ATTRS(mesh_proxy_attr_tbl),                 &mesh_proxy_internal_cbs             );    /* Save the Callback Provided */    proxy_cb = cb;    return (status);}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_prov_deinit(void) * ---------------------------------------------------------------------------- * Description   : Send request to delete Mesh Provisioning Service[0x1827] *                 from the attribute database. * Inputs        : None * Outputs       : bStatus_t : SUCCESS or failure reasons * Assumptions   : None * ------------------------------------------------------------------------- */bStatus_t mesh_prov_deinit(void){    uint8 status = SUCCESS;    /* Reset the Callback Provided */    prov_cb = NULL;    /**     * Deregister Mesh Prov Service attribute list and     * CBs from GATT Server Application     */    status = GATTServApp_DeregisterService             (                 GATT_SERVICE_HANDLE(mesh_prov_attr_tbl),                 NULL             );    return ( status );}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_proxy_deinit(void) * ---------------------------------------------------------------------------- * Description   : Send request to delete Mesh Proxy Service[0x1828] *                 from the attribute database. * Inputs        : None * Outputs       : bStatus_t : SUCCESS or failure reasons * Assumptions   : None * ------------------------------------------------------------------------- */bStatus_t mesh_proxy_deinit(void){    uint8 status = SUCCESS;    /* Reset the Callback Provided */    proxy_cb = NULL;    /**     * Deregister Mesh Prov Service attribute list and     * CBs from GATT Server Application     */    status = GATTServApp_DeregisterService             (                 GATT_SERVICE_HANDLE(mesh_proxy_attr_tbl),                 NULL             );    return ( status );}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_prov_notify_data_out(uint16 conn_hndl, *                               uint8 attidx, uint8 *val, uint8 val_len) * ---------------------------------------------------------------------------- * Description   : Send Mesh Provisiong Data Out notification to Peer * Inputs        : - conn_hndl       - connection index *                 - attidx       - index to attributes in the service *                 - val          - pointer to value *                 - val_len      - length of value * Outputs       : bStatus_t : SUCCESS or failure reasons * Assumptions   : None * ------------------------------------------------------------------------- */bStatus_t mesh_prov_notify_data_out          (              uint16  conn_hndl,              uint8   attidx,              uint8   * val,              uint8   val_len          ){  attHandleValueNoti_t mesh_prov_notif;  uint16 value = GATTServApp_ReadCharCfg                 (                     conn_hndl,                     mesh_prov_data_out_cccd                 );  /* NOTE: Currently the attidx is ignored */  (void)attidx;  /* Assign the Mesh Prov Data Out Value Handle */  mesh_prov_notif.handle =\         mesh_prov_attr_tbl[MESH_PROV_DATA_OUT_VALUE_VAL].handle;  /* Copy the Value and Length */  mesh_prov_notif.len = val_len;  osal_memcpy(mesh_prov_notif.value, val, val_len);  /* If notifications enabled */  if ( value & GATT_CLIENT_CFG_NOTIFY )  {    /* Send the notification */    return GATT_Notification( conn_hndl, &mesh_prov_notif, FALSE );  }  return bleIncorrectMode;}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_proxy_notify_data_out(uint16 conn_hndl, *                               uint8 attidx, uint8 *val, uint8 val_len) * ---------------------------------------------------------------------------- * Description   : Send Mesh Proxy Data Out notification to Peer * Inputs        : - conn_hndl       - connection index *                 - attidx       - index to attributes in the service *                 - val          - pointer to value *                 - val_len      - length of value * Outputs       : bStatus_t : SUCCESS or failure reasons * Assumptions   : None * ------------------------------------------------------------------------- */bStatus_t mesh_proxy_notify_data_out          (              uint16  conn_hndl,              uint8   attidx,              uint8   * val,              uint8   val_len          ){  attHandleValueNoti_t mesh_proxy_notif;  uint16 value = GATTServApp_ReadCharCfg                 (                     conn_hndl,                     mesh_proxy_data_out_cccd                 );  /* NOTE: Currently the attidx is ignored */  (void)attidx;  /* Assign the Mesh Prov Data Out Value Handle */  mesh_proxy_notif.handle =\         mesh_proxy_attr_tbl[MESH_PROV_DATA_OUT_VALUE_VAL].handle;  /* Copy the Value and Length */  mesh_proxy_notif.len = val_len;  osal_memcpy(mesh_proxy_notif.value, val, val_len);  /* If notifications enabled */  if ( value & GATT_CLIENT_CFG_NOTIFY )  {    /* Send the notification */    return GATT_Notification( conn_hndl, &mesh_proxy_notif, FALSE );  }  return bleIncorrectMode;}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_prov_write_cb (uint16 connHandle,                             gattAttribute_t * pAttr, uint8 * pValue,                             uint8 len, uint16 offset) * ---------------------------------------------------------------------------- * Description   : Validate attribute data prior to a write operation * Inputs        : - connHandle - connection Handle *                 - pAttr      - pointer to attribute *                 - pValue     - pointer to data to be written *                 - len        - length of data *                 - offset     - offset of the first octet to be written * Outputs       : Success or Failure * Assumptions   : None * ------------------------------------------------------------------------- */static bStatus_t mesh_prov_write_cb                 (                     uint16            connHandle,                     gattAttribute_t * pAttr,                     uint8           * pValue,                     uint8             len,                     uint16            offset                 ){  bStatus_t status = SUCCESS;  /* If attribute permissions require authorization to write, return error */  if ( gattPermitAuthorWrite( pAttr->permissions ) )  {    /* Insufficient authorization */    return ( ATT_ERR_INSUFFICIENT_AUTHOR );  }  if ( pAttr->type.len == ATT_BT_UUID_SIZE )  {    /* 16-bit UUID */    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);    switch (uuid)    {      case MESH_PROV_DATA_IN_UUID:        /* Validate the value */        /* Make sure it's not a blob oper */        /* phy_printf("\r\n MESH_PROV_DATA_IN WWR of length %d\r\n", len); */        if ( offset != 0 )        {            status = ATT_ERR_ATTR_NOT_LONG;        }        /* Write the value */        if (SUCCESS == status)        {            /* TODO: Check if this is needed */            /* len = (len <= MESH_PROV_DATA_IN_MAX_LENGTH) ?\                  len : MESH_PROV_DATA_IN_MAX_LENGTH; */            /* Notify Data IN Write Callback */            /* Invoke Data IN Callback */            if (NULL != prov_cb)            {                prov_cb->prov_data_in_cb                (                    connHandle,                    offset,                    len,                    pValue                );            }        }        break;      case GATT_CLIENT_CHAR_CFG_UUID:        /* phy_printf("\r\n MESH_PROV_DATA_OUT CCCD Write for %d Attr Handle of length %d\r\n", pAttr->handle, len); */        status = GATTServApp_ProcessCCCWriteReq                 (                     connHandle,                     pAttr,                     pValue,                     len,                     offset,                     GATT_CLIENT_CFG_NOTIFY                 );        if ( status == SUCCESS )        {            uint16 t_cccd_val = BUILD_UINT16( pValue[0], pValue[1] );            t_cccd_val = (GATT_CLIENT_CFG_NOTIFY == t_cccd_val) ?\                         TRUE : FALSE;            /* Invoke CCCD Update Callback */            if (NULL != prov_cb)            {                prov_cb->prov_data_out_ccd_cb                (                    connHandle,                    t_cccd_val                );            }        }        break;      default:        status = ATT_ERR_ATTR_NOT_FOUND;        break;    }  }  else  {    // 128-bit UUID    status = ATT_ERR_INVALID_HANDLE;  }  return ( status );}/* ---------------------------------------------------------------------------- * Function      : bStatus_t mesh_proxy_write_cb (uint16 connHandle,                             gattAttribute_t * pAttr, uint8 * pValue,                             uint8 len, uint16 offset) * ---------------------------------------------------------------------------- * Description   : Validate attribute data prior to a write operation * Inputs        : - connHandle - connection Handle *                 - pAttr      - pointer to attribute *                 - pValue     - pointer to data to be written *                 - len        - length of data *                 - offset     - offset of the first octet to be written * Outputs       : Success or Failure * Assumptions   : None * ------------------------------------------------------------------------- */static bStatus_t mesh_proxy_write_cb                 (                     uint16            connHandle,                     gattAttribute_t * pAttr,                     uint8           * pValue,                     uint8             len,                     uint16            offset                 ){  bStatus_t status = SUCCESS;  /* If attribute permissions require authorization to write, return error */  if ( gattPermitAuthorWrite( pAttr->permissions ) )  {    /* Insufficient authorization */    return ( ATT_ERR_INSUFFICIENT_AUTHOR );  }  if ( pAttr->type.len == ATT_BT_UUID_SIZE )  {    /* 16-bit UUID */    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);    switch (uuid)    {      case MESH_PROXY_DATA_IN_UUID:        /* Validate the value */        /* Make sure it's not a blob oper */        /* phy_printf("\r\n MESH_PROXY_DATA_IN WWR of length %d\r\n", len); */        if ( offset != 0 )        {            status = ATT_ERR_ATTR_NOT_LONG;        }        /* Write the value */        if (SUCCESS == status)        {            /* TODO: Check if this is needed */            /* len = (len <= MESH_PROXY_DATA_IN_MAX_LENGTH) ?\                  len : MESH_PROXY_DATA_IN_MAX_LENGTH; */            /* Notify Data IN Write Callback */            /* Invoke Data IN Callback */            if (NULL != proxy_cb)            {                proxy_cb->proxy_data_in_cb                (                    connHandle,                    offset,                    len,                    pValue                );            }        }        break;      case GATT_CLIENT_CHAR_CFG_UUID:        /* phy_printf("\r\n MESH_PROXY_DATA_OUT CCCD Write for %d Attr Handle of length %d\r\n", pAttr->handle, len); */        status = GATTServApp_ProcessCCCWriteReq                 (                     connHandle,                     pAttr,                     pValue,                     len,                     offset,                     GATT_CLIENT_CFG_NOTIFY                 );        if ( status == SUCCESS )        {            uint16 t_cccd_val = BUILD_UINT16( pValue[0], pValue[1] );            t_cccd_val = (GATT_CLIENT_CFG_NOTIFY == t_cccd_val) ?\                         TRUE : FALSE;            /* Invoke CCCD Update Callback */            if (NULL != proxy_cb)            {                proxy_cb->proxy_data_out_ccd_cb                (                    connHandle,                    t_cccd_val                );            }        }        break;      default:        status = ATT_ERR_ATTR_NOT_FOUND;        break;    }  }  else  {    // 128-bit UUID    status = ATT_ERR_INVALID_HANDLE;  }  return ( status );}/* ---------------------------------------------------------------------------- * Function      : void mesh_prov_handle_conn(uint16 connHandle, *                                uint8 changeType) * ---------------------------------------------------------------------------- * Description   : Callback to Handle Mesh Prov Connection event * Inputs        : - connHandle   - connection Handle *                 - changeType   - type of change * Outputs       : None * Assumptions   : None * ------------------------------------------------------------------------- */static void mesh_prov_handle_conn( uint16 connHandle, uint8 changeType ){  // Make sure this is not loopback connection  if ( connHandle != LOOPBACK_CONNHANDLE )  {    // Reset Client Char Config if connection has dropped    if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED )      ||         ( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&           ( !linkDB_Up( connHandle ) ) ) )    {      GATTServApp_InitCharCfg( connHandle, mesh_prov_data_out_cccd );    }  }}/* ---------------------------------------------------------------------------- * Function      : void mesh_proxy_handle_conn(uint16 connHandle, *                                uint8 changeType) * ---------------------------------------------------------------------------- * Description   : Callback to Handle Mesh Proxy Connection event * Inputs        : - connHandle   - connection Handle *                 - changeType   - type of change * Outputs       : None * Assumptions   : None * ------------------------------------------------------------------------- */static void mesh_proxy_handle_conn( uint16 connHandle, uint8 changeType ){  // Make sure this is not loopback connection  if ( connHandle != LOOPBACK_CONNHANDLE )  {    // Reset Client Char Config if connection has dropped    if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED )      ||         ( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&           ( !linkDB_Up( connHandle ) ) ) )    {      GATTServApp_InitCharCfg( connHandle, mesh_proxy_data_out_cccd );    }  }}
 |