#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 48 // 图标缩放最小尺寸 #define ANIMATION_ICON_SIZE_MAX 80 // 图标缩放最大尺寸 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; static void func_bt_call_back_to(void) { u8 last_func = func_directly_back_to(); if (last_func == FUNC_BT_RING) { func_directly_back_to(); } } 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_BG_BIN); compo_setid(pic, COMPO_ID_CALL_ICON); compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, 2+37); compo_textbox_t *number_txt = compo_textbox_create(frm, 20); compo_textbox_set_location(number_txt, GUI_SCREEN_CENTER_X, 70+7 , 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, 93+5, 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, 6, 37, 6, 80); compo_shape_set_alpha(vol_bar_bg, 0); compo_shape_set_visible(vol_bar_bg, false); // 通话音量进度条 int height = SysVariable.hfp_vol * 80 / (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, 6, 37 + (80 - height), 6, height); compo_shape_set_alpha(vol_bar, 0); compo_shape_set_visible(vol_bar, false); //挂断按钮 compo_button_t *btn; 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, 117+16); //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_BG_BIN); compo_setid(pic, COMPO_ID_CALL_ICON); compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, 7+32); 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, 6, 37, 6, 80); compo_shape_set_alpha(vol_bar_bg, 0); compo_shape_set_visible(vol_bar_bg, false); // 通话音量进度条 int height = SysVariable.hfp_vol * 80 / (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, 6, 37 + (80 - height), 6, 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, 117+16); 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 * 80 / (VOL_MAX - 1); compo_shape_set_location(vol_bar, 6, 37 + (80 - height), 6, 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|| bt_get_call_indicate() == BT_CALL_OUTGOING) { 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); } }