Esempio n. 1
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HRPS_ENABLE_REQ message.
 * The handler enables the Heart Rate Sensor Profile.
 * @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 hrps_enable_req_handler(ke_msg_id_t const msgid,
                                   struct hrps_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    uint16_t value = 0;

    // Save the application task id
    hrps_env.con_info.appid = src_id;
    // Save the connection handle associated to the profile
    hrps_env.con_info.conidx = gapc_get_conidx(param->conhdl);

    // Check if the provided connection exist
    if (hrps_env.con_info.conidx == GAP_INVALID_CONIDX)
    {
        // The connection doesn't exist, request disallowed
        prf_server_error_ind_send((prf_env_struct *)&hrps_env, PRF_ERR_REQ_DISALLOWED,
                                  HRPS_ERROR_IND, HRPS_ENABLE_REQ);
    }
    else
    {
        // If this connection is a not configuration one, apply config saved by app
        if(param->con_type == PRF_CON_NORMAL)
        {
            value = param->hr_meas_ntf_en;

            if (param->hr_meas_ntf_en == PRF_CLI_START_NTF)
            {
                hrps_env.features |= HRPS_HR_MEAS_NTF_CFG;
            }
        }

        //Set HR Meas. Char. NTF Configuration in DB
        attmdb_att_set_value(hrps_env.shdl + HRS_IDX_HR_MEAS_NTF_CFG, sizeof(uint16_t),
                             (uint8_t *)&value);

        if (HRPS_IS_SUPPORTED(HRPS_BODY_SENSOR_LOC_CHAR_SUP))
        {
            //Set Body Sensor Location Char Value in DB - Not supposed to change during connection
            attmdb_att_set_value(hrps_env.shdl + HRS_IDX_BOBY_SENSOR_LOC_VAL, sizeof(uint8_t),
                                 (uint8_t *)&param->body_sensor_loc);
        }

        // Enable Service + Set Security Level
        attmdb_svc_set_permission(hrps_env.shdl, param->sec_lvl);

        // Go to connected state
        ke_state_set(TASK_HRPS, HRPS_CONNECTED);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 2
0
/**
 ****************************************************************************************
 * @brief Enable the Sample128 role, used after connection.
 * @param[in] msgid     Id of the message received.
 * @param[in] param     Pointer to the parameters of the message.
 * @param[in] dest_id   ID of the receiving task instance
 * @param[in] src_id    ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int sample128_enable_req_handler(ke_msg_id_t const msgid,
                                    struct sample128_enable_req const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    
    uint16_t temp = 1;
    
    // Keep source of message, to respond to it further on
    sample128_env.con_info.appid = src_id;
    // Store the connection handle for which this profile is enabled
    sample128_env.con_info.conidx = gapc_get_conidx(param->conhdl);

    // Check if the provided connection exist
    if (sample128_env.con_info.conidx == GAP_INVALID_CONIDX)
    {
        // The connection doesn't exist, request disallowed
        prf_server_error_ind_send((prf_env_struct *)&sample128_env, PRF_ERR_REQ_DISALLOWED,
                 SAMPLE128_ERROR_IND, SAMPLE128_ENABLE_REQ);
    }
    else
    {
        // Sample128 1
        attmdb_svc_set_permission(sample128_env.sample128_shdl, param->sec_lvl);

        //set char 1 to specified value
        attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_1_IDX_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->sample128_1_val);
        
        attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->sample128_2_val);

        sample128_env.feature = param->feature; 
        
        if (!sample128_env.feature)
        {
               temp = 0;
        }
        
        attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_CFG,
                             sizeof(uint16_t), (uint8_t *)&temp);
        
        // Go to Connected state
        ke_state_set(TASK_SAMPLE128, SAMPLE128_CONNECTED);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPS_UPD_REF_TIME_INFO_REQ message.
 * @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 tips_upd_ref_time_info_req_handler(ke_msg_id_t const msgid,
                                              struct tips_upd_ref_time_info_req const *param,
                                              ke_task_id_t const dest_id,
                                              ke_task_id_t const src_id)
{
    // Status
    uint8_t status = PRF_ERR_INVALID_PARAM;

    // Get the address of the environment
    struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx);

    // Check the Connection Handle
    if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx))
    {
        // Check if the Reference Time Info Char. has been added in the database
        if (TIPS_IS_SUPPORTED(TIPS_CTS_REF_TIME_INFO_SUP))
        {
            status = attmdb_att_set_value(tips_env.cts_shdl + tips_env.cts_att_tbl[CTS_REF_TIME_INFO_CHAR] + 1,
                                          sizeof(struct tip_ref_time_info), (uint8_t *)&(param->ref_time_info));
        }
        else
        {
            status = PRF_ERR_FEATURE_NOT_SUPPORTED;
        }
    }

    if (status != PRF_ERR_OK)
    {
        //Wrong Connection Handle
        tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_REF_TIME_INFO_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 4
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref ACCEL_VALUE_REQ 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 accel_value_req_handler(ke_msg_id_t const msgid,
                                   struct accel_value_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
//    uint16_t len;
//    uint16_t* axis_en;
//    uint8_t* axis_val;

    // Check if acceleration changed on each axis and notify it if required
    for (int i = 0; i < ACCEL_MAX; i++)
    {
        //attmdb_att_get_value(ACCEL_DIR_VAL_HANDLE(i), &(len), (uint8_t**)&(axis_val));	////gsx
        //attmdb_att_get_value(ACCEL_DIR_EN_HANDLE(i), &(len), (uint8_t**)&(axis_en));	////gsx

        //if ((*axis_en) && (param->accel[i] != *axis_val))	////gsx
        {
            // Update the value in the attribute database
            attmdb_att_set_value(ACCEL_DIR_VAL_HANDLE(i),   sizeof(uint16_t), (uint8_t*) &(param->accel[i]));//gsx  sizeof(uint8_t), (uint8_t*) &(param->accel[i]

            // Send notification
            prf_server_send_event((prf_env_struct *)&accel_env, false, ACCEL_DIR_VAL_HANDLE(i));

        }
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 5
0
static int sample128_upd_char2_req_handler(ke_msg_id_t const msgid,
                                    struct sample128_upd_char2_req const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    uint8_t status = PRF_ERR_OK;

    // Check provided values
    if(param->conhdl == gapc_get_conhdl(sample128_env.con_info.conidx))
    {
        // Update value in DB
        attmdb_att_set_value(sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->val);

        if((sample128_env.feature & PRF_CLI_START_NTF))
            // Send notification through GATT
            prf_server_send_event((prf_env_struct *)&sample128_env, false,
                    sample128_env.sample128_shdl + SAMPLE128_2_IDX_VAL);
        
    }
    else
    {
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        sample128_upd_char2_cfm_send(status);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 6
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPS_UPD_TIME_UPD_STATE_REQ message.
 * @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 tips_upd_time_upd_state_req_handler(ke_msg_id_t const msgid,
                                              struct tips_upd_time_upd_state_req const *param,
                                              ke_task_id_t const dest_id,
                                              ke_task_id_t const src_id)
{
    // Status
    uint8_t status = PRF_ERR_INVALID_PARAM;

    // Get the address of the environment
    struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx);

    // Check the provided Connection Handle
    if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx))
    {
        // Check if the Reference Time Update Service is supported
        if (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP))
        {
            status = attmdb_att_set_value(tips_env.rtus_shdl + RTUS_IDX_TIME_UPD_STATE_VAL,
                                          sizeof(struct tip_time_upd_state), (uint8_t *)&(param->time_upd_state));
        }
        else
        {
            status = PRF_ERR_FEATURE_NOT_SUPPORTED;
        }
    }

    if (status != PRF_ERR_OK)
    {
        //Wrong Connection Handle
        tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_TIME_UPD_STATE_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 7
0
/**
 ****************************************************************************************
 * @brief Request to update Measurement Interval Value
 * @param[in] msgid     Id of the message received.
 * @param[in] param     Pointer to the parameters of the message.
 * @param[in] dest_id   ID of the receiving task instance
 * @param[in] src_id    ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int htpt_meas_intv_upd_req_handler(ke_msg_id_t const msgid,
                                          struct htpt_meas_intv_upd_req const *param,
                                          ke_task_id_t const dest_id,
                                          ke_task_id_t const src_id)
{
    uint16_t handle;

    //Check if Measurement Interval is supported
    if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00)
    {
        //Check Connection Handle
        if(param->conhdl == gapc_get_conhdl(htpt_env.con_info.conidx))
        {
            handle = htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1;

            //Update saved value in database
            attmdb_att_set_value(handle, sizeof(param->meas_intv), (uint8_t *)&param->meas_intv);

            //Must be indicated if enabled
            if((htpt_env.features & HTPT_MASK_MEAS_INTV_CFG) == HTPT_MASK_MEAS_INTV_CFG)
            {
                prf_server_send_event((prf_env_struct *)&htpt_env, true, handle);
            }
        }
        else
        {
            //Wrong Connection Handle
            prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_INVALID_PARAM,
                                      HTPT_ERROR_IND, HTPT_MEAS_INTV_UPD_REQ);
        }
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 8
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref UDSS_ENABLE_REQ message.
 * @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 udss_enable_req_handler(ke_msg_id_t const msgid,
                                   struct udss_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    //Save the connection handle associated to the profile
    udss_env.con_info.conidx = gapc_get_conidx(param->conhdl);
    //Save the application id
    udss_env.con_info.appid = src_id;

    // Check if the provided connection exist
    if (udss_env.con_info.conidx == GAP_INVALID_CONIDX)
    {
        // The connection doesn't exist, request disallowed
        prf_server_error_ind_send((prf_env_struct *)&udss_env, PRF_ERR_REQ_DISALLOWED,
                                  UDSS_ERROR_IND, UDSS_ENABLE_REQ);
    }
    else
    {
        //Enable Attributes + Set Security Level
        attmdb_svc_set_permission(udss_env.shdl, param->sec_lvl);

        //Set User Height to specified value
        attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->user_height);

        //Set User Age to specified value
        attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_AGE_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->user_age);
			
				//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 *)&param->user_date_of_birth);
			
				//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 *)&param->user_db_change_incr);

				
        // Go to connected state
        ke_state_set(TASK_UDSS, UDSS_CONNECTED);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 9
0
void streamdatad_streamonoff(void)
{
    uint16_t len = 0;
    uint8_t* streamdatad_en = NULL;

    attmdb_att_get_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_ENABLE_VAL), &(len), &(streamdatad_en));


    // Indicate to the application the state of the profile
    int on = ((len == 2) && (streamdatad_en && (*streamdatad_en))) ? 1 : 0;

    if (on)
    {
        // Allocate the start indication message
        struct streamdatad_start_ind *ind = KE_MSG_ALLOC(STREAMDATAD_START_IND,
                                            streamdatad_env.appid, TASK_STREAMDATAD,
                                            streamdatad_start_ind);
        streamdatad_env.stream_enabled = (*streamdatad_en);
        ind->status = PRF_ERR_OK;
        // Send the message
        ke_msg_send(ind);
    }
    else
    {
        streamdatad_env.next_attribute_idx = 0;
        streamdatad_env.stream_enabled = 0;

        // Send the stop indication
        ke_msg_send_basic(STREAMDATAD_STOP_IND, streamdatad_env.appid, TASK_STREAMDATAD);
    }

    uint16_t enable_val = streamdatad_en?(*streamdatad_en):0;
    // Enable or disable all data notifications
    streamdatad_env.nr_enabled_attributes = 0;
    int lastattr = enable_val?((STREAMDATAD_MAX>MAX_TRANSMIT_BUFFER_PACKETS)?MAX_TRANSMIT_BUFFER_PACKETS:STREAMDATAD_MAX):STREAMDATAD_MAX;

    attmdb_att_set_value(STREAMDATAD_IDX_ENABLE_EN, sizeof(uint16_t),(uint8_t*) &(enable_val));
    for (int i = 0; i < lastattr; i++)
    {
        attmdb_att_set_value(STREAMDATAD_DIR_EN_HANDLE(i), sizeof(uint16_t),(uint8_t*) &(enable_val));
        streamdatad_env.nr_enabled_attributes++;
    }
    if (!enable_val) streamdatad_env.nr_enabled_attributes = 0;
}
Esempio n. 10
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * @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 = ADC_NOTIFY_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == adc_notify_env.con_info.conidx)
    {
                
        if (param->handle == adc_notify_env.adc_notify_shdl + ADC_NOTIFY_IDX_CFG)
        {
            char_code = ADC_NOTIFY_CFG;
        }
        
        if (char_code == ADC_NOTIFY_CFG)
        {
            
            // Written value
            uint16_t ntf_cfg;

            // Extract value before check
            ntf_cfg = co_read16p(&param->value[0]);
        
            // Only update configuration if value for stop or notification enable
            if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))
            {
                //Save value in DB
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&param->value[0]);
                
                // Conserve information in environment
                if (ntf_cfg == PRF_CLI_START_NTF)
                {
                    // Ntf cfg bit set to 1
                    adc_notify_env.feature |= PRF_CLI_START_NTF;
                }
                else
                {
                    // Ntf cfg bit set to 0
                    adc_notify_env.feature &= ~PRF_CLI_START_NTF;
                }                
                
                adc_notify_send_cfg(ntf_cfg);
                
                status = PRF_ERR_OK; 
                
            }
        }
    }

    // Send Write Response
    atts_write_rsp_send(adc_notify_env.con_info.conidx, param->handle, status);
    
    return (KE_MSG_CONSUMED);
}
Esempio n. 11
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPS_UPD_CURR_TIME_REQ message.
 * @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 tips_upd_curr_time_req_handler(ke_msg_id_t const msgid,
                                          struct tips_upd_curr_time_req const *param,
                                          ke_task_id_t const dest_id,
                                          ke_task_id_t const src_id)
{
    // Packed Current Time value
    uint8_t pckd_time[CTS_CURRENT_TIME_VAL_LEN];
    // Status
    uint8_t status = PRF_ERR_INVALID_PARAM;

    // Get the address of the environment
    struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx);

    if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx))
    {
        // Pack the Current Time value
        tips_pack_curr_time_value(&pckd_time[0], &param->current_time);
        // Set the value in the database
        status = attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_CURRENT_TIME_VAL,
                                      CTS_CURRENT_TIME_VAL_LEN, (uint8_t *)&pckd_time[0]);

        //Check if Notifications are enabled
        if ((tips_idx_env->ntf_state & TIPS_CTS_CURRENT_TIME_CFG) == TIPS_CTS_CURRENT_TIME_CFG)
        {
            //Check if notification can be sent
            if ((param->current_time.adjust_reason & TIPS_FLAG_EXT_TIME_UPDATE) == TIPS_FLAG_EXT_TIME_UPDATE)
            {
                if (param->enable_ntf_send == 0)
                {
                    status = PRF_ERR_REQ_DISALLOWED;
                }
            }

            if (status == PRF_ERR_OK)
            {
                // The notification can be sent, send the notification
                prf_server_send_event((prf_env_struct *)tips_idx_env, false,
                                      tips_env.cts_shdl + CTS_IDX_CURRENT_TIME_VAL);
            }
        }
        else
        {
            status = PRF_ERR_NTF_DISABLED;
        }
    }

    if (status != PRF_ERR_OK)
    {
        // Wrong Connection Handle
        tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_CURR_TIME_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 12
0
int streamdatad_send_data_packets_req_handler(ke_msg_id_t const msgid,
                                   struct streamdatad_send_data_packets_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
	uint16_t next_packet;
	uint16_t nr_packets;
    uint16_t* packet_buffer_enabled;
    uint16_t len = 0;

	if (!streamdatad_env.stream_enabled) return KE_MSG_CONSUMED; 

	next_packet = 0;
	nr_packets = param->nr_packets;

    nb_buf_av = l2cm_get_nb_buffer_available();
    
    for (int li = 0; (li < STREAMDATAD_MAX) && (nr_packets > 0) && (nb_buf_av > 0); li++)
	{		
        packet_buffer_enabled = NULL;
        attmdb_att_get_value(STREAMDATAD_DIR_EN_HANDLE(streamdatad_env.next_attribute_idx), &(len), (uint8_t**)&(packet_buffer_enabled));
        
        if ((packet_buffer_enabled && (*packet_buffer_enabled)))
        {        
            // Update the value in the attribute database
            attmdb_att_set_value(STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx), sizeof(uint8_t) * STREAMDATAD_PACKET_SIZE, (uint8_t*) &(param->packets[next_packet][0]));

            // Send notification
            prf_server_send_event((prf_env_struct *)&(streamdatad_env.con_info), false, STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx));
        }
        else
        {
            len = 2;
        }
        
        //set_pxact_gpio();
        next_packet++; nr_packets--;
        nb_buf_av--;
        
        streamdatad_env.next_attribute_idx++; 
        if (streamdatad_env.next_attribute_idx >= STREAMDATAD_MAX) {
            
            streamdatad_env.next_attribute_idx = 0;
            break; // the for loop
        }
        
		// else notification at this index was not enabled;
    }
    //set_pxact_gpio();
    return (KE_MSG_CONSUMED);
}
Esempio n. 13
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref UDSS_SET_CHAR_VAL_REQ message.
 * @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 udss_set_char_val_req_handler(ke_msg_id_t const msgid,
                                         struct udss_set_char_val_req const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id)
{
    // Request status
    uint8_t status;
    // Characteristic Declaration attribute handle
    uint16_t handle;

    //Save the application task id
    udss_env.con_info.appid = src_id;

    // Check Characteristic Code
    if (param->char_code <= 0)//UDS_PNP_ID_CHAR)
    {
        // Get Characteristic Declaration attribute handle
        handle = udss_env.shdl + udss_env.att_tbl[param->char_code];

        // Check if the Characteristic exists in the database
        if (handle != PRF_ERR_INEXISTENT_HDL)
        {
            // Check the value length
//            status = udss_check_val_len(param->char_code, param->val_len);

            if (status == PRF_ERR_OK)
            {
                // Set value in the database
                attmdb_att_set_value(handle + 1, param->val_len, (uint8_t *)&param->val[0]);
            }
        }
        else
        {
            status = PRF_ERR_INEXISTENT_HDL;
        }
    }
    else
    {
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        // Status is PRF_ERR_INVALID_PARAM or PRF_ERR_UNEXPECTED_LEN or PRF_ERR_INEXISTENT_HDL
        prf_server_error_ind_send((prf_env_struct *)&udss_env, status,
                                  UDSS_ERROR_IND, UDSS_SET_CHAR_VAL_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 14
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HRPS_MEAS_SEND_REQ message.
 * @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 hrps_meas_send_req_handler(ke_msg_id_t const msgid,
                                      struct hrps_meas_send_req const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    // Status
    uint8_t status = PRF_ERR_OK;
    // Packed Heart Measurement Value
    uint8_t packed_hr[HRPS_HT_MEAS_MAX_LEN];
    // Packet size
    uint8_t size;

    if((param->conhdl == gapc_get_conhdl(hrps_env.con_info.conidx))
            && (param->meas_val.nb_rr_interval <= HRS_MAX_RR_INTERVAL))
    {
        //Pack the HR Measurement value
        size = hrps_pack_meas_value(&packed_hr[0], &param->meas_val);

        // Check if notifications are enabled
        if(HRPS_IS_SUPPORTED(HRPS_HR_MEAS_NTF_CFG))
        {
            //Update value in DB
            attmdb_att_set_value(hrps_env.shdl + HRS_IDX_HR_MEAS_VAL,
                                 size, &packed_hr[0]);

            //send notification through GATT
            prf_server_send_event((prf_env_struct *)&hrps_env, false,
                    hrps_env.shdl + HRS_IDX_HR_MEAS_VAL);
        }
        //notification not enabled, simply don't send anything
        else
        {
            status = PRF_ERR_NTF_DISABLED;
        }
    }
    else
    {
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        // Value has not been sent
        hrps_meas_send_cfm_send(status);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 15
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HTPT_TEMP_TYPE_UPD_REQ 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 htpt_temp_type_upd_req_handler(ke_msg_id_t const msgid,
                                          struct htpt_temp_type_upd_req const *param,
                                          ke_task_id_t const dest_id,
                                          ke_task_id_t const src_id)
{
    if (htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] != 0x00)
    {
        //Update value in database
        attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] + 1,
                             sizeof(param->value), (uint8_t *)&(param->value));
    }
    else
    {
        prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_FEATURE_NOT_SUPPORTED,
                                  HTPT_ERROR_IND, HTPT_TEMP_TYPE_UPD_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 16
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref BAPS_BATT_LEVEL_SEND_REQ message.
 * @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 bass_batt_level_upd_req_handler(ke_msg_id_t const msgid,
                                            struct bass_batt_level_upd_req const *param,
                                            ke_task_id_t const dest_id,
                                            ke_task_id_t const src_id)
{
    uint8_t status = PRF_ERR_OK;

    // Check provided values
    if((param->conhdl == gapc_get_conhdl(bass_env.con_info.conidx)) &&
       (param->bas_instance < bass_env.bas_nb)     &&
       (param->batt_level <= BAS_BATTERY_LVL_MAX))
    {
        // Update Battery Level value in DB
        attmdb_att_set_value(bass_env.shdl[param->bas_instance] + BAS_IDX_BATT_LVL_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->batt_level);

        // Check if notifications are enabled
        if((bass_env.features[param->bas_instance] & BASS_FLAG_NTF_CFG_BIT)
                                                  == BASS_FLAG_NTF_CFG_BIT)
        {
            // Send notification through GATT
            prf_server_send_event((prf_env_struct *)&bass_env, false,
                    bass_env.shdl[param->bas_instance] + BAS_IDX_BATT_LVL_VAL);
        }
        else
        {
            status = PRF_ERR_NTF_DISABLED;
        }
    }
    else
    {
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        bass_batt_level_upd_cfm_send(status);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 17
0
void cpps_send_rsp_ind(uint16_t handle, uint8_t req_op_code, uint8_t status)
{
    // Error response
    uint8_t rsp[CPP_CP_CNTL_PT_RSP_MIN_LEN];

    // Response Code
    rsp[0] = CPP_CTNL_PT_RSP_CODE;
    // Request Operation Code
    rsp[1] = req_op_code;
    // Response value
    rsp[2] = status;

    // Set the value in the database - If we are here the handle is valid
    attmdb_att_set_value(handle, 3, (uint8_t *)&rsp);

    // Send an indication
    prf_server_send_event((prf_env_struct *)&cpps_env, true, handle);

    // Wait for Confirm
    ke_state_set(TASK_CPPS, CPPS_WAIT_FOR_CFM);
}
Esempio n. 18
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HPSS_HTTP_SEND_STATUS_REQ message.
 * @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 hpss_status_code_send_req_handler(ke_msg_id_t const msgid,
        struct hpss_status_code_send_req const *param,
        ke_task_id_t const dest_id,
        ke_task_id_t const src_id)
{
    // Status
    uint8_t status = PRF_ERR_OK;

    if(param->conhdl == gapc_get_conhdl(hpss_env.con_info.conidx))
    {
//fix me
        // Check if notifications are enabled
        if(HPSS_IS_SUPPORTED(HPSS_STATUS_CODE_NTF_CFG))
        {
            //Update value in DB
            attmdb_att_set_value(hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_VAL,
                                 HPS_STATUS_CODE_LEN, (uint8_t *)&param->status_code);//fix me, LSB?

            //send notification through GATT
            prf_server_send_event((prf_env_struct *)&hpss_env, false,
                                  hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_VAL);
        }
        //notification not enabled, simply don't send anything
        else
        {
            status = PRF_ERR_NTF_DISABLED;
        }
    }
    else
    {
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        // Value has not been sent
        hpss_status_code_send_cfm_send(status);
    }
    return (KE_MSG_CONSUMED);
}
Esempio n. 19
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPS_UPD_TIME_DST_REQ message.
 * @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 tips_upd_time_dst_req_handler(ke_msg_id_t const msgid,
                                                struct tips_upd_time_dst_req const *param,
                                                ke_task_id_t const dest_id,
                                                ke_task_id_t const src_id)
{
    // Packed Time With DST value
    uint8_t pckd_time_dst[NDCS_TIME_DST_VAL_LEN];
    // Status
    uint8_t status = PRF_ERR_INVALID_PARAM;

    // Get the address of the environment
    struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx);

    // Check the provided Connection Handle
    if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx))
    {
        // Check if the Next DST Change Service is supported
        if (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP))
        {
            //Pack the Time with DST value and Save it into the DB
            tips_pack_time_dst_value(&pckd_time_dst[0], &param->time_with_dst);

            // Set the value in the database
            status = attmdb_att_set_value(tips_env.ndcs_shdl + NDCS_IDX_TIME_DST_VAL,
                                          NDCS_TIME_DST_VAL_LEN, (uint8_t *)&pckd_time_dst[0]);
        }
        else
        {
            status = PRF_ERR_FEATURE_NOT_SUPPORTED;
        }
    }

    if (status != PRF_ERR_OK)
    {
        //Wrong Connection Handle
        tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_TIME_DST_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 20
0
int streamdatad_send_data_packet(uint8_t *data)
{
    uint16_t* packet_buffer_enabled;
	int retval = 0;
    uint16_t len = 0;
	packet_buffer_enabled = NULL;
	attmdb_att_get_value(STREAMDATAD_DIR_EN_HANDLE(streamdatad_env.next_attribute_idx), &(len), (uint8_t**)&(packet_buffer_enabled));

	if ((packet_buffer_enabled && (*packet_buffer_enabled)))
	{        
        // Update the value in the attribute database
        attmdb_att_set_value(STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx), sizeof(uint8_t) * STREAMDATAD_PACKET_SIZE, data);

        // Send notification
        prf_server_send_event((prf_env_struct *)&(streamdatad_env.con_info), false, STREAMDATAD_DIR_VAL_HANDLE(streamdatad_env.next_attribute_idx));
        
		retval = 1;
	}

	streamdatad_env.next_attribute_idx++; if (streamdatad_env.next_attribute_idx >= STREAMDATAD_MAX) streamdatad_env.next_attribute_idx = 0;
	return retval;
}
Esempio n. 21
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The message is redirected from TASK_SVC because at profile enable, the ATT handle is
 * register for TASK_FINDT. In the handler, an ATT Write Response/Error Response should
 * be sent for ATT protocol, but Alert Level Characteristic only supports WNR so no
 * response PDU is needed.
 * @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 alert_lvl = 0x0000;

    if (KE_IDX_GET(src_id) == findt_env.con_info.conidx)
    {
        if(param->handle == findt_env.shdl + FINDT_IAS_IDX_ALERT_LVL_VAL)
        {
            alert_lvl = param->value[0];

            //Check if Alert Level is valid
            if ((param->value[0] <= FINDT_ALERT_HIGH))
            {
                //Update the attribute value
                attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&alert_lvl);
                if(param->last)
                {
                    // Allocate the alert value change indication
                    struct findt_alert_ind *ind = KE_MSG_ALLOC(FINDT_ALERT_IND, findt_env.con_info.appid,
                                                               TASK_FINDT, findt_alert_ind);
                    // Fill in the parameter structure
                    ind->conhdl    = gapc_get_conhdl(findt_env.con_info.conidx);
                    ind->alert_lvl = alert_lvl;

                    // Send the message
                    ke_msg_send(ind);
                }
                // It was a Write Without Response so no RSP needed.
            }
        }
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 22
0
/**
 ****************************************************************************************
 * @brief Enable the HPS Server role, used after connection.
 * @param[in] msgid     Id of the message received.
 * @param[in] param     Pointer to the parameters of the message.
 * @param[in] dest_id   ID of the receiving task instance
 * @param[in] src_id    ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int hpss_enable_req_handler(ke_msg_id_t const msgid,
                                   struct hpss_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    uint16_t value = 0;
    // Keep source of message, to respond to it further on
    hpss_env.con_info.appid = src_id;
    // Store the connection handle for which this profile is enabled
    hpss_env.con_info.conidx = gapc_get_conidx(param->conhdl);

    // Check if the provided connection exist
    if (hpss_env.con_info.conidx == GAP_INVALID_CONIDX)
    {
        // The connection doesn't exist, request disallowed
        prf_server_error_ind_send((prf_env_struct *)&hpss_env, PRF_ERR_REQ_DISALLOWED,
                                  HPSS_ERROR_IND, HPSS_ENABLE_REQ);
    }
    else
    {
        // Enable HPS + Set Security Level
        attmdb_svc_set_permission(hpss_env.hps_shdl, param->sec_lvl);
        //Set HR Meas. Char. NTF Configuration in DB
        attmdb_att_set_value(hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_CFG, sizeof(uint16_t),
                             (uint8_t *)&value);
//fix me?
        //Set LLS Alert Level to specified value
        // attmdb_att_set_value(hpss_env.hps_shdl + LLS_IDX_ALERT_LVL_VAL,
        //                     sizeof(uint8_t), (uint8_t *)&param->lls_alert_lvl);

        // Go to Connected state
        ke_state_set(TASK_HPSS, HPSS_CONNECTED);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 23
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * @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 = SAMPLE128_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx)
    {
        if (param->handle == sample128_env.sample128_1_shdl + SAMPLE128_1_IDX_VAL)
        {
            char_code = SAMPLE128_1_CHAR;
        }

        if (char_code != SAMPLE128_ERR_CHAR)
        {
            
            //Save value in DB
            attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&param->value[0]);
            
            if(param->last)
            {
                sample128_send_val(param->value[0]);
            }

            status = PRF_ERR_OK;
            
            // Send Write Response
            atts_write_rsp_send(sample128_env.con_info.conidx, param->handle, status);
            
        }
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 24
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPS_UPD_LOCAL_TIME_INFO_REQ message.
 * @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 tips_upd_local_time_info_req_handler(ke_msg_id_t const msgid,
                                                struct tips_upd_local_time_info_req const *param,
                                                ke_task_id_t const dest_id,
                                                ke_task_id_t const src_id)
{
    // Status
    uint8_t status = PRF_ERR_INVALID_PARAM;

    // Get the address of the environment
    struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx);

    // Check the Connection Handle
    if(param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx))
    {
        // Check if the Local Time Info Char. has been added in the database
        if (TIPS_IS_SUPPORTED(TIPS_CTS_LOC_TIME_INFO_SUP))
        {
            // Set the value in the database
            status = attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_LOCAL_TIME_INFO_VAL,
                                          sizeof(struct tip_loc_time_info), (uint8_t *)&(param->loc_time_info));
        }
        else
        {
            status = PRF_ERR_FEATURE_NOT_SUPPORTED;
        }
    }

    // Send a message to the application if an error has been raised.
    if (status != PRF_ERR_OK)
    {
        //Wrong Connection Handle
        tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_LOCAL_TIME_INFO_REQ);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 25
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref ACCEL_ENABLE_REQ message.
 * The handler enables the accelerometer profile.
 * @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 accel_enable_req_handler(ke_msg_id_t const msgid,
                                    struct accel_enable_req const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    uint16_t disable_val = 0x00;

    //Save Application ID
    accel_env.con_info.appid = src_id;
    accel_env.con_info.prf_id = dest_id;

    // Save the connection index associated to the profile
    accel_env.con_info.conidx = gapc_get_conidx(param->conhdl);


    attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), sizeof(uint8_t), (uint8_t*) &(disable_val));
    attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_RANGE_VAL), sizeof(uint8_t), (uint8_t*) &(disable_val));

    attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_X_EN), sizeof(uint16_t),(uint8_t*) &(disable_val));
    attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_Y_EN), sizeof(uint16_t),(uint8_t*) &(disable_val));
    attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_Z_EN), sizeof(uint16_t),(uint8_t*) &(disable_val));

{
	uint8_t tb;
	
//	tb = battery_get_lvl(BATT_CR2032);
		tb = battery_get_lvl(BATT_JPLUS);//gsx,jplus battery type.

	 // Update the value in the attribute database
    attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), sizeof(uint8_t), (uint8_t*) &(tb));
}
	    
    //Enable Service
    attmdb_svc_set_permission(accel_env.shdl, PERM(SVC, ENABLE));

    // Go to active state
    ke_state_set(TASK_ACCEL, ACCEL_ACTIVE);

    return (KE_MSG_CONSUMED);
}
Esempio n. 26
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref SAMPLE128_CREATE_DB_REQ message.
 * @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 sample128_create_db_req_handler(ke_msg_id_t const msgid,
                                       struct sample128_create_db_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    //Database Creation Status
    uint8_t status;
    uint8_t nb_att_16;
    uint8_t nb_att_128;
    uint8_t nb_att_32;
    uint16_t att_decl_svc = ATT_DECL_PRIMARY_SERVICE;
    uint16_t att_decl_char = ATT_DECL_CHARACTERISTIC;
    uint16_t att_decl_cfg = ATT_DESC_CLIENT_CHAR_CFG;
    uint16_t val_hdl;
    uint16_t char_hdl; 

    //Save Profile ID
    sample128_env.con_info.prf_id = TASK_SAMPLE128;

    /*---------------------------------------------------*
     * Link Loss Service Creation
     *---------------------------------------------------*/

        //Add Service Into Database
        nb_att_16 = 4; // 2 UUID16 atts
        nb_att_32 = 0;// No UUID32 att
        nb_att_128 = 2; //1 UUID128 att
        status = attmdb_add_service(&(sample128_env.sample128_shdl), TASK_SAMPLE128,
                                             nb_att_16, nb_att_32, nb_att_128, 58); //total attributte size = 36, 16 (svc)  + 19 (desc_char) + 1 (att)

        if (status == ATT_ERR_NO_ERROR)
        {
            //add svc attribute
            status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN, //Data size = 16 (ATT_UUID_128_LEN)
                                               ATT_UUID_16_LEN, (uint8_t*)&att_decl_svc, PERM(RD, ENABLE),
                                               &(sample128_env.sample128_shdl));
            
            
            
            status = attmdb_att_set_value(sample128_env.sample128_shdl, ATT_UUID_128_LEN, (uint8_t *)sample128_svc.uuid);
            
            
//char 1     
            //add char attribute
            status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN + 3, //Data size = 19 (ATT_UUID_128_LEN + 3)
                                               ATT_UUID_16_LEN, (uint8_t*) &att_decl_char, PERM(RD, ENABLE),
                                               &(char_hdl));
            
            
            
            //add val attribute
            status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint8_t), //Data size = 1
                                               ATT_UUID_128_LEN, (uint8_t*)&sample128_1_val.uuid, PERM(RD, ENABLE) | PERM(WR, ENABLE),
                                               &(val_hdl));
            
            memcpy(sample128_1_char.attr_hdl, &val_hdl, sizeof(uint16_t));
            
            status = attmdb_att_set_value(char_hdl, sizeof(sample128_1_char), (uint8_t *)&sample128_1_char);
            

