/** **************************************************************************************** * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message. * The handler checks if the stream needs to be turned on. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Update the attribute value attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t*)&(param->value[0])); switch (STREAMDATAD_IDX(param->handle)) { case STREAMDATAD_IDX_ENABLE_VAL: streamdatad_streamonoff(); atts_write_rsp_send(streamdatad_env.conhdl, param->handle, PRF_ERR_OK); break; case STREAMDATAD_IDX_STREAMDATAD_D0_EN: case STREAMDATAD_IDX_STREAMDATAD_D1_EN: case STREAMDATAD_IDX_STREAMDATAD_D2_EN: case STREAMDATAD_IDX_STREAMDATAD_D3_EN: case STREAMDATAD_IDX_STREAMDATAD_D4_EN: case STREAMDATAD_IDX_STREAMDATAD_D5_EN: case STREAMDATAD_IDX_STREAMDATAD_D6_EN: case STREAMDATAD_IDX_STREAMDATAD_D7_EN: case STREAMDATAD_IDX_STREAMDATAD_D8_EN: case STREAMDATAD_IDX_STREAMDATAD_D9_EN: atts_write_rsp_send(streamdatad_env.conhdl, param->handle, PRF_ERR_OK); break; case STREAMDATAD_IDX_STREAMDATAD_D0_VAL: case STREAMDATAD_IDX_STREAMDATAD_D1_VAL: case STREAMDATAD_IDX_STREAMDATAD_D2_VAL: case STREAMDATAD_IDX_STREAMDATAD_D3_VAL: case STREAMDATAD_IDX_STREAMDATAD_D4_VAL: case STREAMDATAD_IDX_STREAMDATAD_D5_VAL: case STREAMDATAD_IDX_STREAMDATAD_D6_VAL: case STREAMDATAD_IDX_STREAMDATAD_D7_VAL: case STREAMDATAD_IDX_STREAMDATAD_D8_VAL: case STREAMDATAD_IDX_STREAMDATAD_D9_VAL: { struct streamdatad_rcv_data_packet_ind * ind = KE_MSG_ALLOC(STREAMDATAD_RCV_DATA_PACKET_IND, streamdatad_env.con_info.appid, dest_id, streamdatad_rcv_data_packet_ind); ind->conhdl = gapc_get_conhdl(streamdatad_env.con_info.conidx); ind->handle = param->handle; ind->seq = param->value[0]; // is already incrementing (with the dummy data of the test) ind->size = param->length; memcpy(&(ind->value[0]), &(param->value[0]), param->length); // Forward Received packet data to APP with the sequence number to indicate lost packets ke_msg_send(ind); } break; } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. * The handler will analyse what has been set and decide alert level * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t char_code = UDSS_ERR_CHAR; uint8_t status = PRF_APP_ERROR; if (KE_IDX_GET(src_id) == udss_env.con_info.conidx) { // uint8_t att_idx = GLPS_IDX(param->handle); status = PRF_ERR_OK; if (param->handle == udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL) { char_code = UDSS_USER_HEIGHT_CHAR; //Set User Height to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL, sizeof(uint8_t), (uint8_t *)¶m->value[0]); } else if (param->handle == udss_env.shdl + UDS_IDX_USER_AGE_VAL) { char_code = UDSS_USER_AGE_CHAR; //Set User Age to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_AGE_VAL, sizeof(uint8_t), (uint8_t *)¶m->value[0]); } else if (param->handle == udss_env.shdl + UDS_IDX_USER_DATE_OF_BIRTH_VAL) { char_code = UDSS_USER_DATE_OF_BIRTH_CHAR; //Set User Date of Birth to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_DATE_OF_BIRTH_VAL, sizeof(struct date), (uint8_t *)¶m->value[0]); } else if (param->handle == udss_env.shdl + UDS_IDX_USER_DB_CHANGE_INCR_VAL) { char_code = UDSS_USER_DB_CHANGE_INCR_CHAR; //Set User DB Change Increment to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_DB_CHANGE_INCR_VAL, sizeof(uint8_t), (uint8_t *)¶m->value[0]); } else if (param->handle == udss_env.shdl + UDS_IDX_USER_CTRL_POINT_VAL) { uint8_t reqstatus; uint8_t* value; uint16_t length; struct uds_ucp_req ucp_req; // Update the attribute value (note several write could be required since // attribute length > (ATT_MTU-3) attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t*)&(param->value[0])); // retrieve full data. attmdb_att_get_value(param->handle, &length, &value); // unpack user control point value reqstatus = udss_unpack_ucp_req(value, length, &ucp_req); // check unpacked status switch(reqstatus) { case PRF_APP_ERROR: { /* Do nothing, ignore request since it's not complete and maybe * requires several peer write to be performed. */ } break; case PRF_ERR_OK: { // check wich request shall be send to api task switch(ucp_req.op_code) { case UDS_REQ_REG_NEW_USER: case UDS_REQ_CONSENT: case UDS_REQ_DEL_USER_DATA: { //forward request operation to application struct udss_ucp_req_ind * req = KE_MSG_ALLOC(UDSS_UCP_REQ_IND, udss_env.con_info.appid, TASK_UDSS, udss_ucp_req_ind); // UCP on going. // UDSS_SET(UCP_ON_GOING); req->conhdl = gapc_get_conhdl(udss_env.con_info.conidx); req->ucp_req = ucp_req; ke_msg_send(req); } break; // case UDS_REQ_ABORT_OP: // { // // nothing to abort, send an error message. // struct uds_ucp_rsp ucp_rsp; // ucp_rsp.op_code = UDS_REQ_RSP_CODE; // ucp_rsp.operand.rsp.op_code_req = // ucp_req.op_code; // ucp_rsp.operand.rsp.status = UDS_RSP_ABORT_UNSUCCESSFUL; // // send user control response indication // udss_send_ucp_rsp(&(ucp_rsp), // TASK_UDSS); // } // break; default: { // nothing to do since it's handled during unpack } break; } } break; default: { /* There is an error in user control request, inform peer * device that request is incorrect. */ struct uds_ucp_rsp ucp_rsp; ucp_rsp.op_code = UDS_REQ_RSP_CODE; ucp_rsp.req_op_code = ucp_req.op_code; ucp_rsp.rsp_val = reqstatus; // send user control response indication udss_send_ucp_rsp(&(ucp_rsp), TASK_UDSS); } break; } } // not expected request else { status = ATT_ERR_WRITE_NOT_PERMITTED; } } if(param->response) { // Send Write Response atts_write_rsp_send(udss_env.con_info.conidx, param->handle, status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. * The handler compares the new values with current ones and notifies them if they changed. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Update the attribute value attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t*)&(param->value[0])); switch (ACCEL_IDX(param->handle)) { case ACCEL_IDX_ENABLE_VAL: { uint16_t len; uint8_t* accel_en; uint8_t* axis_en; uint8_t* range; if(*(uint8_t*)&(param->value[0]) > 1) accel_threshold = *(uint8_t*)&(param->value[0]) - 2; // set_accel_thr(); attmdb_att_get_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), &(len), &(accel_en)); // Indicate to the application the state of the profile if (accel_en) { // Allocate the start indication message struct accel_start_ind *ind = KE_MSG_ALLOC(ACCEL_START_IND, accel_env.con_info.appid, dest_id, accel_start_ind); // Fill in the parameter structure for (int i = 0; i < ACCEL_MAX; i++) { attmdb_att_get_value(ACCEL_DIR_VAL_HANDLE(i), &(len), &(axis_en)); ind->accel_en[i] = *axis_en; } attmdb_att_get_value(ACCEL_HANDLE(ACCEL_IDX_RANGE_VAL), &(len), &(range)); ind->range = *range; // Send the message ke_msg_send(ind); } else { // Send the stop indication ke_msg_send_basic(ACCEL_STOP_IND, accel_env.con_info.appid, TASK_ACCEL); } } break; case ACCEL_IDX_ACCEL_DISPLAY1_VAL: case ACCEL_IDX_ACCEL_DISPLAY2_VAL: if(*(uint8_t*)&(param->value[0]) == 0xFF) { if(param->length > 1 && *(uint8_t*)&(param->value[1]) > 1) accel_con_interval = *(uint8_t*)&(param->value[1]); if(param->length > 2 && *(uint8_t*)&(param->value[2]) > 1) accel_mode = *(uint8_t*)&(param->value[2])-2; if(param->length > 3 && *(uint8_t*)&(param->value[3]) > 1) accel_latency = *(uint8_t*)&(param->value[3])-2; if(param->length > 4 && *(uint8_t*)&(param->value[4]) > 1) accel_window = *(uint8_t*)&(param->value[4]); } { uint8_t line; uint16_t len; uint8_t* display; struct accel_write_line_ind *ind = KE_MSG_ALLOC(ACCEL_WRITE_LINE_IND, accel_env.con_info.appid, TASK_ACCEL, accel_write_line_ind); line = (param->handle == ACCEL_HANDLE(ACCEL_IDX_ACCEL_DISPLAY1_VAL))?0:1; attmdb_att_get_value(param->handle, &(len), &(display)); // Fill in the parameter structure memcpy(ind->text, display, len); ind->line = line; // Send the message ke_msg_send(ind); } atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK); break; case ACCEL_IDX_ACCEL_X_VAL: case ACCEL_IDX_ACCEL_X_EN: if(*(uint8_t*)&(param->value[0]) > 1) accel_adv_interval1 = *(uint8_t*)&(param->value[0]); atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK); break; case ACCEL_IDX_ACCEL_Y_VAL: case ACCEL_IDX_ACCEL_Y_EN: if(*(uint8_t*)&(param->value[0]) > 1) accel_adv_interval2 = *(uint8_t*)&(param->value[0]); if(*(uint8_t*)&(param->value[0]) == 255) accel_adv_interval2 = 0; atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK); break; case ACCEL_IDX_ACCEL_Z_VAL: case ACCEL_IDX_ACCEL_Z_EN: if(*(uint8_t*)&(param->value[0]) > 1) accel_adv_interval3 = *(uint8_t*)&(param->value[0]); if(*(uint8_t*)&(param->value[0]) == 255) accel_adv_interval3 = 0; atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK); break; default: atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK); break; } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. * The handler will * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t value = 0x0000; uint8_t char_code = HPS_ERR_CHAR; uint8_t status = PRF_APP_ERROR; if (KE_IDX_GET(src_id) == hpss_env.con_info.conidx) { if (param->handle == hpss_env.hps_shdl + HPS_IDX_URI_VAL) { char_code = HPS_URI_CHAR; } else if (param->handle == hpss_env.hps_shdl + HPS_IDX_HEADER_VAL) { char_code = HPS_HEADER_CHAR; } else if (param->handle == hpss_env.hps_shdl + HPS_IDX_BODY_VAL) { char_code = HPS_BODY_CHAR; } else if (param->handle == hpss_env.hps_shdl + HPS_IDX_CNTL_PT_VAL) { char_code = HPS_CNTL_PT_CHAR; } //this case is processed seperately else if (param->handle == hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_CFG) { //Extract value before check memcpy(&value, &(param->value), sizeof(uint16_t)); if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF)) { status = PRF_ERR_OK; if (value == PRF_CLI_STOP_NTFIND) { hpss_env.features &= ~HPSS_STATUS_CODE_NTF_CFG; } else //PRF_CLI_START_NTF { hpss_env.features |= HPSS_STATUS_CODE_NTF_CFG; } } else { status = PRF_APP_ERROR; } if (status == PRF_ERR_OK) { //Update the attribute value attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value); if(param->last) { //Inform APP of configuration change struct hpss_cfg_indntf_ind * ind = KE_MSG_ALLOC(HPSS_CFG_INDNTF_IND, hpss_env.con_info.appid, TASK_HPSS, hpss_cfg_indntf_ind); ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx); memcpy(&ind->cfg_val, &value, sizeof(uint16_t)); ke_msg_send(ind); } } //If HPS, send write response if (param->response != 0x00) { // Send Write Response atts_write_rsp_send(hpss_env.con_info.conidx, param->handle, status); } return (KE_MSG_CONSUMED); } if (char_code != HPS_ERR_CHAR) { //Save value in DB attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)¶m->value[0]); status = PRF_ERR_OK; switch(char_code) { case HPS_URI_CHAR: if ((param->length + param->offset) <= HPS_URI_MAX_LEN) { // First part of the uri value if (param->offset == 0) { // Set value in the database attmdb_att_set_value(param->handle, param->length, (uint8_t *)¶m->value[0]); } else { // Complete the value stored in the database attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t *)¶m->value[0]); } if(param->last) { uint16_t len = 0; uint8_t *data = NULL; // Get complete uri value and length attmdb_att_get_value(param->handle, &len, &data); // Inform APP. Allocate the URI value change indication struct hpss_uri_ind *ind = KE_MSG_ALLOC(HPSS_URI_IND, hpss_env.con_info.appid, TASK_HPSS, hpss_uri_ind); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx); ind->char_code = HPS_URI_CHAR; ind->len = len; memcpy(&ind->uri, data, len); ke_msg_send(ind); } } break; case HPS_HEADER_CHAR: if ((param->length + param->offset) <= HPS_HEADER_MAX_LEN) { // First part of the uri value if (param->offset == 0) { // Set value in the database attmdb_att_set_value(param->handle, param->length, (uint8_t *)¶m->value[0]); } else { // Complete the value stored in the database attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t *)¶m->value[0]); } if(param->last) { uint16_t len = 0; uint8_t *data = NULL; // Get complete uri value and length attmdb_att_get_value(param->handle, &len, &data); // Inform APP. Allocate the URI value change indication struct hpss_header_ind *ind = KE_MSG_ALLOC(HPSS_HEADER_IND, hpss_env.con_info.appid, TASK_HPSS, hpss_header_ind); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx); ind->char_code = HPS_HEADER_CHAR; ind->len = len; memcpy(&ind->header, data, len); ke_msg_send(ind); } } break; case HPS_BODY_CHAR: if ((param->length + param->offset) <= HPS_BODY_MAX_LEN) { // First part of the uri value if (param->offset == 0) { // Set value in the database attmdb_att_set_value(param->handle, param->length, (uint8_t *)¶m->value[0]); } else { // Complete the value stored in the database attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t *)¶m->value[0]); } if(param->last) { uint16_t len = 0; uint8_t *data = NULL; // Get complete uri value and length attmdb_att_get_value(param->handle, &len, &data); // Inform APP. Allocate the URI value change indication struct hpss_body_ind *ind = KE_MSG_ALLOC(HPSS_BODY_IND, hpss_env.con_info.appid, TASK_HPSS, hpss_body_ind); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx); ind->char_code = HPS_BODY_CHAR; ind->len = len; memcpy(&ind->body, data, len); ke_msg_send(ind); } } break; case HPS_CNTL_PT_CHAR: if ((param->length + param->offset) <= HPS_CNTL_PT_MAX_LEN) { // First part of the uri value if (param->offset == 0) { // Set value in the database attmdb_att_set_value(param->handle, param->length, (uint8_t *)¶m->value[0]); } else { // Complete the value stored in the database attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t *)¶m->value[0]); } if(param->last) { uint16_t len = 0; uint8_t *data = NULL; // Get complete uri value and length attmdb_att_get_value(param->handle, &len, &data); // Inform APP. Allocate the URI value change indication struct hpss_cntl_pt_ind *ind = KE_MSG_ALLOC(HPSS_CNTL_PT_IND, hpss_env.con_info.appid, TASK_HPSS, hpss_cntl_pt_ind); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx); ind->char_code = HPS_CNTL_PT_CHAR; ind->len = len; memcpy(&ind->cntl_pt, data, len); ke_msg_send(ind); } } break; default: break; } //If HPS, send write response if (param->response != 0x00) { // Send Write Response atts_write_rsp_send(hpss_env.con_info.conidx, param->handle, status); } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. * The handler compares the new values with current ones and notifies them if they changed. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = ATT_ERR_INSUFF_AUTHOR; // check connection if (KE_IDX_GET(src_id) == glps_env.con_info.conidx) { uint8_t att_idx = GLPS_IDX(param->handle); status = PRF_ERR_OK; // check if it's a client configuration char if(glps_att_db[att_idx].uuid == ATT_DESC_CLIENT_CHAR_CFG) { uint16_t cli_cfg; uint8_t evt_mask = GLPS_IND_NTF_EVT(att_idx); // get client configuration cli_cfg = co_read16(&(param->value)); // stop indication/notification if(cli_cfg == PRF_CLI_STOP_NTFIND) { glps_env.evt_cfg &= ~evt_mask; } // start indication/notification (check that char value accept it) else if((((glps_att_db[att_idx-1].perm & PERM(IND, ENABLE)) != 0) && cli_cfg == PRF_CLI_START_IND) ||(((glps_att_db[att_idx-1].perm & PERM(NTF, ENABLE)) != 0) && cli_cfg == PRF_CLI_START_NTF)) { glps_env.evt_cfg |= evt_mask; } // improper value else { status = GLP_ERR_IMPROPER_CLI_CHAR_CFG; } if (status == PRF_ERR_OK) { //Inform APP of configuration change struct glps_cfg_indntf_ind * ind = KE_MSG_ALLOC(GLPS_CFG_INDNTF_IND, glps_env.con_info.appid, TASK_GLPS, glps_cfg_indntf_ind); //Update the attribute value attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&cli_cfg); ind->conhdl = gapc_get_conhdl(glps_env.con_info.conidx); ind->evt_cfg = glps_env.evt_cfg; ke_msg_send(ind); } } else if (glps_att_db[att_idx].uuid == ATT_CHAR_REC_ACCESS_CTRL_PT) { uint8_t reqstatus; uint8_t* value; uint16_t length; struct glp_racp_req racp_req; if((glps_env.evt_cfg & GLPS_RACP_IND_CFG) == 0) { // do nothing since indication not enabled for this characteristic status = GLP_ERR_IMPROPER_CLI_CHAR_CFG; } // If a request is on going else if(GLPS_IS(RACP_ON_GOING)) { // if it's an abort command, execute it. if((param->offset == 0) && (param->value[0] == GLP_REQ_ABORT_OP)) { //forward abort operation to application struct glps_racp_req_ind * req = KE_MSG_ALLOC(GLPS_RACP_REQ_IND, glps_env.con_info.appid, TASK_GLPS, glps_racp_req_ind); req->conhdl = gapc_get_conhdl(glps_env.con_info.conidx); req->racp_req.op_code = GLP_REQ_ABORT_OP; req->racp_req.filter.operator = 0; ke_msg_send(req); } else { // do nothing since a procedure already in progress status = GLP_ERR_PROC_ALREADY_IN_PROGRESS; } } else { // Update the attribute value (note several write could be required since // attribute length > (ATT_MTU-3) attmdb_att_update_value(param->handle, param->length, param->offset, (uint8_t*)&(param->value[0])); // retrieve full data. attmdb_att_get_value(param->handle, &length, &value); // unpack record access control point value reqstatus = glps_unpack_racp_req(value, length, &racp_req); // check unpacked status switch(reqstatus) { case PRF_APP_ERROR: { /* Do nothing, ignore request since it's not complete and maybe * requires several peer write to be performed. */ } break; case PRF_ERR_OK: { // check wich request shall be send to api task switch(racp_req.op_code) { case GLP_REQ_REP_STRD_RECS: case GLP_REQ_DEL_STRD_RECS: case GLP_REQ_REP_NUM_OF_STRD_RECS: { //forward request operation to application struct glps_racp_req_ind * req = KE_MSG_ALLOC(GLPS_RACP_REQ_IND, glps_env.con_info.appid, TASK_GLPS, glps_racp_req_ind); // RACP on going. GLPS_SET(RACP_ON_GOING); req->conhdl = gapc_get_conhdl(glps_env.con_info.conidx); req->racp_req = racp_req; ke_msg_send(req); } break; case GLP_REQ_ABORT_OP: { // nothing to abort, send an error message. struct glp_racp_rsp racp_rsp; racp_rsp.op_code = GLP_REQ_RSP_CODE; racp_rsp.operand.rsp.op_code_req = racp_req.op_code; racp_rsp.operand.rsp.status = GLP_RSP_ABORT_UNSUCCESSFUL; // send record access control response indication glps_send_racp_rsp(&(racp_rsp), TASK_GLPS); } break; default: { // nothing to do since it's handled during unpack } break; } } break; default: { /* There is an error in record access control request, inform peer * device that request is incorrect. */ struct glp_racp_rsp racp_rsp; racp_rsp.op_code = GLP_REQ_RSP_CODE; racp_rsp.operand.rsp.op_code_req = racp_req.op_code; racp_rsp.operand.rsp.status = reqstatus; // send record access control response indication glps_send_racp_rsp(&(racp_rsp), TASK_GLPS); } break; } } } // not expected request else { status = ATT_ERR_WRITE_NOT_PERMITTED; } } if(param->response) { //Send write response atts_write_rsp_send(glps_env.con_info.conidx, param->handle, status); } return (KE_MSG_CONSUMED); }