476 lines
16 KiB
C
476 lines
16 KiB
C
#include "include.h"
|
||
#include "func.h"
|
||
#include "func_bt.h"
|
||
#include "m_rtc.h"
|
||
#include "app_variable.h"
|
||
|
||
#define VOLUME_BAR_TIME_MAX 2000 // 音量条显示时长(unit:ms)
|
||
#define VOLUME_BAR_ANIM_TIME_MAX 10 // 音量条淡入淡出(unit:ms)
|
||
|
||
#define ANIMATION_TICK_EXPIRE 20 // 动画帧间隔(unit:ms)
|
||
#define ANIMATION_ROTATION_ANGLE (3600 / 100) // 单次旋转角度
|
||
#define ANIMATION_ICON_SIZE_MIN 40 // 图标缩放最小尺寸
|
||
#define ANIMATION_ICON_SIZE_MAX 110 // 图标缩放最大尺寸
|
||
|
||
enum {
|
||
COMPO_ID_TXT_NUMBER = 0xff, //避免id被覆盖
|
||
COMPO_ID_CALL_ICON,
|
||
COMPO_ID_TXT_TIME,
|
||
COMPO_ID_BTN_REJECT,
|
||
// COMPO_ID_BTN_MIC,
|
||
COMPO_ID_CALL_VOLUME,
|
||
COMPO_ID_CALL_VOLUME_BG,
|
||
};
|
||
|
||
typedef struct f_bt_call_t_ {
|
||
bool sta; //0:呼出(outgoing); 1:通话(call);
|
||
|
||
// u16 times; //通话秒数
|
||
char call_time_str[16]; //通话计时字符串
|
||
u32 clcc_tick; //主动查询号码计时
|
||
u32 exit_tick; //页面退出计时
|
||
u32 sco_tick;
|
||
u8 hours;
|
||
u8 minutes;
|
||
u8 seconds;
|
||
|
||
u16 anim_angle;
|
||
u32 anim_tick;
|
||
|
||
u8 vol_hfp; // 临时音量
|
||
u8 vol_gradually; // 音量条淡入淡出(1:淡入,2:淡出)
|
||
s16 vol_alpha; // 音量条透明度
|
||
bool vol_show; // 音量条显示标志
|
||
u32 amin_tick; // 音量条动画Tick
|
||
u32 vol_show_tick; // 音量条Tick
|
||
} f_bt_call_t;
|
||
|
||
|
||
extern struct Phone_Time_t phone_time;
|
||
extern int phonebook_get_name_by_number(u8 *number, u8 *name);
|
||
|
||
void bt_incall_time_update(void)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
// char *call_time_str = f_bt_call->call_time_str;
|
||
|
||
// u16 call_times = f_bt_call->times;
|
||
// u8 f_bt_call->hours = call_times / 3600;
|
||
// u8 f_bt_call->minutes = (call_times % 3600) / 60;
|
||
// u8 f_bt_call->seconds = call_times % 60;
|
||
sprintf(f_bt_call->call_time_str, "%02d:%02d:%02d", phone_time.hour, phone_time.min, phone_time.sec);
|
||
// printf("call_time_str: %s\n", call_time_str);
|
||
|
||
compo_textbox_t *time_txt = compo_getobj_byid(COMPO_ID_TXT_TIME);
|
||
compo_textbox_set(time_txt, f_bt_call->call_time_str);
|
||
compo_textbox_set_visible(time_txt, true);
|
||
}
|
||
|
||
void func_bt_call_number_update(void)
|
||
{
|
||
int name_len = 0;
|
||
if (bt_cb.number_sta) {
|
||
compo_textbox_t *number_txt = compo_getobj_byid(COMPO_ID_TXT_NUMBER);
|
||
name_len = phonebook_get_name_by_number((u8*)hfp_get_last_call_number(0),(u8*)sys_cb.outgoing_name);
|
||
if(name_len > 0)
|
||
compo_textbox_set(number_txt, sys_cb.outgoing_name);
|
||
else
|
||
compo_textbox_set(number_txt, (const char*)hfp_get_last_call_number(0));
|
||
}
|
||
}
|
||
|
||
//创建窗体,创建窗体中不要使用功能结构体 func_cb.f_cb
|
||
compo_form_t *func_bt_call_form_create(void)
|
||
{
|
||
//printf("%s\n", __func__);
|
||
//新建窗体, 通话页面
|
||
compo_form_t *frm = compo_form_create(true);
|
||
//大背景
|
||
compo_picturebox_t *pic;
|
||
pic = compo_picturebox_create(frm, UI_BUF_CALL_CALL_ICON_BIN);
|
||
compo_setid(pic, COMPO_ID_CALL_ICON);
|
||
compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, 70);
|
||
|
||
compo_textbox_t *number_txt = compo_textbox_create(frm, 20);
|
||
compo_textbox_set_location(number_txt, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y , GUI_SCREEN_WIDTH, 50);
|
||
compo_textbox_set_autosize(number_txt, true);
|
||
compo_setid(number_txt, COMPO_ID_TXT_NUMBER);
|
||
msg_enqueue(EVT_CALL_NUMBER_UPDATE);
|
||
|
||
compo_textbox_t *time_txt = compo_textbox_create(frm, 10);
|
||
compo_textbox_set_location(time_txt, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y + 20, GUI_SCREEN_WIDTH, 50);
|
||
compo_textbox_set_forecolor(time_txt,COLOR_GREEN);
|
||
compo_textbox_set_autosize(time_txt, true);
|
||
compo_setid(time_txt, COMPO_ID_TXT_TIME);
|
||
|
||
// 通话音量背景
|
||
compo_shape_t *vol_bar_bg = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
|
||
compo_setid(vol_bar_bg, COMPO_ID_CALL_VOLUME_BG);
|
||
compo_shape_set_align_center(vol_bar_bg, false);
|
||
compo_shape_set_color(vol_bar_bg, make_color(38, 103, 65));
|
||
compo_shape_set_location(vol_bar_bg, 10, 70, 8, 112);
|
||
compo_shape_set_alpha(vol_bar_bg, 0);
|
||
compo_shape_set_visible(vol_bar_bg, false);
|
||
|
||
// 通话音量进度条
|
||
int height = SysVariable.hfp_vol * 112 / (VOL_MAX - 1);
|
||
compo_shape_t *vol_bar = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
|
||
compo_setid(vol_bar, COMPO_ID_CALL_VOLUME);
|
||
compo_shape_set_align_center(vol_bar, false);
|
||
compo_shape_set_color(vol_bar, make_color(12, 227, 103));
|
||
compo_shape_set_location(vol_bar, 10, 70 + (112 - height), 8, height);
|
||
compo_shape_set_alpha(vol_bar, 0);
|
||
compo_shape_set_visible(vol_bar, false);
|
||
|
||
//挂断按钮
|
||
compo_button_t *btn = compo_button_create_by_image(frm, UI_BUF_CALL_HANG_UP_BIN);
|
||
compo_setid(btn, COMPO_ID_BTN_REJECT);
|
||
compo_button_set_pos(btn, GUI_SCREEN_CENTER_X, 250);
|
||
|
||
//mic
|
||
// btn = compo_button_create_by_image(frm, UI_BUF_CALL_MUTE_BIN);
|
||
// compo_setid(btn, COMPO_ID_BTN_MIC);
|
||
// compo_button_set_pos(btn, 49, 234);
|
||
|
||
return frm;
|
||
}
|
||
|
||
//创建窗体,创建窗体中不要使用功能结构体 func_cb.f_cb
|
||
compo_form_t *func_bt_outgoing_form_create(void)
|
||
{
|
||
//新建窗体, 呼出页面
|
||
compo_form_t *frm = compo_form_create(true);
|
||
compo_button_t *btn;
|
||
//大背景
|
||
compo_picturebox_t *pic;
|
||
pic = compo_picturebox_create(frm, UI_BUF_CALL_CALL_ICON_BIN);
|
||
compo_setid(pic, COMPO_ID_CALL_ICON);
|
||
compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, 70);
|
||
|
||
compo_textbox_t *number_txt = compo_textbox_create(frm, 20);
|
||
compo_textbox_set_location(number_txt, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y, GUI_SCREEN_WIDTH, 50);
|
||
compo_textbox_set_autosize(number_txt, true);
|
||
compo_setid(number_txt, COMPO_ID_TXT_NUMBER);
|
||
msg_enqueue(EVT_CALL_NUMBER_UPDATE);
|
||
|
||
// 通话音量背景
|
||
compo_shape_t *vol_bar_bg = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
|
||
compo_setid(vol_bar_bg, COMPO_ID_CALL_VOLUME_BG);
|
||
compo_shape_set_align_center(vol_bar_bg, false);
|
||
compo_shape_set_color(vol_bar_bg, make_color(38, 103, 65));
|
||
compo_shape_set_location(vol_bar_bg, 10, 70, 8, 112);
|
||
compo_shape_set_alpha(vol_bar_bg, 0);
|
||
compo_shape_set_visible(vol_bar_bg, false);
|
||
|
||
// 通话音量进度条
|
||
int height = SysVariable.hfp_vol * 112 / (VOL_MAX - 1);
|
||
compo_shape_t *vol_bar = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
|
||
compo_setid(vol_bar, COMPO_ID_CALL_VOLUME);
|
||
compo_shape_set_align_center(vol_bar, false);
|
||
compo_shape_set_color(vol_bar, make_color(12, 227, 103));
|
||
compo_shape_set_location(vol_bar, 10, 70 + (112 - height), 8, height);
|
||
compo_shape_set_alpha(vol_bar, 0);
|
||
compo_shape_set_visible(vol_bar, false);
|
||
|
||
//挂断按钮
|
||
btn = compo_button_create_by_image(frm, UI_BUF_CALL_HANG_UP_BIN);
|
||
compo_setid(btn, COMPO_ID_BTN_REJECT);
|
||
compo_button_set_pos(btn, GUI_SCREEN_CENTER_X, 250);
|
||
|
||
return frm;
|
||
}
|
||
|
||
AT(.text.func.bt)
|
||
static void func_bt_call_interface(void)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
|
||
if (bt_cb.disp_status == BT_STA_INCALL && f_bt_call->sta == false) {
|
||
//销毁窗体
|
||
if (func_cb.frm_main != NULL) {
|
||
compo_form_destroy(func_cb.frm_main);
|
||
}
|
||
|
||
func_cb.frm_main = func_bt_call_form_create();
|
||
f_bt_call->sta = true;
|
||
|
||
}
|
||
if (f_bt_call->sco_tick && tick_check_expire(f_bt_call->sco_tick, 1000)) {
|
||
f_bt_call->sco_tick = 0;
|
||
bt_hfp_switch_to_watch(); //通话音频强制切到手表
|
||
}
|
||
}
|
||
|
||
AT(.text.func.bt)
|
||
static void func_bt_call_exit_process(void)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
|
||
if (!bt_cb.number_sta) { //号码未通知, 主动查询
|
||
if (tick_check_expire(f_bt_call->clcc_tick, 500)) {
|
||
f_bt_call->clcc_tick = tick_get();
|
||
bt_call_get_remote_phone_number();
|
||
}
|
||
}
|
||
|
||
if(bt_cb.disp_status != BT_STA_OUTGOING && bt_cb.disp_status != BT_STA_INCALL) { //退出通话页面
|
||
printf("func_bt_call_exit_process1111\n");
|
||
func_switch_to_assign_screen(FUNC_BT_END, false);
|
||
}
|
||
|
||
if (f_bt_call->exit_tick && tick_check_expire(f_bt_call->exit_tick, 1000)) { //强制退出, 防呆
|
||
f_bt_call->exit_tick = 0;
|
||
printf("func_bt_call_exit_process2222\n");
|
||
func_switch_to_assign_screen(FUNC_BT_END, false);
|
||
}
|
||
}
|
||
|
||
static void func_bt_call_animation_process(void)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
compo_picturebox_t *pic = compo_getobj_byid(COMPO_ID_CALL_ICON);
|
||
|
||
if (f_bt_call == NULL || pic == NULL)
|
||
return;
|
||
|
||
u8 angle_per = 0;
|
||
s16 icon_size = 0;
|
||
|
||
if (tick_check_expire(f_bt_call->anim_tick, ANIMATION_TICK_EXPIRE))
|
||
{
|
||
f_bt_call->anim_tick = tick_get();
|
||
|
||
/* Calculated rotation Angle */
|
||
f_bt_call->anim_angle = (f_bt_call->anim_angle + ANIMATION_ROTATION_ANGLE) % 3600;
|
||
|
||
/* Gets the ICON size based on the rotation Angle */
|
||
if (f_bt_call->anim_angle < 3600 / 2) // lessen
|
||
{
|
||
angle_per = (f_bt_call->anim_angle * 100) / 1800;
|
||
icon_size = ((ANIMATION_ICON_SIZE_MAX - ANIMATION_ICON_SIZE_MIN) * angle_per) / 100;
|
||
icon_size = (ANIMATION_ICON_SIZE_MAX - ANIMATION_ICON_SIZE_MIN) - icon_size;
|
||
}
|
||
else // magnify
|
||
{
|
||
angle_per = ((f_bt_call->anim_angle - 1800) * 100) / 1800;
|
||
icon_size = ((ANIMATION_ICON_SIZE_MAX - ANIMATION_ICON_SIZE_MIN) * angle_per) / 100;
|
||
}
|
||
icon_size += ANIMATION_ICON_SIZE_MIN;
|
||
|
||
compo_picturebox_set_size(pic, icon_size, icon_size);
|
||
compo_picturebox_set_rotation(pic, f_bt_call->anim_angle);
|
||
}
|
||
}
|
||
|
||
static void func_bt_call_volume_bar_process(void)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
compo_shape_t *vol_bar = compo_getobj_byid(COMPO_ID_CALL_VOLUME);
|
||
compo_shape_t *vol_bar_bg = compo_getobj_byid(COMPO_ID_CALL_VOLUME_BG);
|
||
|
||
if (f_bt_call == NULL || vol_bar == NULL || vol_bar_bg == NULL)
|
||
return;
|
||
|
||
if (f_bt_call->vol_hfp != SysVariable.hfp_vol)
|
||
{
|
||
int height = SysVariable.hfp_vol * 112 / (VOL_MAX - 1);
|
||
compo_shape_set_location(vol_bar, 10, 70 + (112 - height), 8, height);
|
||
compo_shape_set_visible(vol_bar, true);
|
||
compo_shape_set_visible(vol_bar_bg, true);
|
||
|
||
if(!f_bt_call->vol_show) {
|
||
f_bt_call->vol_alpha = !f_bt_call->vol_gradually ? 0 : f_bt_call->vol_alpha;
|
||
f_bt_call->vol_gradually = 1;
|
||
f_bt_call->vol_show = true;
|
||
}
|
||
f_bt_call->amin_tick = tick_get();
|
||
f_bt_call->vol_show_tick = tick_get();
|
||
f_bt_call->vol_hfp = SysVariable.hfp_vol;
|
||
}
|
||
|
||
/* 超时退出 */
|
||
if (tick_check_expire(f_bt_call->vol_show_tick, VOLUME_BAR_TIME_MAX) && f_bt_call->vol_show) {
|
||
f_bt_call->vol_show = false;
|
||
f_bt_call->vol_alpha = 255;
|
||
f_bt_call->vol_gradually = 2;
|
||
f_bt_call->amin_tick = tick_get();
|
||
}
|
||
|
||
/* 淡入淡出 */
|
||
if (tick_check_expire(f_bt_call->amin_tick, VOLUME_BAR_ANIM_TIME_MAX) && f_bt_call->vol_gradually) {
|
||
f_bt_call->amin_tick = tick_get();
|
||
if (f_bt_call->vol_gradually == 1) {
|
||
if (f_bt_call->vol_alpha < 255)
|
||
f_bt_call->vol_alpha += 5;
|
||
|
||
if (f_bt_call->vol_alpha >= 255) {
|
||
f_bt_call->vol_alpha = 255;
|
||
f_bt_call->vol_gradually = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (f_bt_call->vol_alpha > 0)
|
||
f_bt_call->vol_alpha -= 5;
|
||
|
||
if (f_bt_call->vol_alpha <= 0) {
|
||
f_bt_call->vol_alpha = 0;
|
||
f_bt_call->vol_gradually = 0;
|
||
|
||
compo_shape_set_visible(vol_bar, false);
|
||
compo_shape_set_visible(vol_bar_bg, false);
|
||
}
|
||
}
|
||
compo_shape_set_alpha(vol_bar, f_bt_call->vol_alpha);
|
||
compo_shape_set_alpha(vol_bar_bg, f_bt_call->vol_alpha);
|
||
}
|
||
}
|
||
|
||
void func_bt_call_process(void)
|
||
{
|
||
func_process();
|
||
func_bt_sub_process();
|
||
func_bt_call_exit_process();
|
||
func_bt_call_interface();
|
||
|
||
/* Call ICON animation */
|
||
func_bt_call_animation_process();
|
||
|
||
/* Display volume bar when volume changes */
|
||
func_bt_call_volume_bar_process();
|
||
}
|
||
|
||
static void func_bt_call_click(void)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
|
||
int id = compo_get_button_id();
|
||
switch (id) {
|
||
|
||
case COMPO_ID_BTN_REJECT:
|
||
printf("COMPO_ID_BTN_REJECT\n");
|
||
bt_call_terminate();
|
||
f_bt_call->exit_tick = tick_get();
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
//蓝牙音乐消息处理
|
||
static void func_bt_call_message(size_msg_t msg)
|
||
{
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
|
||
switch (msg) {
|
||
|
||
/* UX不响应处理触摸滑动事件 */
|
||
case MSG_CTP_TOUCH:
|
||
case MSG_CTP_SHORT_RIGHT:
|
||
break;
|
||
|
||
/* 单击静音 */
|
||
case KU_BACK:
|
||
bt_volume_set(0);
|
||
f_bt_call->vol_hfp = 0xff;
|
||
break;
|
||
|
||
/* 双击挂断 */
|
||
case KD_BACK:
|
||
bt_call_terminate();
|
||
f_bt_call->exit_tick = tick_get();
|
||
break;
|
||
|
||
case KU_RIGHT:
|
||
if(bt_get_call_indicate() == BT_CALL_INCOMING) {
|
||
bt_call_answer_incoming(); //接听第2路通话
|
||
} else {
|
||
bt_call_terminate(); //挂断当前通话
|
||
sys_cb.motor_flag = 1;
|
||
set_func_motor(80,2,2,1);
|
||
}
|
||
break;
|
||
|
||
case KU_LEFT:
|
||
break;
|
||
|
||
case MSG_SYS_1S:
|
||
if (f_bt_call->sta == true) {
|
||
// f_bt_call->times++;
|
||
bt_incall_time_update();
|
||
}
|
||
break;
|
||
|
||
case MSG_CTP_CLICK:
|
||
func_bt_call_click(); //单击按钮
|
||
break;
|
||
|
||
case EVT_CALL_NUMBER_UPDATE:
|
||
if (bt_get_call_indicate() == BT_CALL_ACTIVE || bt_get_call_indicate() == BT_CALL_3WAY_CALL) {
|
||
func_bt_call_number_update();
|
||
}
|
||
break;
|
||
|
||
case MSG_SYS_500MS:
|
||
if(bt_cb.disp_status == BT_STA_OUTGOING)
|
||
{
|
||
reset_sleep_delay_all(); // 来电不休眠
|
||
}
|
||
break;
|
||
|
||
default:
|
||
func_message(msg);
|
||
break;
|
||
}
|
||
}
|
||
|
||
void func_bt_call_enter(void)
|
||
{
|
||
func_cb.f_cb = func_zalloc(sizeof(f_bt_call_t));
|
||
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
|
||
|
||
func_cb.frm_main = func_bt_outgoing_form_create();
|
||
|
||
func_cb.mp3_res_play = func_bt_mp3_res_play;
|
||
|
||
bsp_bt_call_enter();
|
||
if (sys_cb.gui_sleep_sta) {
|
||
sys_cb.gui_need_wakeup = 1;
|
||
}
|
||
|
||
f_bt_call->vol_hfp = SysVariable.hfp_vol;
|
||
}
|
||
|
||
void func_bt_call_exit(void)
|
||
{
|
||
bsp_bt_call_exit();
|
||
bsp_motor_stop(MOTOR_PORT);
|
||
}
|
||
|
||
void func_bt_call(void)
|
||
{
|
||
printf("%s\n", __func__);
|
||
u16 interval = 0, latency = 0, tout = 0;
|
||
|
||
// Adjust BLE connection parameter when incall
|
||
if (ble_is_connect() && (ble_get_conn_interval() < 400)) {
|
||
interval = ble_get_conn_interval();
|
||
latency = ble_get_conn_latency();
|
||
tout = ble_get_conn_timeout();
|
||
ble_update_conn_param(480, 0, 500);
|
||
}
|
||
func_bt_call_enter();
|
||
while (func_cb.sta == FUNC_BT_CALL) {
|
||
func_bt_call_process();
|
||
func_bt_call_message(msg_dequeue());
|
||
}
|
||
func_bt_call_exit();
|
||
|
||
// Restore BLE connection parameter
|
||
if (interval | latency | tout) {
|
||
ble_update_conn_param(interval, latency, tout);
|
||
}
|
||
}
|