1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504 |
- /*
- * Copyright (c) 2017 Actions Semi Co., Ltd.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief btsrvice hfp
- */
- #define SYS_LOG_DOMAIN "btsrv_hfp"
- #include "btsrv_os_common.h"
- #include "btsrv_inner.h"
- struct btsrv_hfp_context_info {
- btsrv_hfp_callback hfp_user_callback;
- };
- static int btsrv_hfp_hf_disable_nrec(struct bt_conn *br_conn);
- static struct btsrv_hfp_context_info hfp_context;
- static void _btsrv_hfp_connected_cb(struct bt_conn *conn)
- {
- btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_HFP_CONNECTED, conn);
- }
- static void _btsrv_hfp_disconnected_cb(struct bt_conn *conn)
- {
- /* TODO: Disconnected process order: btsrv_tws(if need)->btsrv_hfp->btsrv_connect */
- btsrv_event_notify(MSG_BTSRV_HFP, MSG_BTSRV_HFP_DISCONNECTED, conn);
- }
- static void _btsrv_hfp_service_cb(struct bt_conn *conn, uint32_t value)
- {
- /* CIEV service
- * 0: No Home/Roam network available.
- * 1: Home/Roam network available.
- */
- SYS_LOG_INF("hf service %d", value);
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SERVICE, conn, (uint8_t)value);
- }
- static void _btsrv_hfp_call_cb(struct bt_conn *conn, uint32_t value)
- {
- /* CIEV call
- * 0: there are no calls in progress
- * 1: at least one call is in progress
- */
- SYS_LOG_INF("hf call %d", value);
- if (value == 0) {
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_EXITED);
- } else if (value == 1) {
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_ONGOING);
- }
- }
- static void _btsrv_hfp_call_setup_cb(struct bt_conn *conn, uint32_t value)
- {
- /* CIEV call_setup
- * 0: not currently in call set up
- * 1: an incoming call process ongoing
- * 2: an outgoing call set up is ongoing
- * 3: remote party being alerted in an outgoing call
- */
- SYS_LOG_INF("hf call_setup %d", value);
- switch (value) {
- case 0:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_SETUP_EXITED);
- break;
- case 1:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_INCOMING);
- break;
- case 2:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_OUTCOMING);
- break;
- case 3:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_ALERTED);
- break;
- }
- }
- static void _btsrv_hfp_call_held_cb(struct bt_conn *conn, uint32_t value)
- {
- /* CIEV call_held
- * 0: No calls held
- * 1: Call is placed on hold or active/held calls swapped
- * 2: Call on hold, no active call
- */
- SYS_LOG_INF("hf call_held %d", value);
- switch (value) {
- case 0:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_HELD_EXITED);
- break;
- case 1:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_MULTIPARTY_HELD);
- break;
- case 2:
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SET_STATE, conn, BTSRV_HFP_STATE_CALL_HELD);
- break;
- }
- }
- static void _btsrv_hfp_signal_cb(struct bt_conn *conn, uint32_t value)
- {
- SYS_LOG_INF("hfp signal %u", value);
- }
- static void _btsrv_hfp_roam_cb(struct bt_conn *conn, uint32_t value)
- {
- SYS_LOG_INF("Roaming is %s active", value ? "" : "not");
- }
- static void _btsrv_hfp_battery_cb(struct bt_conn *conn, uint32_t value)
- {
- SYS_LOG_INF("Battery value: %u", value);
- }
- static void _btsrv_hfp_ring_cb(struct bt_conn *conn)
- {
- SYS_LOG_INF("Incoming Call...");
- }
- static void _btsrv_hfp_bsir_cb(struct bt_conn *conn, uint32_t value)
- {
- SYS_LOG_INF("%s provide in-band ring tones", value ? "" : "not");
- }
- static void _btsrv_hfp_ccwa_cb(struct bt_conn *conn, uint8_t *buf, uint32_t value)
- {
- int buffer[12] = {0};
- int len = 0;
- SYS_LOG_INF("Call waiting phone number:%s, type:%d", buf, value);
- buffer[0] = (int)conn;
- len = snprintf((char *)&buffer[1], sizeof(buffer) - 4, "%s", buf) + 4;
- btsrv_event_notify_malloc(MSG_BTSRV_HFP, MSG_BTSRV_HFP_HF_CCWA_PHONE_NUM, (uint8_t *)buffer, len, 0);
- }
- static void _btsrv_hfp_clip_cb(struct bt_conn *conn, uint8_t *buf, uint32_t value, uint8_t *name)
- {
- int buffer[12] = {0};
- int len = 0;
- SYS_LOG_INF("phone number:%s, type:%d phone name:%s", buf, value ,name);
- buffer[0] = (int)conn;
- len = snprintf((char *)&buffer[1], sizeof(buffer) - 4, "%s", buf) + 4;
- btsrv_event_notify_malloc(MSG_BTSRV_HFP, MSG_BTSRV_HFP_PHONE_NUM, (uint8_t *)buffer, len, 0);
- #if 0 /* Not used now */
- buffer[0] = (int)conn;
- len = snprintf((char *)&buffer[1], sizeof(buffer) - 4, "%s", name) + 4;
- btsrv_event_notify_malloc(MSG_BTSRV_HFP, MSG_BTSRV_HFP_PHONE_NAME, (uint8_t *)buffer, len, 0);
- #endif
- }
- static void _btsrv_hfp_bcs_cb(struct bt_conn *conn, uint32_t codec_id)
- {
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_CODEC_INFO, conn, codec_id);
- SYS_LOG_INF("codec_id %d\n", codec_id);
- }
- static void _btsrv_hfp_bvra_cb(struct bt_conn *conn, uint32_t active)
- {
- uint8_t state;
- state = active ? BTSRV_HFP_SIRI_CHANGE_ACTIVE : BTSRV_HFP_SIRI_CHANGE_DEACTIVE;
- SYS_LOG_INF("Voice recognition is %s in the AG", active ? "enabled" : "disabled");
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SIRI_STATE, conn, state);
- }
- static void _btsrv_hfp_vgs_cb(struct bt_conn *conn, uint32_t value)
- {
- SYS_LOG_INF("Gain of Speaker %d", value);
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_VOLUME_CHANGE, conn, value);
- }
- static void _btsrv_hfp_vgm_cb(struct bt_conn *conn, uint32_t value)
- {
- SYS_LOG_INF("Gain of Microphone %d", value);
- }
- static void _btsrv_hfp_btrh_cb(struct bt_conn *conn, uint32_t value)
- {
- /* CIEV btrh
- * 0: Incoming call is put on hold in the AG
- * 1: Held incoming call is accepted in the AG
- * 2: Held incoming call is rejected in the AG
- */
- SYS_LOG_INF("hf btrh %d", value);
- }
- static void _btsrv_hfp_cops_cb(struct bt_conn *conn, uint32_t mode, uint32_t format, uint8_t *opt)
- {
- SYS_LOG_INF("Cops mode %d, format: %d, operator: %s", mode, format, opt);
- }
- static void _btsrv_hfp_cnum_cb(struct bt_conn *conn, uint8_t *buf, uint32_t value)
- {
- SYS_LOG_INF("Subscriber Number Information phone number:%s, type:%d", buf, value);
- }
- static void _btsrv_hfp_clcc_cb(struct bt_conn *conn, uint32_t idx, uint32_t dir, uint32_t status, uint32_t mode, uint32_t mpty,uint8_t *number, uint32_t type, uint8_t *name)
- {
- struct btsrv_hfp_clcc_info clcc_info;
- SYS_LOG_INF("list current calls result code, idx: %d, dir: %d,"
- "status: %d, mode: %d, mpty: %d number:%s type: %d, name: %s", idx, dir, status, mode, mpty,number, type, name);
- clcc_info.conn = conn;
- clcc_info.idx = idx;
- clcc_info.dir = dir;
- clcc_info.status = status;
- clcc_info.mode = mode;
- clcc_info.mpty = mpty;
- snprintf(clcc_info.number, 24, "%s", number);
- btsrv_event_notify_malloc(MSG_BTSRV_HFP, MSG_BTSRV_HFP_CLCC_INFO, (uint8_t *)&clcc_info, sizeof(struct btsrv_hfp_clcc_info), 0);
- }
- static void _btsrv_hfp_cclk_cb(struct bt_conn *conn, uint8_t *buf)
- {
- uint8_t buffer[36] = {0};
- int len = 0;
- SYS_LOG_INF("time of phone is :%s",buf);
- buffer[0] = (int)conn;
- memcpy(buffer,&conn,4);
- len = snprintf((char *)&buffer[4], sizeof(buffer) - 4, "%s", buf) + 4;
- //memcpy(&buffer[4],buf,strlen(buf));
- //len = strlen(buf) + 4 +1;
- btsrv_event_notify_malloc(MSG_BTSRV_HFP, MSG_BTSRV_HFP_TIME_UPDATE, (uint8_t *)buffer, len, 0);
- }
- static void _btsrv_hfp_cgmi_cb(struct bt_conn *conn, uint8_t *buf)
- {
- uint8_t buffer[30] = {0};
- int len = 0;
- SYS_LOG_INF("phone:%s",buf);
- buffer[0] = (int)conn;
- memcpy(buffer,&conn,4);
- len = snprintf((char *)&buffer[4], sizeof(buffer) - 4, "%s", buf) + 4;
- //memcpy(&buffer[4],buf,strlen(buf));
- //len = strlen(buf) + 4 +1;
- btsrv_event_notify_malloc(MSG_BTSRV_HFP, MSG_BTSRV_HFP_MANUFACTURE_INFO, (uint8_t *)buffer, len, 0);
- }
- static void _btsrv_hfp_battery_indicator_cb(struct bt_conn *conn, uint32_t status)
- {
- SYS_LOG_INF("status:%d.",status);
- if (1 == status) {
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_HPREC_BATTERY, conn, status);
- }
- }
- static void _btsrv_hfp_cmd_complete_cb(struct bt_conn *conn,
- struct bt_hfp_hf_cmd_complete *cmd)
- {
- uint8_t state;
- if (cmd->type != HFP_HF_CMD_OK) {
- SYS_LOG_INF("Send at cmd %s err %d-%d", cmd->sending_cmd, cmd->type, cmd->cme);
- if (!memcmp(cmd->sending_cmd, "AT+BVRA=1", strlen("AT+BVRA=1"))) {
- state = BTSRV_HFP_SIRI_CHANGE_DEACTIVE;
- btsrv_event_notify_ext(MSG_BTSRV_HFP, MSG_BTSRV_HFP_SIRI_STATE, conn, state);
- }
- }
- }
- static void _btsrv_hfp_cmd_recv_cb(struct bt_conn *conn, uint8_t *data, uint16_t len)
- {
- /* Do not modify the content of the input parameters.*/
- // stack_print_char("\nrecv:\n", data, len);
- }
- static const struct bt_hfp_hf_cb btsrv_hf_cb = {
- .connected = _btsrv_hfp_connected_cb,
- .disconnected = _btsrv_hfp_disconnected_cb,
- .service = _btsrv_hfp_service_cb,
- .call = _btsrv_hfp_call_cb,
- .call_setup = _btsrv_hfp_call_setup_cb,
- .call_held = _btsrv_hfp_call_held_cb,
- .signal = _btsrv_hfp_signal_cb,
- .roam = _btsrv_hfp_roam_cb,
- .battery = _btsrv_hfp_battery_cb,
- .ring_indication = _btsrv_hfp_ring_cb,
- .bsir = _btsrv_hfp_bsir_cb,
- .ccwa = _btsrv_hfp_ccwa_cb,
- .clip = _btsrv_hfp_clip_cb,
- .bcs = _btsrv_hfp_bcs_cb,
- .bvra = _btsrv_hfp_bvra_cb,
- .vgs = _btsrv_hfp_vgs_cb,
- .vgm = _btsrv_hfp_vgm_cb,
- .btrh = _btsrv_hfp_btrh_cb,
- .cops = _btsrv_hfp_cops_cb,
- .cnum = _btsrv_hfp_cnum_cb,
- .clcc = _btsrv_hfp_clcc_cb,
- .cclk = _btsrv_hfp_cclk_cb,
- .cgmi = _btsrv_hfp_cgmi_cb,
- .battery_indicator = _btsrv_hfp_battery_indicator_cb,
- .cmd_complete_cb = _btsrv_hfp_cmd_complete_cb,
- .recv = _btsrv_hfp_cmd_recv_cb,
- };
- uint8_t btsrv_hfp_get_codec_id(struct bt_conn *conn)
- {
- struct bt_conn *base_conn = btsrv_rdm_get_base_conn_by_sco(conn);
- uint8_t codec_id = BT_CODEC_ID_CVSD;
- uint8_t sample_rate = 8;
- btsrv_rdm_hfp_get_codec_info(base_conn, &codec_id, &sample_rate);
- return codec_id;
- }
- static int _btsrv_hfp_update_codec_info(void)
- {
- uint8_t codec_info[2] = {BT_CODEC_ID_CVSD, 8};
- struct bt_conn *conn = btsrv_rdm_hfp_get_actived();
- if(!conn)
- return -EINVAL;
-
- btsrv_rdm_hfp_get_codec_info(conn, codec_info, &codec_info[1]);
- #ifdef CONFIG_MEDIA
- if (codec_info[0] == BT_CODEC_ID_CVSD) {
- codec_info[0] = CVSD_TYPE;
- } else if (codec_info[0] == BT_CODEC_ID_MSBC) {
- codec_info[0] = MSBC_TYPE;
- }
- #endif
- hfp_context.hfp_user_callback(BTSRV_HFP_CODEC_INFO, codec_info, sizeof(codec_info));
- return 0;
- }
- static int _btsrv_hfp_tws_start_call(void)
- {
- #ifdef CONFIG_SUPPORT_TWS
- uint8_t codec_info[2] = {BT_CODEC_ID_CVSD, 8};
- struct bt_conn *conn = btsrv_rdm_hfp_get_actived();
- if(btsrv_rdm_get_dev_role() == BTSRV_TWS_MASTER){
- btsrv_rdm_hfp_get_codec_info(conn, codec_info, &codec_info[1]);
- btsrv_tws_hfp_start_callout(codec_info[0]);
- }
- #endif
- return 0;
- }
- static void btsrv_hfp_call_status_cb(struct bt_conn *conn, btsrv_hfp_event_e event, btsrv_hfp_state state)
- {
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- int other_dev_state = -1;
- if (!second_conn) {
- if (state == BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- _btsrv_hfp_update_codec_info();
- hfp_context.hfp_user_callback(BTSRV_HFP_SCO, NULL, 0);
- }
- hfp_context.hfp_user_callback(event, NULL, 0);
- } else {
- if (conn == second_conn)
- other_dev_state = btsrv_rdm_hfp_get_state(btsrv_rdm_hfp_get_actived());
- else
- other_dev_state = btsrv_rdm_hfp_get_state(second_conn);
- switch (state) {
- case BTSRV_HFP_STATE_INIT:
- case BTSRV_HFP_STATE_LINKED:
- switch (other_dev_state) {
- case BTSRV_HFP_STATE_INIT:
- case BTSRV_HFP_STATE_LINKED:
- hfp_context.hfp_user_callback(event, NULL, 0);
- break;
- case BTSRV_HFP_STATE_CALL_INCOMING:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_INCOMING, NULL, 0);
- event = BTSRV_HFP_CALL_INCOMING;
- break;
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_OUTGOING, NULL, 0);
- event = BTSRV_HFP_CALL_OUTGOING;
- break;
- case BTSRV_HFP_STATE_CALL_ALERTED:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_ALERTED, NULL, 0);
- event = BTSRV_HFP_CALL_ALERTED;
- break;
- case BTSRV_HFP_STATE_CALL_ONGOING:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_ONGOING, NULL, 0);
- event = BTSRV_HFP_CALL_ONGOING;
- break;
- case BTSRV_HFP_STATE_SCO_ESTABLISHED:
- hfp_context.hfp_user_callback(BTSRV_HFP_SCO, NULL, 0);
- event = BTSRV_HFP_SCO;
- break;
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_3WAYIN, NULL, 0);
- event = BTSRV_HFP_CALL_3WAYIN;
- break;
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_MULTIPARTY, NULL, 0);
- event = BTSRV_HFP_CALL_MULTIPARTY;
- break;
- default:
- break;
- }
- break;
- case BTSRV_HFP_STATE_CALL_INCOMING:
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- case BTSRV_HFP_STATE_CALL_ALERTED:
- switch (other_dev_state) {
- case BTSRV_HFP_STATE_INIT:
- case BTSRV_HFP_STATE_LINKED:
- hfp_context.hfp_user_callback(event, NULL, 0);
- break;
- case BTSRV_HFP_STATE_CALL_INCOMING:
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- case BTSRV_HFP_STATE_CALL_ALERTED:
- case BTSRV_HFP_STATE_CALL_ONGOING:
- case BTSRV_HFP_STATE_SCO_ESTABLISHED: /* to do */
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_3WAYIN, NULL, 0);
- event = BTSRV_HFP_CALL_3WAYIN;
- break;
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_MULTIPARTY, NULL, 0);
- event = BTSRV_HFP_CALL_MULTIPARTY;
- break;
- default:
- break;
- }
- break;
- case BTSRV_HFP_STATE_CALL_ONGOING:
- switch (other_dev_state) {
- case BTSRV_HFP_STATE_INIT:
- case BTSRV_HFP_STATE_LINKED:
- hfp_context.hfp_user_callback(event, NULL, 0);
- break;
- case BTSRV_HFP_STATE_CALL_INCOMING:
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- case BTSRV_HFP_STATE_CALL_ALERTED:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_3WAYIN, NULL, 0);
- event = BTSRV_HFP_CALL_3WAYIN;
- break;
- case BTSRV_HFP_STATE_CALL_ONGOING:
- case BTSRV_HFP_STATE_SCO_ESTABLISHED: /* to do */
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hfp_context.hfp_user_callback(BTSRV_HFP_CALL_MULTIPARTY, NULL, 0);
- event = BTSRV_HFP_CALL_MULTIPARTY;
- break;
- default:
- break;
- }
- break;
- case BTSRV_HFP_STATE_SCO_ESTABLISHED:
- if (conn != second_conn) {
- _btsrv_hfp_update_codec_info();
- hfp_context.hfp_user_callback(BTSRV_HFP_SCO, NULL, 0);
- hfp_context.hfp_user_callback(event, NULL, 0);
- }
- break;
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hfp_context.hfp_user_callback(event, NULL, 0);
- break;
- default:
- break;
- }
- }
- SYS_LOG_INF("event %d dev state %d second dev state %d\n", event, state, other_dev_state);
- }
- int btsrv_hfp_set_status(struct bt_conn *conn, int state)
- {
- int old_state = btsrv_rdm_hfp_get_state(conn);
- int new_state = -1;
- int event = -1;
- uint8_t active_call, held_call, incoming_call, outgoing_call;
- int ret = btsrv_rdm_hfp_get_call_state(conn, &active_call, &held_call, &incoming_call, &outgoing_call);
- if (ret < 0)
- return -ESRCH;
- switch (state) {
- case BTSRV_HFP_STATE_CALL_EXITED:
- active_call = 0;
- held_call = 0;
- if (old_state > BTSRV_HFP_STATE_INIT) {
- if (!incoming_call && !outgoing_call) {
- new_state = BTSRV_HFP_STATE_LINKED;
- event = BTSRV_HFP_CALL_EXIT;
- if(btsrv_rdm_hfp_get_sco_state(conn) == BTSRV_SCO_STATE_PHONE)
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_INIT);
- } else if (incoming_call == 1) {
- new_state = BTSRV_HFP_STATE_CALL_INCOMING;
- event = BTSRV_HFP_CALL_INCOMING;
- } else if (outgoing_call == 1) {
- new_state = BTSRV_HFP_STATE_CALL_OUTCOMING;
- event = BTSRV_HFP_CALL_OUTGOING;
- }
- }
- break;
- case BTSRV_HFP_STATE_CALL_SETUP_EXITED:
- if (incoming_call > 0)
- incoming_call = 0;
- else if (outgoing_call > 0)
- outgoing_call = 0;
- if (old_state == BTSRV_HFP_STATE_CALL_INCOMING ||
- old_state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- old_state == BTSRV_HFP_STATE_CALL_ALERTED) {
- new_state = BTSRV_HFP_STATE_LINKED;
- event = BTSRV_HFP_CALL_EXIT;
- if(btsrv_rdm_hfp_get_sco_state(conn) == BTSRV_SCO_STATE_PHONE)
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_INIT);
- } else if (old_state == BTSRV_HFP_STATE_CALL_3WAYIN) {
- new_state = BTSRV_HFP_STATE_CALL_ONGOING;
- event = BTSRV_HFP_CALL_ONGOING;
- }
- break;
- case BTSRV_HFP_STATE_CALL_HELD_EXITED:
- held_call = 0;
- if (old_state == BTSRV_HFP_STATE_CALL_MULTIPARTY) {
- if ((incoming_call + outgoing_call > 0)
- && active_call){
- new_state = BTSRV_HFP_STATE_CALL_3WAYIN;
- event = BTSRV_HFP_CALL_3WAYIN;
- } else if (incoming_call == 1) {
- new_state = BTSRV_HFP_STATE_CALL_INCOMING;
- event = BTSRV_HFP_CALL_INCOMING;
- } else if (outgoing_call == 1) {
- new_state = BTSRV_HFP_STATE_CALL_OUTCOMING;
- event = BTSRV_HFP_CALL_OUTGOING;
- } else {/* to do : held call --> active call */
- new_state = BTSRV_HFP_STATE_CALL_ONGOING;
- event = BTSRV_HFP_CALL_ONGOING;
- active_call = 1;
- }
- }
- break;
- case BTSRV_HFP_STATE_CALL_HELD:
- new_state = BTSRV_HFP_STATE_CALL_MULTIPARTY;
- event = BTSRV_HFP_CALL_MULTIPARTY;
- active_call = 0;
- held_call = 1;
- break;
- case BTSRV_HFP_STATE_CALL_MULTIPARTY_HELD:
- active_call = 1;
- held_call = 1;
- new_state = BTSRV_HFP_STATE_CALL_MULTIPARTY;
- event = BTSRV_HFP_CALL_MULTIPARTY;
- break;
- case BTSRV_HFP_STATE_CALL_INCOMING:
- incoming_call = 1;
- if (old_state == BTSRV_HFP_STATE_INIT ||
- old_state == BTSRV_HFP_STATE_LINKED ||
- old_state == BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- new_state = BTSRV_HFP_STATE_CALL_INCOMING;
- event = BTSRV_HFP_CALL_INCOMING;
- } else if (old_state >= BTSRV_HFP_STATE_CALL_ONGOING && old_state <= BTSRV_HFP_STATE_CALL_3WAYIN) {
- new_state = BTSRV_HFP_STATE_CALL_3WAYIN;
- event = BTSRV_HFP_CALL_3WAYIN;
- }
- break;
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- outgoing_call = 1;
- if (old_state == BTSRV_HFP_STATE_INIT ||
- old_state == BTSRV_HFP_STATE_LINKED ||
- old_state == BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- new_state = BTSRV_HFP_STATE_CALL_OUTCOMING;
- event = BTSRV_HFP_CALL_OUTGOING;
- } else if (old_state >= BTSRV_HFP_STATE_CALL_ONGOING && old_state <= BTSRV_HFP_STATE_CALL_3WAYIN) {
- new_state = BTSRV_HFP_STATE_CALL_3WAYIN;
- event = BTSRV_HFP_CALL_3WAYIN;
- }
- break;
- case BTSRV_HFP_STATE_CALL_ONGOING:
- active_call = 1;
- if (old_state == BTSRV_HFP_STATE_INIT ||
- old_state == BTSRV_HFP_STATE_CALL_INCOMING ||
- old_state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- old_state == BTSRV_HFP_STATE_CALL_ALERTED ||
- old_state == BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- new_state = BTSRV_HFP_STATE_CALL_ONGOING;
- event = BTSRV_HFP_CALL_ONGOING;
- } else if (old_state == BTSRV_HFP_STATE_CALL_3WAYIN) {
- new_state = BTSRV_HFP_STATE_CALL_MULTIPARTY;
- event = BTSRV_HFP_CALL_MULTIPARTY;
- }
- break;
- case BTSRV_HFP_STATE_CALL_ALERTED:
- outgoing_call = 1;
- if (old_state == BTSRV_HFP_STATE_INIT ||
- old_state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- old_state == BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- new_state = BTSRV_HFP_STATE_CALL_ALERTED;
- event = BTSRV_HFP_CALL_ALERTED;
- } else if (old_state >= BTSRV_HFP_STATE_CALL_ONGOING && old_state <= BTSRV_HFP_STATE_CALL_3WAYIN) {
- new_state = BTSRV_HFP_STATE_CALL_3WAYIN;
- event = BTSRV_HFP_CALL_3WAYIN;
- }
- break;
- case BTSRV_HFP_STATE_SCO_ESTABLISHED:
- if (old_state == BTSRV_HFP_STATE_INIT ||
- old_state == BTSRV_HFP_STATE_LINKED)
- new_state = BTSRV_HFP_STATE_SCO_ESTABLISHED;
- else{
- if (conn == btsrv_rdm_hfp_get_actived() ||
- conn == btsrv_rdm_get_tws_by_role(BTSRV_TWS_SLAVE)) {
- _btsrv_hfp_update_codec_info();
- hfp_context.hfp_user_callback(BTSRV_SCO_CONNECTED, NULL, 0);
- }
- }
- event = BTSRV_SCO_CONNECTED;
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_HFP);
- if(conn == btsrv_rdm_hfp_get_actived() && btsrv_rdm_get_dev_role() == BTSRV_TWS_MASTER){
- _btsrv_hfp_tws_start_call();
- }
- break;
- case BTSRV_HFP_STATE_SCO_RELEASED:
- if (old_state == BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- new_state = BTSRV_HFP_STATE_LINKED;
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_INIT);
- } else {
- if (conn == btsrv_rdm_hfp_get_actived() ||
- conn == btsrv_rdm_get_tws_by_role(BTSRV_TWS_SLAVE))
- hfp_context.hfp_user_callback(BTSRV_SCO_DISCONNECTED, NULL, 0);
- /* sco may be released after call exit,sco state must set to INIT */
- if (old_state != BTSRV_HFP_STATE_LINKED && old_state != BTSRV_HFP_STATE_INIT)
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_PHONE);
- else
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_INIT);
- }
- event = BTSRV_SCO_DISCONNECTED;
- #ifdef CONFIG_SUPPORT_TWS
- if(conn == btsrv_rdm_hfp_get_actived() && btsrv_rdm_get_dev_role() == BTSRV_TWS_MASTER){
- btsrv_tws_hfp_stop_call();
- }
- #endif
- break;
- }
- SYS_LOG_INF("old state %d new state %d state %d\n", old_state, new_state, state);
- SYS_LOG_INF("active %d hold %d coming %d\n", active_call, held_call,
- incoming_call + outgoing_call);
- btsrv_rdm_hfp_set_call_state(conn, active_call, held_call, incoming_call, outgoing_call);
- if (new_state >= 0) {
- if ((new_state >= BTSRV_HFP_STATE_CALL_INCOMING &&
- new_state <= BTSRV_HFP_STATE_SCO_ESTABLISHED) &&
- conn == btsrv_rdm_a2dp_get_actived() &&
- btsrv_rdm_is_a2dp_stream_open(conn)) {
- btsrv_rdm_a2dp_actived_switch_lock(conn, 1);
- SYS_LOG_INF("conn %p a2dp switch lock\n", conn);
- } else if (new_state == BTSRV_HFP_STATE_LINKED &&
- conn == btsrv_rdm_a2dp_get_actived()) {
- btsrv_rdm_a2dp_actived_switch_lock(conn, 0);
- SYS_LOG_INF("conn %p a2dp switch unlock\n", conn);
- }
- if(conn == btsrv_rdm_hfp_get_actived() && old_state == BTSRV_HFP_STATE_CALL_INCOMING
- && btsrv_rdm_hfp_get_notify_phone_num_state(conn)){
- hfp_context.hfp_user_callback(BTSRV_HFP_PHONE_NUM_STOP, NULL, 0);
- btsrv_rdm_hfp_set_notify_phone_num_state(conn,0);
- }
- btsrv_rdm_hfp_set_state(conn, new_state);
- btsrv_hfp_call_status_cb(conn, event, new_state);
- }
- return 0;
- }
- int btsrv_hfp_connect(struct bt_conn *conn)
- {
- if (!hostif_bt_hfp_hf_connect(conn)) {
- SYS_LOG_INF("Connect hfp_conn:%p\n", conn);
- } else {
- SYS_LOG_ERR("cmd_bredr_hfp_connect failed\n");
- }
- return 0;
- }
- int btsrv_hfp_init(btsrv_hfp_callback cb)
- {
- SYS_LOG_INF("cb %p", cb);
- memset(&hfp_context, 0, sizeof(struct btsrv_hfp_context_info));
- hostif_bt_hfp_hf_register_cb((struct bt_hfp_hf_cb *)&btsrv_hf_cb);
- hfp_context.hfp_user_callback = cb;
- return 0;
- }
- int btsrv_hfp_deinit(void)
- {
- hostif_bt_hfp_hf_register_cb(NULL);
- return 0;
- }
- static int _btsrv_hfp_connected(struct bt_conn *conn)
- {
- bd_address_t *addr = NULL;
- int state = btsrv_rdm_hfp_get_state(conn);
- addr = GET_CONN_BT_ADDR(conn);
- SYS_LOG_INF("hfp connected:%p addr %p\n", conn, addr);
- /**decode id may update during connect*/
- /* btsrv_rdm_hfp_set_codec_info(conn, BT_CODEC_ID_CVSD, 8); */
- if (state == BTSRV_HFP_STATE_INIT)
- btsrv_rdm_hfp_set_state(conn, BTSRV_HFP_STATE_LINKED);
- hfp_context.hfp_user_callback(BTSRV_HFP_CONNECTED, NULL, 0);
- btsrv_hfp_hf_disable_nrec(conn);
- return 0;
- }
- static int _btsrv_hfp_disconnected(struct bt_conn *conn)
- {
- bd_address_t *addr = NULL;
- int old_state = btsrv_rdm_hfp_get_state(conn);
- addr = GET_CONN_BT_ADDR(conn);
- SYS_LOG_INF("hfp disconnected:%p addr %p\n", conn, addr);
- btsrv_rdm_hfp_set_state(conn, BTSRV_HFP_STATE_INIT);
- if(btsrv_rdm_hfp_get_sco_state(conn) == BTSRV_SCO_STATE_PHONE)
- btsrv_rdm_hfp_set_sco_state(conn, BTSRV_SCO_STATE_INIT);
- if (old_state > BTSRV_HFP_STATE_LINKED)
- btsrv_hfp_call_status_cb(conn, BTSRV_HFP_CALL_EXIT, BTSRV_HFP_STATE_INIT);
- if (!btsrv_rdm_hfp_get_second_dev())
- hfp_context.hfp_user_callback(BTSRV_HFP_DISCONNECTED, NULL, 0);
- return 0;
- }
- int btsrv_hfp_rejected(struct bt_conn *conn)
- {
- hfp_context.hfp_user_callback(BTSRV_HFP_SCO_REJECTED, NULL, 0);
- return 0;
- }
- static int _btsrv_hfp_phone_num(struct bt_conn *conn, char *data)
- {
- struct bt_conn *trs_conn;
- /* call back to uplayer , play tts deceide by up layer*/
- if (conn == btsrv_rdm_hfp_get_actived()) {
- if (NULL != (trs_conn = (struct bt_conn *)btsrv_a2dp_trs_conn_get())) {
- hostif_bt_conn_check_exit_sniff(trs_conn);
- }
- hfp_context.hfp_user_callback(BTSRV_HFP_PHONE_NUM, data, strlen(data));
- btsrv_rdm_hfp_set_notify_phone_num_state(conn,1);
- }
- return 0;
- }
- static int _btsrv_hfp_phone_name(struct bt_conn *conn, char *data)
- {
- if (conn == btsrv_rdm_hfp_get_actived()) {
- hfp_context.hfp_user_callback(BTSRV_HFP_PHONE_NAME, data, strlen(data));
- }
- return 0;
- }
- static int _btsrv_hfp_hf_ccwa_phone_num(struct bt_conn *conn, char *data)
- {
- if (conn == btsrv_rdm_hfp_get_actived()) {
- hfp_context.hfp_user_callback(BTSRV_HFP_CCWA_PHONE_NUM, data, strlen(data));
- }
- return 0;
- }
- static int _btsrv_hfp_hf_clcc_info(struct btsrv_hfp_clcc_info *data)
- {
- if (data->conn == btsrv_rdm_hfp_get_actived()) {
- hfp_context.hfp_user_callback(BTSRV_HFP_CLCC_INFO, (uint8_t *)data, sizeof(struct btsrv_hfp_clcc_info));
- }
- return 0;
- }
- static int _btsrv_hfp_codec_info(struct bt_conn *conn, uint8_t codec_id)
- {
- uint8_t codec_info[2] = {0};
- #ifdef CONFIG_MEDIA
- if (codec_id == BT_CODEC_ID_CVSD) {
- codec_info[0] = CVSD_TYPE;
- codec_info[1] = 8;
- } else if (codec_id == BT_CODEC_ID_MSBC) {
- codec_info[0] = MSBC_TYPE;
- codec_info[1] = 16;
- }
- #endif
- btsrv_rdm_hfp_set_codec_info(conn, codec_id, codec_info[1]);
- if (conn == btsrv_rdm_hfp_get_actived() || conn == btsrv_rdm_get_tws_by_role(BTSRV_TWS_SLAVE))
- hfp_context.hfp_user_callback(BTSRV_HFP_CODEC_INFO, codec_info, sizeof(codec_info));
- return 0;
- }
- static int _btsrv_hfp_volume_change(struct bt_conn *conn, uint8_t volume)
- {
- if (conn == btsrv_rdm_hfp_get_actived())
- hfp_context.hfp_user_callback(BTSRV_HFP_VOLUME_CHANGE, (uint8_t *)&volume, sizeof(volume));
- return 0;
- }
- static int _btsrv_hfp_active_dev_change(struct bt_conn *conn)
- {
- if (conn == btsrv_rdm_hfp_get_actived()) {
- #ifdef CONFIG_SUPPORT_TWS
- if(btsrv_rdm_get_dev_role() == BTSRV_TWS_MASTER){
- btsrv_tws_hfp_stop_call();
- }
- #endif
- hfp_context.hfp_user_callback(BTSRV_HFP_ACTIVE_DEV_CHANGE, NULL, 0);
- int state = btsrv_rdm_hfp_get_state(conn);
- int sco_state = btsrv_rdm_hfp_get_sco_state(conn);
- if(!btsrv_rdm_hfp_get_actived_sco()){
- if ((state >= BTSRV_HFP_STATE_CALL_ONGOING && state <= BTSRV_HFP_STATE_CALL_MULTIPARTY) ||
- (state >= BTSRV_HFP_STATE_CALL_INCOMING && state <= BTSRV_HFP_STATE_CALL_ALERTED &&
- sco_state == BTSRV_SCO_STATE_PHONE))
- if (btsrv_allow_sco_connect()) {
- hostif_bt_conn_create_sco(conn);
- }
- }else{
- struct thread_timer *sco_disconnect_timer = btsrv_rdm_get_sco_disconnect_timer(conn);
- if(thread_timer_is_running(sco_disconnect_timer)){
- thread_timer_stop(sco_disconnect_timer);
- }
- if(sco_state != BTSRV_SCO_STATE_DISCONNECT){
- _btsrv_hfp_update_codec_info();
- _btsrv_hfp_tws_start_call();
- hfp_context.hfp_user_callback(BTSRV_SCO_CONNECTED, NULL, 0);
- }
- }
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- if(second_conn && btsrv_rdm_hfp_get_notify_phone_num_state(second_conn)){
- hfp_context.hfp_user_callback(BTSRV_HFP_PHONE_NUM_STOP, NULL, 0);
- btsrv_rdm_hfp_set_notify_phone_num_state(second_conn,0);
- }
- }
- return 0;
- }
- static int _btsrv_hfp_siri_state_change(struct bt_conn *conn, uint8_t state)
- {
- if (conn == btsrv_rdm_hfp_get_actived())
- hfp_context.hfp_user_callback(BTSRV_HFP_SIRI_STATE_CHANGE, (uint8_t *)&state, sizeof(state));
- return 0;
- }
- static int _btsrv_hfp_time_update(struct bt_conn *conn, char *data)
- {
- /* call back to uplayer , play tts deceide by up layer*/
- if (conn == btsrv_rdm_hfp_get_actived()) {
- hfp_context.hfp_user_callback(BTSRV_HFP_TIME_UPDATE, data, strlen(data));
- }
- return 0;
- }
- static int _btsrv_hfp_cgmi_update(struct bt_conn *conn, char *data)
- {
- /* call back to uplayer , play tts deceide by up layer*/
- if (conn == btsrv_rdm_hfp_get_actived()) {
- hfp_context.hfp_user_callback(BTSRV_HFP_CGMI_UPDATE, data, strlen(data));
- }
- return 0;
- }
- static int _btsrv_hfp_hf_switch_sound_source(void)
- {
- struct bt_conn *sco_conn = btsrv_rdm_hfp_get_actived_sco();
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- int state;
- if(second_conn)
- state = btsrv_rdm_hfp_get_state(second_conn);
- if (!br_conn)
- return -ESRCH;
- if (sco_conn) {
- if (second_conn && (state >= BTSRV_HFP_STATE_CALL_INCOMING
- && state <= BTSRV_HFP_STATE_SCO_ESTABLISHED)){
- btsrv_rdm_hfp_actived(second_conn, 1, 1);
- }
- btsrv_sco_disconnect(sco_conn);
- } else {
- if (second_conn && (state >= BTSRV_HFP_STATE_CALL_INCOMING
- && state <= BTSRV_HFP_STATE_SCO_ESTABLISHED)){
- btsrv_rdm_hfp_actived(second_conn, 1, 1);
- return 0;
- }
- /* phone which has ring tone will creat sco buring incoming
- * so we don't creat sco during incoming except for BTSRV_SCO_STATE_PHONE state
- * this state means sco has been created before.
- */
- int sco_state = btsrv_rdm_hfp_get_sco_state(br_conn);
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if ((state >= BTSRV_HFP_STATE_CALL_ONGOING && state <= BTSRV_HFP_STATE_CALL_MULTIPARTY) ||
- (state >= BTSRV_HFP_STATE_CALL_INCOMING && state <= BTSRV_HFP_STATE_CALL_ALERTED &&
- sco_state == BTSRV_SCO_STATE_PHONE)) {
- if (btsrv_allow_sco_connect()) {
- hostif_bt_conn_create_sco(br_conn);
- }
- }
- }
- return 0;
- }
- static int _btsrv_hfp_hf_dial_number(uint8_t *number)
- {
- char at_command[32];
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- snprintf(at_command, sizeof(at_command), "ATD%s;\r", number);
- hostif_bt_hfp_hf_send_cmd(br_conn, at_command);
- return 0;
- }
- static int _btsrv_hfp_hf_dial_last_number(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state != BTSRV_HFP_STATE_LINKED && state != BTSRV_HFP_STATE_CALL_ONGOING &&
- state != BTSRV_HFP_STATE_SCO_ESTABLISHED)
- return -EBUSY;
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+BLDN\r");
- return 0;
- }
- static int _btsrv_hfp_hf_dial_memory(int location)
- {
- char at_command[32];
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- snprintf(at_command, sizeof(at_command), "ATD>%u;\r", location);
- hostif_bt_hfp_hf_send_cmd(br_conn, at_command);
- return 0;
- }
- static int _btsrv_hfp_hf_volume_control(uint8_t type, uint8_t volume)
- {
- char at_command[32];
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- if (type == 0x01) {
- snprintf(at_command, sizeof(at_command), "AT+VGS=%u\r", volume);
- } else {
- snprintf(at_command, sizeof(at_command), "AT+VGM=%u\r", volume);
- }
- hostif_bt_hfp_hf_send_cmd(br_conn, at_command);
- return 0;
- }
- static int _btsrv_hfp_hf_battery_report(uint8_t mode, uint8_t bat_val)
- {
- char at_command[32];
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- if (mode == 0x01) {
- snprintf(at_command, sizeof(at_command), "AT+XAPL=0000-0000-0100,2\r");
- } else {
- snprintf(at_command, sizeof(at_command), "AT+IPHONEACCEV=1,1,%u\r", bat_val);
- }
- hostif_bt_hfp_hf_send_cmd(br_conn, at_command);
- br_conn = btsrv_rdm_hfp_get_second_dev();
- if (br_conn) {
- hostif_bt_hfp_hf_send_cmd(br_conn, at_command);
- }
- return 0;
- }
- static int btsrv_hfp_hf_disable_nrec(struct bt_conn *br_conn)
- {
- if (!br_conn)
- return -ESRCH;
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+NREC=0");
- return 0;
- }
- static int _btsrv_hfp_hf_accept_call(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state == BTSRV_HFP_STATE_CALL_INCOMING) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "ATA");
- }
- return 0;
- }
- static int _btsrv_hfp_hf_reject_call(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state == BTSRV_HFP_STATE_CALL_INCOMING) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHUP");
- }
- return 0;
- }
- static int _btsrv_hfp_hf_hangup_call(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state == BTSRV_HFP_STATE_CALL_ONGOING ||
- state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- state == BTSRV_HFP_STATE_CALL_ALERTED ||
- state == BTSRV_HFP_STATE_CALL_MULTIPARTY) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHUP");
- }
- return 0;
- }
- static int _btsrv_hfp_hf_hangup_another_call(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state == BTSRV_HFP_STATE_CALL_3WAYIN ||
- state == BTSRV_HFP_STATE_CALL_MULTIPARTY) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHLD=0");
- return 0;
- }
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- if (!second_conn)
- return 0;
- int other_dev_state = btsrv_rdm_hfp_get_state(second_conn);
- if (state == BTSRV_HFP_STATE_CALL_INCOMING) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "ATA");
- }
- switch (other_dev_state) {
- case BTSRV_HFP_STATE_CALL_INCOMING:
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- case BTSRV_HFP_STATE_CALL_ALERTED:
- case BTSRV_HFP_STATE_CALL_ONGOING:
- hostif_bt_hfp_hf_send_cmd(second_conn, "AT+CHUP");
- break;
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hostif_bt_hfp_hf_send_cmd(second_conn, "AT+CHLD=0");
- break;
- }
- return 0;
- }
- static int _btsrv_hfp_hf_holdcur_answer_call(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state == BTSRV_HFP_STATE_CALL_3WAYIN ||
- state == BTSRV_HFP_STATE_CALL_MULTIPARTY) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHLD=2");
- return 0;
- }
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- if (!second_conn)
- return 0;
- int other_dev_state = btsrv_rdm_hfp_get_state(second_conn);
- if (state == BTSRV_HFP_STATE_CALL_INCOMING) {
- if (other_dev_state == BTSRV_HFP_STATE_CALL_INCOMING ||
- other_dev_state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- other_dev_state == BTSRV_HFP_STATE_CALL_ALERTED) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "ATA");
- return 0;
- }
- }
- if (state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- state == BTSRV_HFP_STATE_CALL_ALERTED) {
- if (other_dev_state == BTSRV_HFP_STATE_CALL_OUTCOMING ||
- other_dev_state == BTSRV_HFP_STATE_CALL_ALERTED) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHUP");
- return 0;
- }
- }
- switch (state) {
- case BTSRV_HFP_STATE_SCO_ESTABLISHED: /* to do for siri */
- break;
- }
- switch (other_dev_state) {
- case BTSRV_HFP_STATE_CALL_INCOMING:
- hostif_bt_hfp_hf_send_cmd(second_conn, "ATA");
- break;
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hostif_bt_hfp_hf_send_cmd(second_conn, "AT+CHLD=2");
- break;
- }
- btsrv_rdm_hfp_actived(second_conn, 1, 1);
- return 0;
- }
- static int _btsrv_hfp_hf_hangupcur_answer_call(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- int state = btsrv_rdm_hfp_get_state(br_conn);
- if (state == BTSRV_HFP_STATE_CALL_3WAYIN ||
- state == BTSRV_HFP_STATE_CALL_MULTIPARTY) {
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHLD=1");
- return 0;
- }
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- if (!second_conn)
- return 0;
- int other_dev_state = btsrv_rdm_hfp_get_state(second_conn);
- switch (state) {
- case BTSRV_HFP_STATE_CALL_INCOMING:
- case BTSRV_HFP_STATE_CALL_OUTCOMING:
- case BTSRV_HFP_STATE_CALL_ALERTED:
- case BTSRV_HFP_STATE_CALL_ONGOING:
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CHUP");
- break;
- case BTSRV_HFP_STATE_SCO_ESTABLISHED: /* to do */
- break;
- }
- switch (other_dev_state) {
- case BTSRV_HFP_STATE_CALL_INCOMING:
- hostif_bt_hfp_hf_send_cmd(second_conn, "ATA");
- break;
- case BTSRV_HFP_STATE_CALL_3WAYIN:
- case BTSRV_HFP_STATE_CALL_MULTIPARTY:
- hostif_bt_hfp_hf_send_cmd(second_conn, "AT+CHLD=1");
- break;
- }
- btsrv_rdm_hfp_actived(second_conn, 1, 1);
- return 0;
- }
- static int _btsrv_hfp_hf_voice_recognition_start(void)
- {
- uint8_t srir_state = BTSRV_HFP_SIRI_CHANGE_START;
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- int state;
- if (!br_conn) {
- return -ESRCH;
- }
- state = btsrv_rdm_hfp_get_state(br_conn);
- if (state >= BTSRV_HFP_STATE_CALL_INCOMING &&
- state <= BTSRV_HFP_STATE_SCO_ESTABLISHED) {
- return -EBUSY;
- }
- hfp_context.hfp_user_callback(BTSRV_HFP_SIRI_STATE_CHANGE, (uint8_t *)&srir_state, sizeof(srir_state));
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+BVRA=1");
- return 0;
- }
- static int _btsrv_hfp_hf_voice_recognition_stop(void)
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+BVRA=0");
- return 0;
- }
- static int _btsrv_hfp_get_time()
- {
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- hostif_bt_hfp_hf_send_cmd(br_conn, "AT+CCLK?");
- return 0;
- }
- static int _btsrv_hfp_hf_send_at_command(uint8_t *command,uint8_t active_call)
- {
- if(active_call){
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- hostif_bt_hfp_hf_send_cmd(br_conn, command);
- }else{
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- if (!second_conn)
- return -ESRCH;
- hostif_bt_hfp_hf_send_cmd(second_conn, command);
- }
- return 0;
- }
- int btsrv_hfp_get_call_state(uint8_t active_call,uint8_t *call_state)
- {
- uint8_t active_state,held_call,incoming_call,outgoing_call;
- if(active_call){
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return BTSRV_HFP_STATE_INIT;
- if(!btsrv_rdm_hfp_get_call_state(br_conn,
- &active_state,
- &held_call,
- &incoming_call,
- &outgoing_call)){
- if(call_state){
- *call_state = ((active_state << 4) | (held_call << 2)
- | (incoming_call << 1) | outgoing_call);
- }
- }
- return btsrv_rdm_hfp_get_state(br_conn);
- }else{
- struct bt_conn *second_conn = btsrv_rdm_hfp_get_second_dev();
- if (!second_conn)
- return BTSRV_HFP_STATE_INIT;
- if(!btsrv_rdm_hfp_get_call_state(second_conn,
- &active_state,
- &held_call,
- &incoming_call,
- &outgoing_call)){
- if(call_state){
- *call_state = ((active_state << 4) | (held_call << 2)
- | (incoming_call << 1) | outgoing_call);
- }
- }
- return btsrv_rdm_hfp_get_state(second_conn);
- }
- }
- static void _btsrv_hfp_service_notify(struct bt_conn *conn, uint8_t service)
- {
- btsrv_rdm_set_hfp_service(conn, service);
- }
- static int _btsrv_hfp_hf_battery_indicator(struct bt_conn *conn, char *data)
- {
- if (conn == btsrv_rdm_hfp_get_actived()) {
- hfp_context.hfp_user_callback(BTSRV_HFP_BATTERY_HPREC, NULL, 0);
- }
- return 0;
- }
- static int _btsrv_hfp_hf_battery_hprec_report(uint8_t bat_val)
- {
- char at_command[32];
- struct bt_conn *br_conn = btsrv_rdm_hfp_get_actived();
- if (!br_conn)
- return -ESRCH;
- if (bat_val > 100)
- bat_val = 100;
- snprintf(at_command, sizeof(at_command), "AT+BIEV=2,%u\r", bat_val);
- hostif_bt_hfp_hf_send_cmd(br_conn, at_command);
- return 0;
- }
- int btsrv_hfp_process(struct app_msg *msg)
- {
- struct bt_conn *param;
- if (_btsrv_get_msg_param_type(msg) != MSG_BTSRV_HFP) {
- return -ENOTSUP;
- }
- switch (_btsrv_get_msg_param_cmd(msg)) {
- case MSG_BTSRV_HFP_START:
- SYS_LOG_INF("BHF start");
- btsrv_hfp_init(msg->ptr);
- break;
- case MSG_BTSRV_HFP_STOP:
- SYS_LOG_INF("BHF stop");
- btsrv_hfp_deinit();
- break;
- case MSG_BTSRV_HFP_CONNECTED:
- _btsrv_hfp_connected(msg->ptr);
- break;
- case MSG_BTSRV_HFP_DISCONNECTED:
- _btsrv_hfp_disconnected(msg->ptr);
- btsrv_event_notify(MSG_BTSRV_CONNECT, _btsrv_get_msg_param_cmd(msg), msg->ptr);
- break;
- case MSG_BTSRV_HFP_SET_STATE:
- SYS_LOG_INF("BHF set state");
- btsrv_hfp_set_status(msg->ptr, msg->reserve);
- break;
- case MSG_BTSRV_HFP_HF_DIAL_NUM:
- SYS_LOG_INF("BHF dial num");
- _btsrv_hfp_hf_dial_number(msg->ptr);
- break;
- case MSG_BTSRV_HFP_HF_DIAL_LAST_NUM:
- SYS_LOG_INF("BHF last num");
- _btsrv_hfp_hf_dial_last_number();
- break;
- case MSG_BTSRV_HFP_HF_DIAL_MEMORY:
- SYS_LOG_INF("BHF dial mem");
- _btsrv_hfp_hf_dial_memory(msg->value);
- break;
- case MSG_BTSRV_HFP_HF_VOLUME_CONTROL:
- SYS_LOG_INF("BHF vol ctrl");
- _btsrv_hfp_hf_volume_control((uint8_t)(msg->value >> 16), (uint8_t)msg->value);
- break;
- case MSG_BTSRV_HFP_HF_BATTERY_REPORT:
- SYS_LOG_INF("BHF bat rep");
- _btsrv_hfp_hf_battery_report((uint8_t)(msg->value >> 16), (uint8_t)msg->value);
- break;
- case MSG_BTSRV_HFP_HF_ACCEPT_CALL:
- SYS_LOG_INF("BHF accep call");
- _btsrv_hfp_hf_accept_call();
- break;
- case MSG_BTSRV_HFP_HF_REJECT_CALL:
- SYS_LOG_INF("BHF reject call");
- _btsrv_hfp_hf_reject_call();
- break;
- case MSG_BTSRV_HFP_HF_HANGUP_CALL:
- SYS_LOG_INF("BHF hangup call");
- _btsrv_hfp_hf_hangup_call();
- break;
- case MSG_BTSRV_HFP_HF_HANGUP_ANOTHER_CALL:
- SYS_LOG_INF("BHF hangup another call");
- _btsrv_hfp_hf_hangup_another_call();
- break;
- case MSG_BTSRV_HFP_HF_HOLDCUR_ANSWER_CALL:
- SYS_LOG_INF("BHF holdcur answer call");
- _btsrv_hfp_hf_holdcur_answer_call();
- break;
- case MSG_BTSRV_HFP_HF_HANGUPCUR_ANSWER_CALL:
- SYS_LOG_INF("BHF hangupcur answer call");
- _btsrv_hfp_hf_hangupcur_answer_call();
- break;
- case MSG_BTSRV_HFP_HF_VOICE_RECOGNITION_START:
- SYS_LOG_INF("BHF voice rec start");
- _btsrv_hfp_hf_voice_recognition_start();
- break;
- case MSG_BTSRV_HFP_HF_VOICE_RECOGNITION_STOP:
- SYS_LOG_INF("BHF voice rec stop");
- _btsrv_hfp_hf_voice_recognition_stop();
- break;
- case MSG_BTSRV_HFP_HF_VOICE_SEND_AT_COMMAND:
- SYS_LOG_INF("BHF send at cmd");
- _btsrv_hfp_hf_send_at_command(msg->ptr, _btsrv_get_msg_param_reserve(msg));
- break;
- case MSG_BTSRV_HFP_SWITCH_SOUND_SOURCE:
- SYS_LOG_INF("BHF switch sound source");
- _btsrv_hfp_hf_switch_sound_source();
- break;
- case MSG_BTSRV_HFP_PHONE_NUM:
- SYS_LOG_INF("BHF phone num");
- param = (struct bt_conn *) *(int *)(msg->ptr);
- _btsrv_hfp_phone_num(param, (char *)((uint32_t)msg->ptr+4));
- break;
- case MSG_BTSRV_HFP_PHONE_NAME:
- SYS_LOG_INF("BHF phone name");
- param = (struct bt_conn *) *(int *)(msg->ptr);
- _btsrv_hfp_phone_name(param, (char *)((uint32_t)msg->ptr+4));
- break;
- case MSG_BTSRV_HFP_HF_CCWA_PHONE_NUM:
- SYS_LOG_INF("BHF ccwa num");
- param = (struct bt_conn *) *(int *)(msg->ptr);
- _btsrv_hfp_hf_ccwa_phone_num(param, (char *)((uint32_t)msg->ptr+4));
- break;
- case MSG_BTSRV_HFP_CODEC_INFO:
- SYS_LOG_INF("BHF codec info");
- _btsrv_hfp_codec_info(msg->ptr, msg->reserve);
- break;
- case MSG_BTSRV_HFP_VOLUME_CHANGE:
- SYS_LOG_INF("BHF vol change");
- _btsrv_hfp_volume_change(msg->ptr, msg->reserve);
- break;
- case MSG_BTSRV_HFP_ACTIVED_DEV_CHANGED:
- SYS_LOG_INF("BHF active dev change");
- _btsrv_hfp_active_dev_change(msg->ptr);
- break;
- case MSG_BTSRV_HFP_SIRI_STATE:
- SYS_LOG_INF("BHF siri state change");
- _btsrv_hfp_siri_state_change(msg->ptr, msg->reserve);
- break;
- case MSG_BTSRV_HFP_TIME_UPDATE:
- SYS_LOG_INF("BHF time update");
- param = (struct bt_conn *) *(int *)(msg->ptr);
- _btsrv_hfp_time_update(param, (char *)(msg->ptr)+4);
- break;
- case MSG_BTSRV_HFP_MANUFACTURE_INFO:
- SYS_LOG_INF("BHF man info");
- param = (struct bt_conn *) *(int *)(msg->ptr);
- _btsrv_hfp_cgmi_update(param, (char *)(msg->ptr)+4);
- case MSG_BTSRV_HFP_GET_TIME:
- SYS_LOG_INF("BHF get time");
- _btsrv_hfp_get_time();
- break;
- case MSG_BTSRV_HFP_CLCC_INFO:
- _btsrv_hfp_hf_clcc_info((struct btsrv_hfp_clcc_info *)(msg->ptr));
- break;
- case MSG_BTSRV_HFP_SERVICE:
- _btsrv_hfp_service_notify(_btsrv_get_msg_param_ptr(msg), _btsrv_get_msg_param_reserve(msg));
- break;
- case MSG_BTSRV_HFP_HPREC_BATTERY:
- _btsrv_hfp_hf_battery_indicator(_btsrv_get_msg_param_ptr(msg), NULL);
- break;
- case MSG_BTSRV_HFP_HF_BATTERY_HPREC_REPORT:
- SYS_LOG_INF("BHF high precision bat rep");
- _btsrv_hfp_hf_battery_hprec_report((uint8_t)msg->value);
- break;
- }
- return 0;
- }
|