123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739 |
- /**************************************************************************************************
-
- Phyplus Microelectronics Limited confidential and proprietary.
- All rights reserved.
- IMPORTANT: All rights of this software belong to Phyplus Microelectronics
- Limited ("Phyplus"). Your use of this Software is limited to those
- specific rights granted under the terms of the business contract, the
- confidential agreement, the non-disclosure agreement and any other forms
- of agreements as a customer or a partner of Phyplus. You may not use this
- Software unless you agree to abide by the terms of these agreements.
- You acknowledge that the Software may not be modified, copied,
- distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
- (BLE) integrated circuit, either as a product or is integrated into your
- products. Other than for the aforementioned purposes, you may not use,
- reproduce, copy, prepare derivative works of, modify, distribute, perform,
- display or sell this Software and/or its documentation for any purposes.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
-
- **************************************************************************************************/
- #include "bcomdef.h"
- #include "linkdb.h"
- #include "hal_defs.h"
- #include "gatt.h"
- #include "gapgattserver.h"
- #include "gattservapp.h"
- #include "gatt_uuid.h"
- #include "peripheral.h"
- #include "gapbondmgr.h"
- #include "gatt_profile_uuid.h"
- #include "ble_ancs.h"
- #include "ancs_attr.h"
- #include "log.h"
- static uint8_t Ancs_CCCDConfig(uint16_t attrHdl, uint8_t isEnable);
- static ancs_ctx_t s_ancs_ctx;
- bStatus_t ble_ancs_attr_add(const ancs_notif_attr_id id, uint8_t * p_data, const uint16_t len)
- {
- ancs_attr_list_t* p_ancs_notif_attr_list = s_ancs_ctx.notif_attr_list;
-
- if(!p_data)
- return INVALIDPARAMETER;
- if((len == 0) || (len > ANCS_ATTR_DATA_MAX))
- {
- return INVALID_MEM_SIZE;
- }
- p_ancs_notif_attr_list[id].en = true;
- p_ancs_notif_attr_list[id].attr_len = len;
- p_ancs_notif_attr_list[id].p_attr_data = p_data;
- return SUCCESS;
- }
- static uint8_t figure_out_chars_end_hdl(void)
- {
- uint8_t errorcode = 0;
- ancs_ctx_t* pctx = &s_ancs_ctx;
- ancs_service_t* pservie = &(s_ancs_ctx.ancs_service);
- uint16_t* p_chars_hdl = pservie->chars_hdl;
- uint16_t ntf, cp, dt;
- ntf = p_chars_hdl[ANCS_NOTIF_SCR_HDL_START];
- cp = p_chars_hdl[ANCS_CTRL_POINT_HDL_START];
- dt = p_chars_hdl[ANCS_DATA_SRC_HDL_START];
-
- if(ntf < ((cp < dt) ? cp :dt))
- p_chars_hdl[ANCS_NOTIF_SCR_HDL_END] = cp > dt ? dt : cp;
- else if(ntf < ((cp < dt) ? dt :cp))
- p_chars_hdl[ANCS_NOTIF_SCR_HDL_END] = cp > dt ? cp : dt;
- else
- p_chars_hdl[ANCS_NOTIF_SCR_HDL_END] = pservie->service_hdl[1];
-
- if(cp < ((ntf < dt) ? ntf:dt))
- p_chars_hdl[ANCS_CTRL_POINT_HDL_END] = ntf > dt ? dt : ntf;
- else if(cp < ((ntf < dt) ? dt :ntf))
- p_chars_hdl[ANCS_CTRL_POINT_HDL_END] = ntf > dt ? ntf : dt;
- else
- p_chars_hdl[ANCS_CTRL_POINT_HDL_END] = pservie->service_hdl[1];
-
- if(dt < ((ntf < cp) ? ntf :cp))
- p_chars_hdl[ANCS_DATA_SRC_HDL_END] = ntf > cp ? cp : ntf;
- else if(dt < ((ntf < cp) ? cp :ntf))
- p_chars_hdl[ANCS_DATA_SRC_HDL_END] = ntf > cp ? ntf : cp;
- else
- p_chars_hdl[ANCS_DATA_SRC_HDL_END] = pservie->service_hdl[1];
- // Sanity check to ensure that each start handle is valid and
- // less than each respective end handle.
- if(p_chars_hdl[ANCS_NOTIF_SCR_HDL_START] != 0 &&
- p_chars_hdl[ANCS_CTRL_POINT_HDL_START] != 0 &&
- p_chars_hdl[ANCS_DATA_SRC_HDL_START] != 0)
- {
- if(p_chars_hdl[ANCS_NOTIF_SCR_HDL_START] < p_chars_hdl[ANCS_NOTIF_SCR_HDL_END] &&
- p_chars_hdl[ANCS_CTRL_POINT_HDL_START] < p_chars_hdl[ANCS_CTRL_POINT_HDL_END] &&
- p_chars_hdl[ANCS_DATA_SRC_HDL_START] < p_chars_hdl[ANCS_DATA_SRC_HDL_END])
- {
- LOG("All chars discoveried\n");
- }
- else
- {
- LOG("ANCS_STORE_CHARS_HANDLES FAILURE\n");
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 4;
- }
- }
- // Throw an error if the handles are invalid.
- else
- {
- LOG("ANCS_STORE_CHARS_HANDLES FAILURE\n");
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 5;
- }
- return errorcode;
- }
- static bStatus_t ble_disc_service(gattMsgEvent_t *pMsg)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- ancs_service_t* pservie = &(pctx->ancs_service);
-
- // Stores the error code, should the discovery process fail at any state.
- uint8_t errorcode = 0;
- //if(pMsg){
- // LOG("ble_disc_service->pMsg->method: 0x%x\n",pMsg->method);
- //}
- // Enter the state machine.
- switch (pctx->disc_state)
- {
- case ANCS_UNINIT:
- LOG("Discovery Progress:\t1\n");
- return FAILURE;
-
- // Perform a GATT Discover Primary Service By Service UUID to located the ANCS
- // handles.
- case ANCS_DISC_SERVICE:
- {
- LOG("Discovery Progress:\t2\n");
- LOG("Discovery State:\tDiscover the ANCS\n");
- // Initialize the ANCS handles to zero.
- pservie->service_hdl[0] = 0;
- pservie->service_hdl[1] = 0;
- // Store the ANCS UUID for GATT request.
- uint8_t uuid[ATT_UUID_SIZE] = {ANCSAPP_ANCS_SVC_UUID};
- // Discover the ANCS by UUID.
- bStatus_t ret = GATT_DiscPrimaryServiceByUUID(pservie->conn_hdl , uuid, ATT_UUID_SIZE, pctx->app_task_ID);
- // If successfully discovered proceed, throw error if not.
- if(ret == SUCCESS){
- pctx->disc_state = ANCS_STORE_SERVICE_HANDLES;
- pservie->expect_type_value_num = 0;
- //ancsAppState = ANCS_STATE_READY;
- }
- else
- {
- LOG("ANCS_DISC_SERVICE FAILURE, Error code:\t%d\n", ret);
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 1;
- }
- }
- break;
- // Store the ANCS handles requested in the previous state.
- case ANCS_STORE_SERVICE_HANDLES:
- {
- LOG("Discovery Progress:\t3\n");
- LOG("Discovery State:\tStore the ANCS handles %d\n",pMsg->method);
- // Did the application receive a response from the GATT Disc Primary Service?
- if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP )
- {
- LOG("found :%d\n",pMsg->msg.findByTypeValueRsp.numInfo);
-
- // Check if the ANCS was found.
- if (pMsg->msg.findByTypeValueRsp.numInfo > 0)
- {
- // Found the ANCS, so store the handles and proceed.
- pservie->service_hdl[0] = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;
- pservie->service_hdl[1] = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
- pctx->disc_state = ANCS_DISC_CHARS;
- //for(i = 0; i< pMsg->msg.findByTypeValueRsp.numInfo; i++){
- // pservie->service_hdl[pservie->expect_type_value_num] = pMsg->msg.findByTypeValueRsp.handlesInfo[i].handle;
- // pservie->expect_type_value_num ++;
- // if(pservie->expect_type_value_num == 2){
- // pctx->disc_state = ANCS_DISC_CHARS;
- // break;
- // }
- //}
- }
- else
- {
- // The ANCS was not found.
- LOG("ANCS_STORE_SERVICE_HANDLES FAILURE\n");
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 2;
- }
- }
- else
- {
- LOG("ble_disc_service->pMsg->method: 0x%x\n",pMsg->method);
- LOG("ANCS_STORE_SERVICE_HANDLES FAILURE\n");
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 2;
- }
- }
- break;
- // Use the ANCS handles to discovery the ANCS's characteristics' handles.
- case ANCS_DISC_CHARS:
- {
- LOG("Discovery Progress:\t4\n");
- LOG("Discovery State:\tDiscover the ANCS characteristics\n");
- // Check if service handle discovery event has completed.
- if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP )
- {
- LOG("ble_disc_service->pMsg->method: 0x%x\n",pMsg->method);
- if(pMsg->hdr.status == bleProcedureComplete)
- {
- // Sanity check to make sure the handle is valid before proceeding.
- if (pservie->service_hdl[0] != 0 && pservie->service_hdl[1] != 0 )
- {
- // Discover all characteristics of the ANCS.
- bStatus_t ret = GATT_DiscAllChars(
- pservie->conn_hdl,
- pservie->service_hdl[0],
- pservie->service_hdl[1],
- pctx->app_task_ID);
- pservie->chars_disc_num = 0;
- // If the request was successfully sent, proceed with the discovery process.
- if (ret == SUCCESS)
- {
- pctx->disc_state = ANCS_STORE_CHARS_HANDLES;
- }
- // If not, throw an error.
- else
- {
- LOG("ANCS_DISC_CHARS FAILURE, Error code:\t%d\n",ret);
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 3;
- }
- }
- }
- }
- else
- {
- LOG("ble_disc_service->pMsg->method: 0x%x\n",pMsg->method);
- }
- }
- break;
- // Store the retrieved ANCS characteristic handles.
- case ANCS_STORE_CHARS_HANDLES:
- {
- LOG("Discovery Progress:\t5\n");
- LOG("Discovery State:\tStore the ANCS characteristics' handles\n");
- // Wait until GATT "Read by type response" is received, then confirm that the correct number of
- // pairs are present, and that their length is correct
- if (pMsg->method == ATT_READ_BY_TYPE_RSP )
- {
- //if ( (pMsg->msg.readByTypeRsp.numPairs == NUMBER_OF_ANCS_CHARS) && (pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID128_LEN) )
- if ((pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID128_LEN) )
- {
- // 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]);
- LOG("Chars found handle is is %d, uuid is %x\n", charStartHandle, charUuid);
- // Store the start and end handles in the handle cache corresponding to
- // their UUID.
- switch (charUuid)
- {
- // If it's the Notification Source.
- case ANCSAPP_NOTIF_SRC_CHAR_UUID:
- p_chars_hdl[ANCS_NOTIF_SCR_HDL_START] = charStartHandle;
- p_chars_hdl[ANCS_NOTIF_SCR_HDL_END] = 0;
- break;
- // If it's the Control Point.
- case ANCSAPP_CTRL_PT_CHAR_UUID:
- p_chars_hdl[ANCS_CTRL_POINT_HDL_START] = charStartHandle;
- p_chars_hdl[ANCS_CTRL_POINT_HDL_END] = 0;
- break;
- // If it's the Data Source.
- case ANCSAPP_DATA_SRC_CHAR_UUID:
- p_chars_hdl[ANCS_DATA_SRC_HDL_START] = charStartHandle;
- p_chars_hdl[ANCS_DATA_SRC_HDL_END] = 0;
- break;
- default:
- break;
- }
- pservie->chars_disc_num ++;
- // If this is the final characteristic found in the response,
- // reset its end handle to the ANCS's end handle. This is because
- // there is no next staring handle to use as a reference and subtract one
- // from, so instead the ending handle of the ANCS must be used.
- if(pservie->chars_disc_num == NUMBER_OF_ANCS_CHARS){
- errorcode = figure_out_chars_end_hdl();
- pctx->disc_state = (errorcode == 0) ? ANCS_DISC_NS_DESCS : ANCS_DISC_FAILED;
- }
- // Increment the pair pointer to the next pair.
- pCharPairList += CHAR_DESC_HDL_UUID128_LEN;
- }
- }
- // Throw an error if the length or number of pairs is incorrect.
- else
- {
- LOG("ANCS_STORE_CHARS_HANDLES FAILURE\n");
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 6;
- }
- }
- else
- {
- LOG("ble_disc_service->pMsg->method: 0x%x\n",pMsg->method);
- if(pMsg->method == ATT_ERROR_RSP){
- attErrorRsp_t* perr = &(pMsg->msg.errorRsp);
- LOG("ATT_ERROR_RSP 0x%x, 0x%x, 0x%x\n", perr->errCode, perr->handle, perr->reqOpcode);
- }
- }
- }
- break;
- // Discover the Notification Source's descriptors (namely, the CCCD) using the start
- // and end handle stored in the handle cache.
- case ANCS_DISC_NS_DESCS:
- {
- LOG("Discovery Progress:\t6\n");
- LOG("Discovery State:\tDiscover the Notification Source's CCCD\n");
-
- // Wait until the characteristic handle discovery has finished.
- if ( (pMsg->method == ATT_READ_BY_TYPE_RSP) && (pMsg->hdr.status == bleProcedureComplete) )
- {
- // Discover the ANCS Notification Source descriptors.
- bStatus_t ret = GATT_DiscAllCharDescs(pservie->conn_hdl,
- pservie->chars_hdl[ANCS_NOTIF_SCR_HDL_START],
- pservie->chars_hdl[ANCS_NOTIF_SCR_HDL_END]-1,
- pctx->app_task_ID);
- // If the discovery was successful, proceed.
- if ( ret == SUCCESS )
- pctx->disc_state = ANCS_STORE_NS_DESCS_HANDLES;
- // If not, throw an error and invalidate the CCCD handle in the handle cache.
- else
- {
- LOG("ANCS_DISC_NS_DESCS FAILURE\n");
- pservie->chars_hdl[ANCS_NOTIF_SCR_HDL_START] = 0;
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 7;
- }
- }
- }
- break;
- // Store the retrieved Notification Source descriptors (namely, the CCCD).
- case ANCS_STORE_NS_DESCS_HANDLES:
- {
- LOG("Discovery Progress:\t7\n");
- LOG("Discovery State:\tStore the Notification Source's CCCD handle\n");
- // Wait for the discovery response.
- if (pMsg->method == ATT_FIND_INFO_RSP )
- {
- // Sanity check to validate that at least one descriptors pair was found,
- // and that the pair length is correct.
- 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)
- {
- // If so, store the handle in the handle cache, and proceed.
- pservie->chars_hdl[ANCS_NOTIF_SCR_HDL_CCCD] = pMsg->msg.findInfoRsp.info.btPair[currentPair].handle;
- pctx->disc_state = ANCS_DISC_DS_DESCS;
- }
- }
- }
- }
- }
- break;
- // Discover the Data Source's descriptors (namely, the CCCD) using the start
- // and end handle stored in the handle cache.
- case ANCS_DISC_DS_DESCS:
- {
- LOG("Discovery Progress:\t8\n");
- LOG("Discovery State:\tDiscover the Data Source's CCCD\n");
- // Wait until the Notification Source descriptors discovery has finished.
- if ( (pMsg->method == ATT_FIND_INFO_RSP) && (pMsg->hdr.status == bleProcedureComplete) )
- {
- // Discover ANCS Notification Source CCCD
- uint8_t discCheck = GATT_DiscAllCharDescs(pservie->conn_hdl,
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_START] + 1,
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_END],
- pctx->app_task_ID);
- // If the discovery was successful, proceed.
- if (discCheck == SUCCESS )
- pctx->disc_state = ANCS_STORE_DS_DESCS_HANDLES;
- // If not, throw an error and invalidate the CCCD handle in the handle cache.
- else
- {
- LOG("ANCS_DISC_DS_DESCS FAILURE\n");
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_CCCD] = 0;
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 8;
- }
- }
- }
- break;
- // Discover the Data Source's descriptors (namely, the CCCD) using the start
- // and end handle stored in the handle cache.
- case ANCS_STORE_DS_DESCS_HANDLES:
- {
- LOG("Discovery Progress:\t9\n");
- LOG("Discovery State:\tStore the Data Source's CCCD handle\n");
- // Wait for the discovery response.
- if (pMsg->method == ATT_FIND_INFO_RSP )
- {
- bool flg = FALSE;
- // Sanity check to validate that at least one descriptors pair was found,
- // and that the pair length is correct.
- 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)
- {
- // If so, store the handle in the handle cache, and proceed to the subscription process.
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_CCCD] = pMsg->msg.findInfoRsp.info.btPair[currentPair].handle;
- flg = TRUE;
- }
- }
- if(flg == FALSE){
- LOG("ANCS_STORE_DS_DESCS_HANDLES FAILURE\n");
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_CCCD] = 0;
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 9;
- }
- else{
- pctx->disc_state = ANCS_ENABLE_NS_CCCD;
- }
- }
- }
- }
- break;
- case ANCS_ENABLE_NS_CCCD:
- {
- bStatus_t ret;
- if (pMsg->method == ATT_FIND_INFO_RSP && (pMsg->hdr.status == bleProcedureComplete)){
- ret = Ancs_CCCDConfig(pservie->chars_hdl[ANCS_NOTIF_SCR_HDL_CCCD], TRUE);
- if(ret != SUCCESS){
- LOG("ANCS_DATA_SRC_HDL_CCCD FAILURE\n");
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_CCCD] = 0;
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 10;
- break;
- }
- pctx->disc_state = ANCS_ENABLE_DS_CCCD;
- }
- }
- case ANCS_ENABLE_DS_CCCD:
- {
- bStatus_t ret;
- if (pMsg->method == ATT_WRITE_RSP ){
- ret = Ancs_CCCDConfig(pservie->chars_hdl[ANCS_DATA_SRC_HDL_CCCD], TRUE);
- if(ret != SUCCESS){
- LOG("ANCS_DATA_SRC_HDL_CCCD FAILURE\n");
- pservie->chars_hdl[ANCS_DATA_SRC_HDL_CCCD] = 0;
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 10;
- break;
- }
- pctx->disc_state = ANCS_DISC_FINISH;
- pctx->app_state = ANCS_STATE_READY;
- //pctx->disc_state = ANCS_WAIT_CCCD_READY;
- }
- }
- break;
- case ANCS_WAIT_CCCD_READY:
- if (pMsg->method == ATT_WRITE_RSP ){
- pctx->disc_state = ANCS_DISC_FINISH;
- pctx->app_state = ANCS_STATE_READY;
-
- LOG("Discovery Progress:\t12\n");
- LOG("Discovery State:\tProcessing notification data\n");
- break;
- }
- default:
- {
- pctx->disc_state = ANCS_DISC_FAILED;
- errorcode = 11;
- }
- break;
- }
- if(errorcode != 0)
- {
- LOG("Discovery State:\tDiscovery Error: %d\n",errorcode);
- }
- return errorcode;
- }
- static uint8_t Ancs_CCCDConfig(uint16_t attrHdl, uint8_t isEnable)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- // Declare return variable status.
- uint8_t status;
- // Stores the GATT write request parameters.
- attWriteReq_t req;
- LOG("Ancs_CCCDConfig handle %d\n", attrHdl);
- // Else, prepare the request.
- // Set the data length to 2 ("01" = 2 bytes).
- req.len = 2;
- // If we are enabling notifications, set the write data to "01".
- if (isEnable == TRUE)
- {
- req.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);
- req.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);
- }
- // Else, disable notifications, thus set the write data to "00".
- else
- {
- req.value[0] = 0x00;
- req.value[1] = 0x00;
- }
- // Signature and command must be set to zero.
- req.sig = 0;
- req.cmd = 0;
- // Set the handle to the passed value (either the Notification Source's CCCD handle
- // or the Data Source's CCCD handle).
- req.handle = attrHdl;
- // Send write request. If it fails, free the memory allocated and
- // return a failure.
- status = GATT_WriteCharValue(pctx->ancs_service.conn_hdl, &req, pctx->app_task_ID);
- if ( status != SUCCESS){
- LOG("Ancs_CCCDConfig %d\n", status);
- }
- return status;
- }
- bStatus_t ble_ancs_start_descovery(uint16_t conn_handle)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- ancs_service_t* pservie = &(pctx->ancs_service);
- pservie->conn_hdl = conn_handle;
- pctx->disc_state = ANCS_DISC_SERVICE;
- pctx->app_state = ANCS_STATE_DISCOVERY;
- ble_disc_service(NULL);
- return SUCCESS;
- }
- static void ble_ancs_process_ds_notify(gattMsgEvent_t *pMsg)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
-
- ancs_parse_get_attrs_response(pctx, (const uint8_t*)pMsg->msg.handleValueNoti.value, pMsg->msg.handleValueNoti.len);
- return;
- }
- void ble_ancs_process_ns_notify(gattMsgEvent_t *pMsg)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- ancs_evt_t evt;
- ancs_notify_evt_t notify_msg;
- uint8_t len = pMsg->msg.handleValueNoti.len;
- if (len != 8)
- {
- LOG("\n");
- LOG("Error evt len\n");
- return;
- }
- // Create pointer to GATT notification data.
- uint8_t *packetData = pMsg->msg.handleValueNoti.value;
- // Store the ANCS notification's eventID
- notify_msg.eventID = packetData[0];
- // Store the ANCS notification's eventFlag
- notify_msg.eventFlag = packetData[1];
- // Store the ANCS notification's categoryID
- notify_msg.categoryID = packetData[2];
- notify_msg.categoryCount = packetData[3];
-
- // Notification UID from packetData[4] to packetData[7]
- notify_msg.notifUID[0] = packetData[ANCS_NOTIF_UID_LENGTH];
- notify_msg.notifUID[1] = packetData[ANCS_NOTIF_UID_LENGTH+1];
- notify_msg.notifUID[2] = packetData[ANCS_NOTIF_UID_LENGTH+2];
- notify_msg.notifUID[3] = packetData[ANCS_NOTIF_UID_LENGTH+3];
- evt.msg = (void*)(¬ify_msg);
- evt.len = sizeof(notify_msg);
- evt.type = BLE_ANCS_EVT_NOTIF;
- if(pctx->callback){
- pctx->callback(&evt);
- }
- }
- bStatus_t ble_ancs_get_notif_attrs(const uint8_t * pNotificationUID)
- {
- return notif_attrs_get(&s_ancs_ctx, pNotificationUID);
- }
- bStatus_t ble_ancs_get_app_attrs(const uint8_t * p_app_id, uint8_t app_id_len)
- {
- return app_attrs_get(&s_ancs_ctx, p_app_id, app_id_len);
- }
- bStatus_t ble_ancs_handle_gatt_event(gattMsgEvent_t* pMsg)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- ancs_service_t* pservie = &(pctx->ancs_service);
- if(pctx->app_state == ANCS_STATE_DISCOVERY)
- {
- ble_disc_service(pMsg);
- }
- else if (pMsg->method == ATT_HANDLE_VALUE_NOTI || pMsg->method == ATT_HANDLE_VALUE_IND)
- {
- // If we receive a GATT notification, we can assume it pertains to ANCS
- // because we only subscribe to notifications from the Notification Source
- // ancs Data Source.
- uint8_t notifHandle = pMsg->msg.handleValueNoti.handle;
- if ( notifHandle == pservie->chars_hdl[ANCS_NOTIF_SCR_HDL_START])
- {
- ble_ancs_process_ns_notify(pMsg);
- }
- else if ( notifHandle == pservie->chars_hdl[ANCS_DATA_SRC_HDL_START])
- {
- ble_ancs_process_ds_notify(pMsg);
- }
- }
- //If we have received a read or write response, assume that it is related to
- //CCCD configuration
- else if (pMsg->method == ATT_WRITE_RSP)
- {
- }
- // It's safe to free the incoming message
- return (TRUE);
- }
- bStatus_t ble_ancs_disconnect(void)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- uint8_t app_task_ID = pctx->app_task_ID;
- ancs_evt_hdl_t callback = pctx->callback;
- osal_memset(&s_ancs_ctx, 0, sizeof(s_ancs_ctx));
- pctx->app_task_ID = app_task_ID;
- pctx->callback = callback;
- return SUCCESS;
- }
- bStatus_t ble_ancs_init(ancs_evt_hdl_t evt_hdl, uint8_t task_ID)
- {
- ancs_ctx_t* pctx = &s_ancs_ctx;
- osal_memset(&s_ancs_ctx, 0, sizeof(s_ancs_ctx));
- pctx->app_task_ID = task_ID;
- pctx->callback = evt_hdl;
- return SUCCESS;
- }
|