1. void send_all_data(boolis_from_cb)
发送数据都是通过send_all_data()去上传的。
1) static boolneed_send_sync_process(void )
判断是否需要进行同步,在send_all_data()一开始时调用。当sync_process_start_send等于false并且有数据存储在FLASH或RAM中,则需要发送同步开始命令(CMD=0x05,KEY= 0x07)。
① have_sleep_group_to_send()
这个函数主要是判断在FLASH中是否有睡眠数据需要上传。通过判断睡眠数据的当前写地址与当前读地址是否相等来判断是否有数据存储在FLASH中。如果写地址与读地址相等,说明没有数据存储在FLASH中。
② have_sleep_data_in_ram_to_send()
这个函数主要是判断在RAM中是否有睡眠数据需要上传。通过判断睡眠数据的结构体mSleepHead.length是否等于0来判断是否有数据需要上传,当此值不为0时,则说明有数据上传。
③ uint16_t sleep_setting_count(void)
这个函数主要判断是否有睡眠设定数据要上传,通过判断manual_sleep_events_head->length是否大于0进行判断。manual_sleep_events_head->length在切换睡眠(应用层)模式的时候进行加1,在发送睡眠数据后的回调函数中作减操作(send_sleep_setting_data_cb)。睡眠模式应该分为两种,一种为BAIDU算法的睡眠,有未睡、浅睡和深睡三种模式,这种睡眠在全天任何时候可能都会切换;另一种是应用级别的睡眠(即那个22~5点的那个,我们可以修改的算法),这个睡眠会调用0505指令去告诉上位机进入睡眠或退出睡眠的状态。
不在睡眠时间内,BAIDU算法也会进入睡眠,但是没有0505指令指示其已进入睡眠状态。
④ bool have_sport_group_to_send()
判断在FLASH中是否有运动数据需要上传。判断方法与have_sleep_group_to_send()一致。
⑤ bool have_history_sport_data_in_ram_to_send(void)
这个函数主要是判断在RAM中是否有运动数据需要上传。通过判断运动数据的结构体mSportHead.length是否等于0来判断是否有数据需要上传,当此值不为0时,则说明有数据上传。
2) send_sport_data_sync_start()
当need_send_sync_process()的返回值为true时,则说明需要进行数据同步,则调用该函数发送同步开始命令(CMD=0x05,KEY= 0x07)。
3) have_sleep_group_to_send()
如果在need_send_sync_process()中判断到sync_process_start_send=true,则不进行同步开始命令(CMD=0x05,KEY= 0x07)的发送,直接进行have_sleep_group_to_send()的判断(在send_all_data()函数内)。这种情况出现在回调时调用的send_all_data()中,即定时器服务send_data_timeout()中。
因此,程序走到这里的话表示已经在前面的一个send_all_data()中调用了同步开始指令。
4) have_sleep_data_in_ram_to_send()
同上(“1.3)”)处理流程。
5) uint16_tsleep_setting_count(void)
同上(“1.3)”)处理流程。
6) bool have_sport_group_to_send()
同上(“1.3)”)处理流程。
7) boolhave_history_sport_data_in_ram_to_send(void)
同上(“1.3)”)处理流程。但此处需要判断mSportHead.length是否大于1,如果等于1则说明还没有完整的一个15分钟数据。因此可以看到have_history_sport_data_in_ram_to_send()与have_sport_data_in_ram_to_send()的不同之处。
8) else if( true ==notify_steps_enable&& have_sport_data_in_ram_to_send())
如果判断到实时上传打开了,并且RAM中有数据需要上传,并且当前步数不等于最后一次发送的步数时(可理解为当次15分钟周期的步改变),则发送在RAM中的运动数据。
如果当前周期中,没有步数,则mSportHead.length为0,如果有步数了,则mSportHead.length=1,如果此值大于1,则说明有历史数据在FLASH中。
在上图中可以看出,如果quarter_steps=0,则说明是新的一个周期的计步回调,即新的周期中的第一个数据,则mSportHead.length自加。
如果mSportHead.length=0,则说明在本周期之前的周期数据都已上传,本周期为第一个周期,则mSportHead.length赋值为1。
9) else if(true == sync_process_start_send)
所有数据发送完了后,则发送停止同步命令。
2. 调用void send_all_data(bool is_from_cb)的情况
1) 发送查询数据指令(CMD=0x05,KEY= 0x01)后,WATCH会马上调用send_all_data(false)上传一次数据,如果没有数据需要上传,则不传输(没指令传输)。如果没有打开实时同步,这里也不会发送当前步数给APP。
2) 如果打开了实时同步(CMD=0x05,KEY= 0x06),则WATCH会马上调用send_all_data(false)上传一次数据,如果没有数据需要上传,则不传输(没指令传输)。
3) handle_distance_event()中,当发生计步事件后,会调用数据发送函数,如果没有打开实时数据同步,则判断到有历史数据时,并且新的周期内有计步事件时,才会上传,因为只有计步事件发生了,才会进行mSportHead.length ++。
4) handle_sleep_event()中,当发生睡眠事件后,会调用数据发送函数,如果没有打开实时数据同步,则判断到有历史数据时,才上传。
5) send_last_time_sleep_mode()
当用户登录成功时,会调用此函数,进而调用send_all_data(false)上传数据。
3. 数据的保存
1) 睡眠数据的保存
save_sleep_group_data()
以上函数为存储睡眠数据到FLASH的函数,当发生睡眠事件时(sleep_evt_handler()),
先会将睡眠数据保存至RAM中,并且mSleepHead.length ++,当判断到mSleepHead.length 大于SLEEP_MAX_GROUP_NUM时,则调用save_sleep_group_data()将数据保存至FLASH中。
当跳转至OTA时,也会进行一次数据的保存,包括睡眠、运动等需要保存的数据,这个过程是调用save_curr_health_data()进行数据的保存。
2) 运动数据的保存
save_sport_group_data()
以上函数为存储运动数据到FLASH的函数,最终由save_quarter_distance_data()调用,每15分钟保存一次。
与睡眠数据保存一样,跳转至OTA时,也会进行一次数据的保存,包括睡眠、运动等需要保存的数据,这个过程是调用save_curr_health_data()进行数据的保存。
4. 睡眠唤醒的注意事项
睡眠唤醒需要注意的是需要百度算法进入了未睡的状态下,再进行大于20步的运动,才会唤醒,才会有睡眠设定数据返回。
5. 睡眠自动进入的注意事项
在检测睡眠的时候,有一个判断,if(sleep_event.starting_time_stamp/60 <= sleepSetting_minutes + 30 ),这个判断是防止连续的多次进入睡眠操作,即30分钟内的连续睡眠切换。也就是说,如果半夜起床了,造成自动唤醒,但是还没到30分钟内,又去睡觉了,这里百度算法变成了睡眠状态(自动唤醒后的30分钟内),这里是不会再进入睡眠的了。