//////char 2
            //add char attribute
            status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN + 3, //Data size = 19 (ATT_UUID_128_LEN + 3)
                                               ATT_UUID_16_LEN, (uint8_t*) &att_decl_char, PERM(RD, ENABLE),
                                               &(char_hdl));
                        
            //add val attribute
            status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint8_t), //Data size = 1
                                               ATT_UUID_128_LEN, (uint8_t*)&sample128_2_val.uuid, PERM(RD, ENABLE) | PERM(NTF, ENABLE),
                                               &(val_hdl));
            
            memcpy(sample128_2_char.attr_hdl, &val_hdl, sizeof(uint16_t));
            
            status = attmdb_att_set_value(char_hdl, sizeof(sample128_2_char), (uint8_t *)&sample128_2_char);

            //add cfg attribute
            status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint16_t), 
                                               ATT_UUID_16_LEN, (uint8_t*) &att_decl_cfg, PERM(RD, ENABLE) | PERM(WR, ENABLE),
                                               &(val_hdl));

            //Disable sample128 service
            attmdb_svc_set_permission(sample128_env.sample128_shdl, PERM(SVC, DISABLE));

            //Go to Idle State
    
            //If we are here, database has been fulfilled with success, go to idle state
            ke_state_set(TASK_SAMPLE128, SAMPLE128_IDLE);
        }
        
        //Send CFM to application
        struct sample128_create_db_cfm * cfm = KE_MSG_ALLOC(SAMPLE128_CREATE_DB_CFM, src_id,
                                                    TASK_SAMPLE128, sample128_create_db_cfm);
        cfm->status = status;
        ke_msg_send(cfm);
    

    return (KE_MSG_CONSUMED);
}
Esempio n. 27
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * @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 = SAMPLE128_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx)
    {
        if (param->handle == sample128_env.sample128_shdl + SAMPLE128_1_IDX_VAL)
        {
            char_code = SAMPLE128_1_CHAR;
        }
        
        if (param->handle == sample128_env.sample128_shdl + SAMPLE128_2_IDX_CFG)
        {
            char_code = SAMPLE128_2_CFG;
        }
        
        if (char_code == SAMPLE128_1_CHAR)
        {
            
            //Save value in DB
            attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&param->value[0]);
            
            if(param->last)
            {
                sample128_send_val(param->value[0]);
							  leds_state.flag = param->value[0];
							  //app_sample128_start_leds();
            }

            status = PRF_ERR_OK;
               
        }
        else if (char_code == SAMPLE128_2_CFG)
        {
            
            // Written value
            uint16_t ntf_cfg;

            // Extract value before check
            ntf_cfg = co_read16p(&param->value[0]);
        
            // Only update configuration if value for stop or notification enable
            if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))
            {
                //Save value in DB
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&param->value[0]);
                
                // Conserve information in environment
                if (ntf_cfg == PRF_CLI_START_NTF)
                {
                    // Ntf cfg bit set to 1
                    sample128_env.feature |= PRF_CLI_START_NTF;
                }
                else
                {
                    // Ntf cfg bit set to 0
                    sample128_env.feature &= ~PRF_CLI_START_NTF;
                }                
                
                status = PRF_ERR_OK; 
                
            }
        }
    }

    // Send Write Response
    atts_write_rsp_send(sample128_env.con_info.conidx, param->handle, status);
    
    return (KE_MSG_CONSUMED);
}
Esempio n. 28
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HTPT_TEMP_UPD_REQ message.
 * @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 htpt_temp_send_req_handler(ke_msg_id_t const msgid,
                                      struct htpt_temp_send_req const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    // Packed Temperature Measurement value
    uint8_t packed_temp[HTPT_TEMP_MEAS_MAX_LEN];
    // Status
    uint8_t status = PRF_ERR_OK;
    // Packet size
    uint8_t size;

    if(param->conhdl == gapc_get_conhdl(htpt_env.con_info.conidx))
    {
        //Pack the temperature measurement value
        size = htpt_pack_temp_value(&packed_temp[0], param->temp_meas);

        //Intermediate Measurement, must be notified if enabled
        if(param->flag_stable_meas == 0x00)
        {
            //Check if Intermediate Measurement Char. is supported
            if (htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] != 0x00)
            {
                //Check if notifications are enabled
                if((htpt_env.features & HTPT_MASK_INTM_MEAS_CFG) == HTPT_MASK_INTM_MEAS_CFG)
                {
                    attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 1,
                                         size, &packed_temp[0]);

                    //Send notification through GATT
                    prf_server_send_event((prf_env_struct *)&htpt_env, false,
                            htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 1);
                }
                else
                {
                    status = PRF_ERR_NTF_DISABLED;
                }
            }
            else
            {
                status = PRF_ERR_FEATURE_NOT_SUPPORTED;
            }
        }
        //Temperature Measurement, must be indicated if enabled
        else
        {
            if((htpt_env.features & HTPT_MASK_TEMP_MEAS_CFG) == HTPT_MASK_TEMP_MEAS_CFG)
            {
                attmdb_att_set_value(htpt_env.shdl + HTS_IDX_TEMP_MEAS_VAL, size, &packed_temp[0]);

                prf_server_send_event((prf_env_struct *)&htpt_env, true,
                        htpt_env.shdl + HTS_IDX_TEMP_MEAS_VAL);
            }
            else
            {
                status = PRF_ERR_IND_DISABLED;
            }
        }
    }
    else
    {
        //Wrong Connection Handle
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        /*
         * The cfm_type value is HTPT_CENTRAL_IND_CFM (1) if param->flag_stable_meas = 1,
         * HTPT_THERM_TEMP_SEND (0) if param->flag_stable_meas = 0
         */
        htpt_temp_send_cfm_send(status, param->flag_stable_meas);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 29
0
/**
 ****************************************************************************************
 * @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 *meas_intv_range;
    uint16_t meas_intv_rge[2];

    uint16_t value = 0x0000;
    uint8_t status = PRF_ERR_OK;
    uint8_t char_code = 0;

    if (KE_IDX_GET(src_id) == htpt_env.con_info.conidx)
    {
        //Extract value before check
        memcpy(&value, &(param->value), sizeof(uint16_t));

        //Measurement Interval Char. - Value
        if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1))
        {
            /*
             * Get Measurement Interval range in database
             * Valid Range descriptor exists because measurement interval is writable
             */
            attmdb_att_get_value(param->handle + htpt_get_valid_rge_offset(), &meas_intv_rge[0], &meas_intv_range);

            memcpy(&meas_intv_rge[0], meas_intv_range, sizeof(uint16_t));
            memcpy(&meas_intv_rge[1], meas_intv_range + 2, sizeof(uint16_t));

            //Check if value to write is in allowed range
            if (((value >= meas_intv_rge[0]) && (value <= meas_intv_rge[1])) || (value == 0))
            {
                //Send APP the indication with the new value
                struct htpt_meas_intv_chg_ind * ind = KE_MSG_ALLOC(HTPT_MEAS_INTV_CHG_IND,
                                                                   htpt_env.con_info.appid, TASK_HTPT,
                                                                   htpt_meas_intv_chg_ind);

                memcpy(&ind->intv, &value, sizeof(uint16_t));

                ke_msg_send(ind);
            }
            else
            {
                status = HTPT_OUT_OF_RANGE_ERR_CODE;
            }
        }
        else
        {
            //Temperature Measurement Char. - Client Char. Configuration
            if (param->handle == (htpt_env.shdl + HTS_IDX_TEMP_MEAS_IND_CFG))
            {
                char_code = HTPT_TEMP_MEAS_CHAR;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    htpt_env.features &= ~HTPT_MASK_TEMP_MEAS_CFG;
                }
                else if (value == PRF_CLI_START_IND)
                {
                    htpt_env.features |= HTPT_MASK_TEMP_MEAS_CFG;
                }
                else
                {
                    //Invalid value
                    status = HTPT_OUT_OF_RANGE_ERR_CODE;
                }
            }
            //Measurement Interval Char. - Client Char. Configuration
            else if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 2))
            {
                char_code = HTPT_MEAS_INTV_CHAR;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    htpt_env.features &= ~HTPT_MASK_MEAS_INTV_CFG;
                }
                else if (value == PRF_CLI_START_IND)
                {
                    htpt_env.features |= HTPT_MASK_MEAS_INTV_CFG;
                }
                else
                {
                    //Invalid value
                    status = HTPT_OUT_OF_RANGE_ERR_CODE;
                }
            }
            //Intermediate Measurement Char. - Client Char. Configuration
            else if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 2))
            {
                char_code = HTPT_INTERM_TEMP_CHAR;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    htpt_env.features &= ~HTPT_MASK_INTM_MEAS_CFG;
                }
                else if (value == PRF_CLI_START_NTF)
                {
                    htpt_env.features |= HTPT_MASK_INTM_MEAS_CFG;
                }
                else
                {
                    //Invalid value
                    status = HTPT_OUT_OF_RANGE_ERR_CODE;
                }
            }

            if (status == PRF_ERR_OK)
            {
                if(param->last)
                {
                    //Inform APP of configuration change
                    struct htpt_cfg_indntf_ind * ind = KE_MSG_ALLOC(HTPT_CFG_INDNTF_IND,
                                                                    htpt_env.con_info.appid, TASK_HTPT,
                                                                    htpt_cfg_indntf_ind);

                    ind->conhdl = gapc_get_conhdl(htpt_env.con_info.conidx);
                    ind->char_code = char_code;
                    memcpy(&ind->cfg_val, &value, sizeof(uint16_t));

                    ke_msg_send(ind);
                }
            }
        }

        if (status == PRF_ERR_OK)
        {
            //Update the attribute value
            attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value);
        }

        //Send write response
        atts_write_rsp_send(htpt_env.con_info.conidx, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
Esempio n. 30
0
static int htpt_create_db_req_handler(ke_msg_id_t const msgid,
                                      struct htpt_create_db_req const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    //Valid Range value
    uint32_t valid_range;
    //Service content flag
    uint16_t cfg_flag;

    uint16_t total_size = 0;
    uint8_t nb_att = 0;
    uint8_t status = ATT_ERR_NO_ERROR;
    uint8_t i;

    // Save profile ID
    htpt_env.con_info.prf_id = TASK_HTPT;

    //Save database configuration
    htpt_env.features = param->features;

    //Compute Attribute Table and save it in environment
    cfg_flag = htpt_compute_att_table(param->features);

    status = attm_svc_create_db(&htpt_env.shdl, (uint8_t *)&cfg_flag, HTS_IDX_NB, &htpt_env.att_tbl[0],
                               dest_id, &htpt_att_db[0]);

    //Disable the service and set optional features
    if (status == ATT_ERR_NO_ERROR)
    {
        //Disable service
        status = attmdb_svc_set_permission(htpt_env.shdl, PERM(SVC, DISABLE));

        //Set optional properties and permissions
        if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00)
        {
            nb_att = ATT_CHAR_PROP_RD;
            total_size = PERM(RD, ENABLE);
            i = 1;

            if ((param->features & HTPT_MEAS_INTV_IND_SUP) == HTPT_MEAS_INTV_IND_SUP)
            {
                nb_att |= ATT_CHAR_PROP_IND;
                total_size |= PERM(IND, ENABLE);
                i++;
            }

            if ((param->features & HTPT_MEAS_INTV_WR_SUP) == HTPT_MEAS_INTV_WR_SUP)
            {
                nb_att |= ATT_CHAR_PROP_WR;
                total_size |= PERM(WR, UNAUTH);
                i++;

                //Set Measurement Interval Char. - Valid Range value
                if ((param->valid_range_min) < (param->valid_range_max))
                {
                    valid_range = param->valid_range_min | (param->valid_range_max << 16);
                }
                else
                {
                    //If minimal and maximal values are the same or if maximal value is upper than minimal value
                    valid_range = HTPT_MEAS_INTV_DFLT_MIN | (HTPT_MEAS_INTV_DFLT_MAX << 16);
                }

                status = attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + i,
                                              sizeof(uint32_t), (uint8_t *)&valid_range);

            }

            attmdb_att_partial_value_update(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR], 0, 1, &nb_att);
            attmdb_att_set_permission(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1, total_size);
        }

        //If we are here, database has been fulfilled with success, go to idle test
        ke_state_set(TASK_HTPT, HTPT_IDLE);
    }

    //Send response to application
    struct htpt_create_db_cfm * cfm = KE_MSG_ALLOC(HTPT_CREATE_DB_CFM, src_id, TASK_HTPT,
                                                   htpt_create_db_cfm);
    cfm->status = status;
    ke_msg_send(cfm);

    return (KE_MSG_CONSUMED);
}