FR8016H的SDK中作为peripheral端时如何使发起BLE的Notification操作



  • 目前,我已在FR801xH的SDK中的ble_simple_peripheral例子上实现了从手机端向FR8016H发起写命令来控制FR8016H执行相应的操作,但是我想在此基础上利用simple_profile_att_table中的0xfff0服务的0xfff4特性(因为此特性具有notification功能)实现FR8016H向手机端notification功能,但是目前我试着根据FREQ BLE SDK User Guide V1.0手册里的gatt_notification()函数向手机端执行notification操作,但却几经尝试,不曾成功,所有在此向官方求助,我现在把我写的代码贴出来,专家帮着看看是哪出了问题,是函数调用的不对,还是函数调用的位置不对,亦或是参数设置不对,多谢了。
    static void sp_gatt_write_cb(uint8_t *write_buf, uint16_t len, uint16_t att_idx, uint8_t conn_idx)
    {
    for (int i = 0; i < len; i++)
    {
    co_printf("Write request: len: %d, 0x%x \r\n", len, write_buf[i]);
    if (att_idx == SP_IDX_CHAR1_VALUE)
    {
    memcpy(sp_char1_value, write_buf, len);
    //co_printf("Write request:sp_char1_value:len: %d, 0x%x \r\n", len, write_buf[i]);
    }

        if (att_idx == SP_IDX_CHAR3_VALUE)//fff0/fff2/fff3
    			{
    				memcpy(sp_char3_value, write_buf, len);//将数据拷贝到sp_char3_value数组中
    			}
        
        if (att_idx == SP_IDX_CHAR5_VALUE)
    			{
    				memcpy(sp_char5_value, write_buf, len);
    				co_printf("Write request:sp_char5_value:len: %d, 0x%x \r\n", len, write_buf[i]);
    			}
            
    }
    
    uint16_t uuid = BUILD_UINT16( simple_profile_att_table[att_idx].uuid.p_uuid[0], simple_profile_att_table[att_idx].uuid.p_uuid[1] );
    if (uuid == GATT_CLIENT_CHAR_CFG_UUID)
    {
    	co_printf("Notification status changed\r\n");
        if (att_idx == SP_IDX_CHAR4_CFG)
        {
            sp_char4_ccc[0] = write_buf[0];
            sp_char4_ccc[1] = write_buf[1];
            co_printf("Char4 ccc: 0x%x 0x%x \r\n", sp_char4_ccc[0], sp_char4_ccc[1]);
        }
    }
    	if(sp_char4_ccc[0] == 1 && sp_char4_ccc[1] == 0)//如果Notification使能
    	{
    		//在接收到对端ntf使能的消息之后,通过调用gatt_notification()函数实现BLE peripheral端向手机端发送数据
    		gatt_ntf_t ntf_att;
    		ntf_att.att_idx = 4;//0xfff0服务的第4个att:0xfff4
    		ntf_att.conidx = conn_idx;//链接号
    		ntf_att.svc_id = sp_svc_id;//此GATT服务号
    		ntf_att.data_len = 6;//Notification数据的长度,根据发送的数据实时调整
    		uint8_t ntf_data[] = "zhusai";//虚拟数据,用户可根据需要替换成需要Notification的数据
    		ntf_att.p_data = ntf_data;//Notification数据的指针
    		gatt_notification(ntf_att);//peripheral端设备向手机端执行一次notification操作;
    		co_printf("Notification Data: %x\r\n", ntf_data);
    	}
    	
    	
    	//对sp_char3_value数组中的数据进行解析[0]:0xa5,[1]:开关,[2]:Red(0xff),[4]:Green(0xff),[6]:Blue(0xff),[9]:0x5a
    	if(sp_char3_value[0] == 0xa5 && sp_char3_value[9] == 0x5a)//包首尾正确
    	{
    		if(sp_char3_value[1] == 1)//灯打开
    		{
    			if(PWM_Start_Flag == false)
    			{
    				pwm_start(PWM_CHANNEL_4);//点亮绿灯
    				pwm_start(PWM_CHANNEL_5);//点亮红灯
    				pwm_start(PWM_CHANNEL_1);//点亮蓝灯
    				PWM_Start_Flag = true;
    			}
    			if(sp_char3_value[2] > 99) sp_char3_value[2] = 99;//红色
    			if(sp_char3_value[4] > 99) sp_char3_value[4] = 99;//绿色
    			if(sp_char3_value[6] > 99) sp_char3_value[6] = 99;//蓝色
    			uint32_t Green_Value = sp_char3_value[4];
    			uint32_t Red_Value = sp_char3_value[2];
    			uint32_t Blue_Value = sp_char3_value[6];
    			pwm_update(PWM_CHANNEL_4, 10000, Green_Value);//更新绿灯亮度
    			pwm_update(PWM_CHANNEL_5, 10000, Red_Value);//更新红灯亮度
    			pwm_update(PWM_CHANNEL_1, 10000, Blue_Value);//更新蓝灯亮度
    		}
    		else
    		{
    			if(PWM_Start_Flag == true)
    			{
    				pwm_stop(PWM_CHANNEL_4);//熄灭绿灯
    				pwm_stop(PWM_CHANNEL_5);//熄灭红灯
    				pwm_stop(PWM_CHANNEL_1);//熄灭蓝灯
    				PWM_Start_Flag = false;
    			}
    			
    		}
    	}
    

    }

    /*********************************************************************

    • @fn sp_gatt_msg_handler

    • @brief Simple Profile callback funtion for GATT messages. GATT read/write

    • 	operations are handeled here.
      
    • @param p_msg - GATT messages from GATT layer.

    • @return uint16_t - Length of handled message.
      */
      static uint16_t sp_gatt_msg_handler(gatt_msg_t *p_msg)
      {
      switch(p_msg->msg_evt)
      {
      case GATTC_MSG_NTF_REQ:
      co_printf("Notification request::: \r\n");
      break;
      case GATTC_MSG_READ_REQ:
      sp_gatt_read_cb((uint8_t *)(p_msg->param.msg.p_msg_data), &(p_msg->param.msg.msg_len), p_msg->att_idx);
      break;

       case GATTC_MSG_WRITE_REQ:
           sp_gatt_write_cb((uint8_t*)(p_msg->param.msg.p_msg_data), (p_msg->param.msg.msg_len), p_msg->att_idx, p_msg->conn_idx);
           break;
           
       default:
           break;
      

      }
      return p_msg->param.msg.msg_len;
      }



  • 你把ntf_att.att_idx 的4改成 SP_IDX_CHAR4_VALUE试试看。这个在simple_gatt_service.h
    里面有定义,这个idx指的是整个特征值table里面的排序,并不是单指某个特征值。



  • 十分感谢!
    按您的要求,将程序该为如下就成功了,专业!及时!给您点赞!谢谢!
    //在接收到对端ntf使能的消息之后,通过调用gatt_notification()函数实现BLE peripheral端向手机端发送数据
    gatt_ntf_t ntf_att;
    ntf_att.att_idx = SP_IDX_CHAR4_VALUE;//0xfff0服务的第4个att:0xfff4
    ntf_att.conidx = conn_idx;//链接号
    ntf_att.svc_id = sp_svc_id;//此GATT服务号
    ntf_att.data_len = 6;//Notification数据的长度,根据发送的数据实时调整
    uint8_t ntf_data[] = "zhusai";//虚拟数据,用户可根据需要替换成需要Notification的数据
    ntf_att.p_data = ntf_data;//Notification数据的指针
    gatt_notification(ntf_att);//peripheral端设备向手机端执行一次notification操作;