123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585 |
- /**
- * \file mesh_clients.c
- *
- *
- */
- /*
- * Copyright (C) 2018. Mindtree Limited.
- * All rights reserved.
- */
- /* --------------------------------------------- Header File Inclusion */
- #include "mesh_clients.h"
- /* --------------------------------------------- Global Definitions */
- /* Compilation Switch to have this module print trace on console */
- #define MESH_CLIENT_CONSOLE_DEBUG
- /* --------------------------------------------- Macros */
- #ifdef MESH_CLIENT_CONSOLE_DEBUG
- #define MESH_CLIENT_TRC(...) printf(__VA_ARGS__)
- #else /* MESH_CLIENT_CONSOLE_DEBUG */
- #define MESH_CLIENT_TRC(...)
- #endif /* MESH_CLIENT_CONSOLE_DEBUG */
- /* --------------------------------------------- External Global Variables */
- /* --------------------------------------------- Exported Global Variables */
- /* --------------------------------------------- Static Global Variables */
- /**
- * This Task ID is the identifier used by the GATT APIs to reference
- * the BLE Mesh Application Task.
- * The definition and usage of this is from the bleMesh.c application
- * file.
- */
- extern uint8_t bleMesh_TaskID;
- /* --------------------------------------------- Functions */
- #define MESH_MAX_CLI_ENV 1
- /* Global variable definition */
- struct mesh_cli_env_tag mesh_cli_env[MESH_MAX_CLI_ENV];
- /* Mesh Provisioning Service Client Related Callbacks */
- static mesh_prov_client_cb * prov_cli_cb;
- /* Mesh Proxy Service Client Related Callbacks */
- static mesh_proxy_client_cb * proxy_cli_cb;
- /* Track current UUID being Discovered */
- static uint16_t mesh_client_curr_dis_uuid;
- /* ----------------------------------------------------------------------------
- * Function : void mesh_client_init(void)
- * ----------------------------------------------------------------------------
- * Description : Initialize Mesh Client environment
- * Inputs : None
- * Outputs : None
- * Assumptions : None
- * ------------------------------------------------------------------------- */
- void mesh_client_init(void)
- {
- for (unsigned int i = 0; i < MESH_MAX_CLI_ENV; i++)
- {
- /* Reset the application manager environment */
- memset(&mesh_cli_env[i], 0, sizeof(struct mesh_cli_env_tag));
- }
- mesh_client_curr_dis_uuid = 0x0000;
- prov_cli_cb = NULL;
- proxy_cli_cb = NULL;
- }
- /**
- * Routine to update the connection identifier for Mesh.
- */
- void mesh_client_update_conidx (uint16_t conidx)
- {
- mesh_cli_env[0].conidx = conidx;
- }
- /**
- * \brief Register Mesh Provisioning Client instance
- *
- * Function registers new Mesh Provisioning Client instance.
- *
- * \param [in] cb client application callbacks
- *
- * \return None
- *
- */
- void mesh_prov_client_init(mesh_prov_client_cb * cb)
- {
- /* Register the upper layer provided Provisioning Client Callbacks */
- if (NULL != cb)
- {
- prov_cli_cb = cb;
- }
- }
- /**
- * \brief Register Mesh Proxy Client instance
- *
- * Function registers new Mesh Proxy Client instance.
- *
- * \param [in] cb client application callbacks
- *
- * \return None
- *
- */
- void mesh_proxy_client_init(mesh_proxy_client_cb * cb)
- {
- /* Register the upper layer provided Provisioning Client Callbacks */
- if (NULL != cb)
- {
- proxy_cli_cb = cb;
- }
- }
- API_RESULT mesh_client_discover_services
- (
- uint16_t conidx,
- uint8_t serv_mode
- )
- {
- uint8_t svc_uuid[2];
- bStatus_t ret;
- if (BLEBRR_GATT_PROV_MODE == serv_mode)
- {
- /* UUID is Provisioning Service */
- svc_uuid[0] = (uint8_t)(UUID_MESH_PROVISIONING_SERVICE);
- svc_uuid[1] = (uint8_t)(UUID_MESH_PROVISIONING_SERVICE >> 8);
- /* EM_mem_copy(svc_uuid, MESH_PROV_SERVICE_UUID128, 16); */
- mesh_client_curr_dis_uuid = UUID_MESH_PROVISIONING_SERVICE;
- }
- else
- {
- /* UUID is Proxy Service */
- svc_uuid[0] = (uint8_t)(UUID_MESH_PROXY_SERVICE);
- svc_uuid[1] = (uint8_t)(UUID_MESH_PROXY_SERVICE >> 8);
- /* EM_mem_copy(svc_uuid, MESH_PROXY_SERVICE_UUID128, 16); */
- mesh_client_curr_dis_uuid = UUID_MESH_PROVISIONING_SERVICE;
- }
- /* Discover service by UUID */
- ret = GATT_DiscPrimaryServiceByUUID
- (
- conidx,
- svc_uuid,
- ATT_BT_UUID_SIZE,
- bleMesh_TaskID
- );
- MESH_CLIENT_TRC(
- "Discovery Primiary Service UUID 0x%04X "
- "returned with retval 0x%04X\r\n",
- mesh_client_curr_dis_uuid, ret);
- return (0 == ret) ? API_SUCCESS : API_FAILURE;
- }
- /* ----------------------------------------------------------------------------
- * Function : void mesh_client_send_wwr(uint8_t conidx, uint8_t *value,
- * uint16_t handle, uint8_t offset,
- * uint16_t length, uint8_t type)
- * ----------------------------------------------------------------------------
- * Description : Send a write command or request to the client device
- * Inputs : - conidx - Connection index
- * - value - Pointer to value
- * - handle - Attribute handle
- * - length - Length of value
- * - type - Type of write message
- * Outputs : None
- * Assumptions : None
- * ------------------------------------------------------------------------- */
- void mesh_client_send_wwr
- (
- uint16_t conidx,
- uint8_t * value,
- uint16_t length,
- uint8_t serv_pref
- )
- {
- attWriteReq_t req;
- bStatus_t ret;
- /* Assign the Handle Based on the Service Preference for Write */
- req.handle = (BLEBRR_GATT_PROV_MODE == serv_pref) ? \
- mesh_cli_env[0].prov_data_in_hdl : \
- mesh_cli_env[0].proxy_data_in_hdl;
- req.len = length;
- req.sig = 0x00;
- req.cmd = 0x01; /* Write witout response */
- osal_memcpy(req.value, value, length);
- ret = GATT_WriteNoRsp(conidx, &req);
- MESH_CLIENT_TRC(
- "Writing data : len 0x%04X : handle 0x%02X : ret 0x%04X\n",
- req.len, req.handle, ret);
- return;
- }
- /* ----------------------------------------------------------------------------
- * Function : void mesh_client_config_ntf
- * (
- * uint16_t conidx,
- * uint8_t serv_pref,
- * uint8_t flag
- * )
- * ----------------------------------------------------------------------------
- * Description : Send a write command or request to the client device
- * Inputs : - conidx - Connection index
- * - serv_pref - Provisioning or Proxy Service
- * - flag - enable or disable
- * Outputs : None
- * Assumptions : None
- * ------------------------------------------------------------------------- */
- API_RESULT mesh_client_config_ntf
- (
- uint16_t conidx,
- uint8_t serv_pref,
- uint8_t flag
- )
- {
- attWriteReq_t req;
- bStatus_t ret;
- /* Assign the Handle Based on the Service Preference for Write */
- /**
- * Increment the Handle by 1 as the CCCD is present in the handle next to
- * the Value handle
- */
- req.handle = (BLEBRR_GATT_PROV_MODE == serv_pref) ? \
- mesh_cli_env[0].prov_data_out_cccd_hdl : \
- mesh_cli_env[0].proxy_data_out_cccd_hdl;
- req.len = 0x02;
- req.sig = 0x00;
- req.cmd = 0x00;
- req.value[0] = (true == flag) ? 0x01 : 0x00;
- req.value[1] = 0x00;
- /* Store CCCD Mode and State in global */
- mesh_cli_env[0].curr_notif_state = flag;
- mesh_cli_env[0].curr_notif_mode = (BLEBRR_GATT_PROV_MODE == serv_pref) ? \
- BLEBRR_GATT_PROV_MODE : \
- BLEBRR_GATT_PROXY_MODE;
- ret = GATT_WriteCharValue(mesh_cli_env[0].conidx, &req, bleMesh_TaskID);
- MESH_CLIENT_TRC
- ("Writing %d to CCCD 0x%04X for Mode 0x%02X\n",
- flag, req.handle, serv_pref);
- return (0 == ret) ? API_SUCCESS : API_FAILURE;
- }
- void mesh_client_process_gattMsg
- (
- gattMsgEvent_t *pMsg,
- uint8_t t_id
- )
- {
- bStatus_t ret;
- uint16_t serv_start_hndl, serv_end_hndl;
- MESH_CLIENT_TRC("Processing GATT Messages:\n");
- MESH_CLIENT_TRC("pMsg->method: 0x%X\n",pMsg->method);
- MESH_CLIENT_TRC("pMsg->hdr.status: 0x%X\n",pMsg->hdr.status);
- /* Cache the Task ID */
- bleMesh_TaskID = t_id;
- /* Process the GATT server message */
- switch ( pMsg->method )
- {
- case ATT_EXCHANGE_MTU_RSP:
- break;
- case ATT_FIND_BY_TYPE_VALUE_RSP:
- {
- if (bleProcedureComplete == pMsg->hdr.status)
- {
- if (UUID_MESH_PROVISIONING_SERVICE == mesh_client_curr_dis_uuid)
- {
- serv_start_hndl = mesh_cli_env[0].prov_start_hdl;
- serv_end_hndl = mesh_cli_env[0].prov_end_hdl;
- }
- else if (UUID_MESH_PROXY_SERVICE == mesh_client_curr_dis_uuid)
- {
- serv_start_hndl = mesh_cli_env[0].proxy_start_hdl;
- serv_end_hndl = mesh_cli_env[0].proxy_end_hdl;
- }
- else
- {
- MESH_CLIENT_TRC( "Mesh Services not Present\r\n");
- }
- /* Start Charactertistic Discovery */
- ret = GATT_DiscAllChars
- (
- mesh_cli_env[0].conidx,
- serv_start_hndl,
- serv_end_hndl,
- bleMesh_TaskID
- );
- MESH_CLIENT_TRC(
- "Disc Characteristics btw Handles 0x%04X :: 0x%04X"
- "returned with retval 0x%04X\r\n",
- serv_start_hndl, serv_end_hndl, ret);
- }
- else
- {
- if (pMsg->msg.findByTypeValueRsp.numInfo > 0)
- {
- MESH_CLIENT_TRC(
- "\nServices found :%d\n",
- pMsg->msg.findByTypeValueRsp.numInfo);
- MESH_CLIENT_TRC(
- "Service Handles are 0x%04X :: 0x%04X",
- pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle,
- pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle);
- if (mesh_client_curr_dis_uuid == UUID_MESH_PROVISIONING_SERVICE)
- {
- mesh_cli_env[0].prov_start_hdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;
- mesh_cli_env[0].prov_end_hdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
- MESH_CLIENT_TRC(
- "\r\n Prov Service Start Handle is 0x%04X\r\n",
- mesh_cli_env[0].prov_start_hdl);
- MESH_CLIENT_TRC(
- "\r\n Prov Service End Handle is 0x%04X\r\n",
- mesh_cli_env[0].prov_end_hdl);
- }
- else if (mesh_client_curr_dis_uuid == UUID_MESH_PROXY_SERVICE)
- {
- mesh_cli_env[0].proxy_start_hdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;
- mesh_cli_env[0].proxy_end_hdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
- MESH_CLIENT_TRC(
- "\r\nProxy Service Start Handle is 0x%04X\r\n",
- mesh_cli_env[0].proxy_start_hdl);
- MESH_CLIENT_TRC(
- "\r\nProxy Service End Handle is 0x%04X\r\n",
- mesh_cli_env[0].proxy_end_hdl);
- }
- }
- else
- {
- MESH_CLIENT_TRC("\n No Services Found!\n");
- /**
- * TODO: Provide Discovery completion Callback.
- */
- }
- }
- }
- break;
- case ATT_READ_BY_TYPE_RSP:
- {
- if (bleProcedureComplete == pMsg->hdr.status)
- {
- uint16_t t_char_start_hndl;
- if (UUID_MESH_PROVISIONING_SERVICE == mesh_client_curr_dis_uuid)
- {
- t_char_start_hndl = mesh_cli_env[0].prov_data_out_hdl;
- serv_end_hndl = mesh_cli_env[0].prov_end_hdl;
- }
- else if (UUID_MESH_PROXY_SERVICE == mesh_client_curr_dis_uuid)
- {
- t_char_start_hndl = mesh_cli_env[0].proxy_data_out_hdl;
- serv_end_hndl = mesh_cli_env[0].proxy_end_hdl;
- }
- ret = GATT_DiscAllCharDescs
- (
- mesh_cli_env[0].conidx,
- t_char_start_hndl,
- serv_end_hndl,
- bleMesh_TaskID
- );
- MESH_CLIENT_TRC(
- "Disc Char Desc btw Handles 0x%04X :: 0x%04X"
- "returned with retval 0x%04X\r\n",
- t_char_start_hndl, serv_end_hndl, ret);
- }
- else
- {
- // Pointer to the pair list data in the GATT response.
- uint8_t *pCharPairList;
- // Will store the start and end handles of the current pair.
- uint16_t charStartHandle;
- // Stores to the UUID of the current pair.
- uint16_t charUuid;
- // Stores what pair the loop is currently processing.
- uint8_t currentCharIndex;
- // Set the pair pointer to the first pair.
- pCharPairList = pMsg->msg.readByTypeRsp.dataList;
- // Iterate through all three pairs found.
- for(currentCharIndex = 0; currentCharIndex < pMsg->msg.readByTypeRsp.numPairs ; currentCharIndex++)
- {
- /* uint16_t* p_chars_hdl = pservie->chars_hdl; */
- // Extract the starting handle, ending handle, and UUID of the current characteristic.
- charStartHandle = BUILD_UINT16(pCharPairList[3], pCharPairList[4]);
- charUuid = BUILD_UINT16(pCharPairList[5], pCharPairList[6]);
- MESH_CLIENT_TRC(
- "Chars found handle is %d, uuid is %x\n",
- charStartHandle, charUuid);
- switch (charUuid)
- {
- /* "Mesh Provisioning Data IN" */
- case UUID_MESH_PROVISIONING_DATA_IN:
- mesh_cli_env[0].prov_data_in_hdl = charStartHandle;
- break;
- /* "Mesh Provisioning Data OUT" */
- case UUID_MESH_PROVISIONING_DATA_OUT:
- mesh_cli_env[0].prov_data_out_hdl = charStartHandle;
- mesh_cli_env[0].prov_data_out_cccd_hdl = charStartHandle + 1;
- break;
- /* "Mesh Proxy Data IN" */
- case UUID_MESH_PROXY_DATA_IN:
- mesh_cli_env[0].proxy_data_in_hdl = charStartHandle;
- break;
- /* "Mesh Proxy Data OUT" */
- case UUID_MESH_PROXY_DATA_OUT:
- mesh_cli_env[0].proxy_data_out_hdl = charStartHandle;
- mesh_cli_env[0].proxy_data_out_cccd_hdl = charStartHandle + 1;
- break;
- }
- // Increment the pair pointer to the next pair.
- pCharPairList += 5 + 2;
- }
- }
- }
- break;
- case ATT_FIND_INFO_RSP:
- {
- if (bleProcedureComplete == pMsg->hdr.status)
- {
- /**
- * TODO: Provide Discovery completion Callback.
- */
- }
- else
- {
- if ( (pMsg->msg.findInfoRsp.numInfo > 0) &&
- (pMsg->msg.findInfoRsp.format == ATT_HANDLE_BT_UUID_TYPE) )
- {
- // This will keep track of the current pair being processed.
- uint8_t currentPair;
- // Iterate through the pair list.
- for(currentPair = 0; currentPair < pMsg->msg.findInfoRsp.numInfo; currentPair++)
- {
- // Check if the pair is a CCCD.
- uint16_t uuid = BUILD_UINT16(pMsg->msg.findInfoRsp.info.btPair[currentPair].uuid[0], pMsg->msg.findInfoRsp.info.btPair[currentPair].uuid[1]);
- if (uuid == GATT_CLIENT_CHAR_CFG_UUID)
- {
- MESH_CLIENT_TRC(
- "CCCD is found at handle 0x%X for Mode %d\n",
- pMsg->msg.findInfoRsp.info.btPair[currentPair].handle, blebrr_gatt_mode_get());
- if (BLEBRR_GATT_PROV_MODE == blebrr_gatt_mode_get())
- {
- mesh_cli_env[0].prov_data_out_cccd_hdl = pMsg->msg.findInfoRsp.info.btPair[currentPair].handle;
- }
- else
- {
- mesh_cli_env[0].proxy_data_out_cccd_hdl = pMsg->msg.findInfoRsp.info.btPair[currentPair].handle;
- }
- }
- }
- }
- }
- }
- break;
- case ATT_HANDLE_VALUE_NOTI:
- {
- uint16_t notifHandle = pMsg->msg.handleValueNoti.handle;
- if (pMsg->msg.handleValueNoti.len > 0)
- {
- /* Check the Attribute Handle:
- * - If Provisioning Data Out Handle: then call the Prov Callback
- * - If Proxy Data Out Handle: the ncall the Proxy Callback
- */
- if (mesh_cli_env[0].prov_data_out_hdl == notifHandle)
- {
- if (NULL != prov_cli_cb)
- {
- prov_cli_cb->mesh_prov_data_out_notif
- (
- mesh_cli_env[0].conidx,
- pMsg->msg.handleValueNoti.len,
- pMsg->msg.handleValueNoti.value
- );
- }
- }
- else if (mesh_cli_env[0].proxy_data_out_hdl == notifHandle)
- {
- if (NULL != proxy_cli_cb)
- {
- proxy_cli_cb->mesh_proxy_data_out_notif
- (
- mesh_cli_env[0].conidx,
- pMsg->msg.handleValueNoti.len,
- pMsg->msg.handleValueNoti.value
- );
- }
- }
- }
- }
- break;
- case ATT_WRITE_RSP:
- {
- if (BLEBRR_GATT_PROV_MODE == mesh_cli_env[0].curr_notif_mode)
- {
- /* Call the Prov CCCD ntf complete Callback */
- if (NULL != prov_cli_cb)
- {
- prov_cli_cb->mesh_prov_ntf_status
- (
- mesh_cli_env[0].conidx,
- mesh_cli_env[0].curr_notif_state,
- 0x00
- );
- }
- }
- else if (BLEBRR_GATT_PROXY_MODE == mesh_cli_env[0].curr_notif_mode)
- {
- /* Call the Proxy CCCD ntf complete Callback */
- if (NULL != proxy_cli_cb)
- {
- proxy_cli_cb->mesh_proxy_ntf_status
- (
- mesh_cli_env[0].conidx,
- mesh_cli_env[0].curr_notif_state,
- 0x00
- );
- }
- }
- else
- {
- /* DO Nothing ! */
- }
- }
- break;
- case ATT_ERROR_RSP:
- {
- attErrorRsp_t* perr = &(pMsg->msg.errorRsp);
- MESH_CLIENT_TRC(
- "\nATT_ERROR_RSP 0x%x, 0x%x, 0x%x\n",
- perr->errCode, perr->handle, perr->reqOpcode);
- }
- break;
- default:
- break;
- }
- (void)ret;
- }
|