hfp_hf.c (3c65e7053eb0574febf31fb17a58168d45bb11e2) hfp_hf.c (af97579e443f2c6b71882d1189eb88c19629f90f)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 461 unchanged lines hidden (view full) ---

470 done = 1;
471 hfp_hf_cmd_enable_extended_audio_gateway_error_report(hfp_connection->rfcomm_cid, hfp_connection->enable_extended_audio_gateway_error_report);
472 return done;
473 }
474
475 return done;
476}
477
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 461 unchanged lines hidden (view full) ---

470 done = 1;
471 hfp_hf_cmd_enable_extended_audio_gateway_error_report(hfp_connection->rfcomm_cid, hfp_connection->enable_extended_audio_gateway_error_report);
472 return done;
473 }
474
475 return done;
476}
477
478static int voice_recognition_state_machine(hfp_connection_t * hfp_connection){
478static int hfp_hf_voice_recognition_state_machine(hfp_connection_t * hfp_connection){
479 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) {
480 return 0;
481 }
479 if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) {
480 return 0;
481 }
482 printf("hfp_hf_voice_recognition_state_machine, status %d\n", hfp_connection->vra_status);
482 int done = 0;
483 if (hfp_connection->ok_pending == 0) {
484 switch (hfp_connection->vra_status){
485 case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
486 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_OFF:
487 hfp_connection->ok_pending = 1;
488 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 0);
489 break;

--- 181 unchanged lines hidden (view full) ---

671 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
672 return;
673 }
674 int done = hfp_hf_run_for_context_service_level_connection(hfp_connection);
675 if (!done){
676 done = hfp_hf_run_for_context_service_level_connection_queries(hfp_connection);
677 }
678 if (!done){
483 int done = 0;
484 if (hfp_connection->ok_pending == 0) {
485 switch (hfp_connection->vra_status){
486 case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
487 case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_OFF:
488 hfp_connection->ok_pending = 1;
489 hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 0);
490 break;

--- 181 unchanged lines hidden (view full) ---

672 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
673 return;
674 }
675 int done = hfp_hf_run_for_context_service_level_connection(hfp_connection);
676 if (!done){
677 done = hfp_hf_run_for_context_service_level_connection_queries(hfp_connection);
678 }
679 if (!done){
679 done = voice_recognition_state_machine(hfp_connection);
680 done = hfp_hf_voice_recognition_state_machine(hfp_connection);
680 }
681 if (!done){
682 done = hfp_hf_run_for_audio_connection(hfp_connection);
683 }
684 if (!done){
685 done = call_setup_state_machine(hfp_connection);
686 }
687

--- 347 unchanged lines hidden (view full) ---

1035 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
1036 break;
1037 case HFP_CODECS_HF_CONFIRMED_CODEC:
1038 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
1039 break;
1040 default:
1041 break;
1042 }
681 }
682 if (!done){
683 done = hfp_hf_run_for_audio_connection(hfp_connection);
684 }
685 if (!done){
686 done = call_setup_state_machine(hfp_connection);
687 }
688

--- 347 unchanged lines hidden (view full) ---

1036 hfp_connection->codecs_state = HFP_CODECS_W4_AG_COMMON_CODEC;
1037 break;
1038 case HFP_CODECS_HF_CONFIRMED_CODEC:
1039 hfp_connection->codecs_state = HFP_CODECS_EXCHANGED;
1040 break;
1041 default:
1042 break;
1043 }
1043 voice_recognition_state_machine(hfp_connection);
1044 hfp_hf_voice_recognition_state_machine(hfp_connection);
1044 break;
1045 case HFP_AUDIO_CONNECTION_ESTABLISHED:
1045 break;
1046 case HFP_AUDIO_CONNECTION_ESTABLISHED:
1046 voice_recognition_state_machine(hfp_connection);
1047 hfp_hf_voice_recognition_state_machine(hfp_connection);
1047 break;
1048 default:
1049 break;
1050 }
1051
1052 // done
1053 hfp_connection->ok_pending = 0;
1054 hfp_connection->command = HFP_CMD_NONE;

--- 642 unchanged lines hidden (view full) ---

1697}
1698
1699static bool hfp_hf_voice_recognition_supported(hfp_connection_t * hfp_connection){
1700 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION);
1701 int hf = get_bit(hfp_supported_features, HFP_HFSF_VOICE_RECOGNITION_FUNCTION);
1702 return hf && ag;
1703}
1704
1048 break;
1049 default:
1050 break;
1051 }
1052
1053 // done
1054 hfp_connection->ok_pending = 0;
1055 hfp_connection->command = HFP_CMD_NONE;

--- 642 unchanged lines hidden (view full) ---

1698}
1699
1700static bool hfp_hf_voice_recognition_supported(hfp_connection_t * hfp_connection){
1701 int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION);
1702 int hf = get_bit(hfp_supported_features, HFP_HFSF_VOICE_RECOGNITION_FUNCTION);
1703 return hf && ag;
1704}
1705
1705uint8_t hfp_hf_activate_voice_recognition_notification(hci_con_handle_t acl_handle){
1706 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1707 if (!hfp_connection) {
1708 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1709 }
1710 if (!hfp_hf_voice_recognition_supported(hfp_connection)){
1706static uint8_t hfp_hf_activate_enhanced_voice_recognition_for_connection(hfp_connection_t * hfp_connection){
1707 if (!hfp_hf_enhanced_voice_recognition_supported(hfp_connection)){
1711 return ERROR_CODE_COMMAND_DISALLOWED;
1712 }
1708 return ERROR_CODE_COMMAND_DISALLOWED;
1709 }
1713
1714 switch (hfp_connection->vra_status){
1710 switch (hfp_connection->vra_status){
1715 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
1716 hfp_emit_event(hfp_connection, HFP_SUBEVENT_VOICE_RECOGNITION_STATUS, 1);
1717 break;
1718 case HFP_VRA_VOICE_RECOGNITION_OFF:
1711 case HFP_VRA_VOICE_RECOGNITION_OFF:
1719 hfp_connection->vra_status = HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED;
1712 hfp_connection->vra_status = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_ACTIVATED;
1720 hfp_hf_run_for_context(hfp_connection);
1721 break;
1722 default:
1723 return ERROR_CODE_COMMAND_DISALLOWED;
1724 }
1725 return ERROR_CODE_SUCCESS;
1726}
1727
1713 hfp_hf_run_for_context(hfp_connection);
1714 break;
1715 default:
1716 return ERROR_CODE_COMMAND_DISALLOWED;
1717 }
1718 return ERROR_CODE_SUCCESS;
1719}
1720
1728
1729uint8_t hfp_hf_start_enhanced_voice_recognition_session(hci_con_handle_t acl_handle){
1730 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1731 if (!hfp_connection) {
1732 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1733 }
1734
1721static uint8_t hfp_hf_deactivate_enhanced_voice_recognition_for_connection(hfp_connection_t * hfp_connection){
1735 if (!hfp_hf_enhanced_voice_recognition_supported(hfp_connection)){
1736 return ERROR_CODE_COMMAND_DISALLOWED;
1737 }
1722 if (!hfp_hf_enhanced_voice_recognition_supported(hfp_connection)){
1723 return ERROR_CODE_COMMAND_DISALLOWED;
1724 }
1738
1739 switch (hfp_connection->vra_status){
1740 case HFP_VRA_ENHANCED_VOICE_RECOGNITION_ACTIVATED:
1725 switch (hfp_connection->vra_status){
1726 case HFP_VRA_ENHANCED_VOICE_RECOGNITION_ACTIVATED:
1741 case HFP_VRA_VOICE_RECOGNITION_OFF:
1742 hfp_connection->vra_status = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_ACTIVATED;
1727 hfp_connection->vra_status = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_OFF;
1743 hfp_hf_run_for_context(hfp_connection);
1744 break;
1745 default:
1746 return ERROR_CODE_COMMAND_DISALLOWED;
1747 }
1748 return ERROR_CODE_SUCCESS;
1749}
1750
1728 hfp_hf_run_for_context(hfp_connection);
1729 break;
1730 default:
1731 return ERROR_CODE_COMMAND_DISALLOWED;
1732 }
1733 return ERROR_CODE_SUCCESS;
1734}
1735
1751static uint8_t hfp_hf_deactivate_voice_recognition(hfp_connection_t * hfp_connection){
1736static uint8_t hfp_hf_deactivate_voice_recognition_for_connection(hfp_connection_t * hfp_connection){
1737 if (!hfp_hf_voice_recognition_supported(hfp_connection)){
1738 return ERROR_CODE_COMMAND_DISALLOWED;
1739 }
1740
1752 switch (hfp_connection->vra_status){
1741 switch (hfp_connection->vra_status){
1753 case HFP_VRA_VOICE_RECOGNITION_OFF:
1754 hfp_emit_event(hfp_connection, HFP_SUBEVENT_VOICE_RECOGNITION_STATUS, 0);
1755 break;
1756 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
1757 hfp_connection->vra_status = HFP_VRA_W4_VOICE_RECOGNITION_OFF;
1758 hfp_hf_run_for_context(hfp_connection);
1759 break;
1742 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
1743 hfp_connection->vra_status = HFP_VRA_W4_VOICE_RECOGNITION_OFF;
1744 hfp_hf_run_for_context(hfp_connection);
1745 break;
1760 case HFP_VRA_ENHANCED_VOICE_RECOGNITION_ACTIVATED:
1761 hfp_connection->vra_status = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_OFF;
1746 default:
1747 return ERROR_CODE_COMMAND_DISALLOWED;
1748 }
1749 return ERROR_CODE_SUCCESS;
1750}
1751
1752static uint8_t hfp_hf_activate_voice_recognition_for_connection(hfp_connection_t * hfp_connection){
1753 if (!hfp_hf_voice_recognition_supported(hfp_connection)){
1754 return ERROR_CODE_COMMAND_DISALLOWED;
1755 }
1756
1757 switch (hfp_connection->vra_status){
1758 case HFP_VRA_VOICE_RECOGNITION_OFF:
1759 hfp_connection->vra_status = HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED;
1762 hfp_hf_run_for_context(hfp_connection);
1763 break;
1764 default:
1765 return ERROR_CODE_COMMAND_DISALLOWED;
1766 }
1767 return ERROR_CODE_SUCCESS;
1768}
1769
1770
1760 hfp_hf_run_for_context(hfp_connection);
1761 break;
1762 default:
1763 return ERROR_CODE_COMMAND_DISALLOWED;
1764 }
1765 return ERROR_CODE_SUCCESS;
1766}
1767
1768
1771uint8_t hfp_hf_deactivate_voice_recognition_notification(hci_con_handle_t acl_handle){
1769uint8_t hfp_hf_activate_voice_recognition(hci_con_handle_t acl_handle){
1772 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1773 if (!hfp_connection) {
1774 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1775 }
1770 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1771 if (!hfp_connection) {
1772 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1773 }
1776 if (!hfp_hf_voice_recognition_supported(hfp_connection)){
1777 return ERROR_CODE_COMMAND_DISALLOWED;
1774 uint8_t status = hfp_hf_activate_voice_recognition_for_connection(hfp_connection);
1775 if (status == ERROR_CODE_SUCCESS){
1776 hfp_hf_run_for_context(hfp_connection);
1778 }
1777 }
1779 return hfp_hf_deactivate_voice_recognition(hfp_connection);
1778 return status;
1780}
1781
1779}
1780
1781uint8_t hfp_hf_deactivate_voice_recognition(hci_con_handle_t acl_handle){
1782 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1783 if (!hfp_connection) {
1784 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1785 }
1786 uint8_t status = hfp_hf_deactivate_voice_recognition_for_connection(hfp_connection);
1787 if (status == ERROR_CODE_SUCCESS){
1788 hfp_hf_run_for_context(hfp_connection);
1789 }
1790 return status;
1791}
1782
1792
1793uint8_t hfp_hf_start_enhanced_voice_recognition_session(hci_con_handle_t acl_handle){
1794 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1795 if (!hfp_connection) {
1796 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1797 }
1798 uint8_t status = hfp_hf_activate_enhanced_voice_recognition_for_connection(hfp_connection);
1799 if (status == ERROR_CODE_SUCCESS){
1800 hfp_hf_run_for_context(hfp_connection);
1801 }
1802 return status;
1803}
1804
1783uint8_t hfp_hf_stop_enhanced_voice_recognition_session(hci_con_handle_t acl_handle){
1784 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1785 if (!hfp_connection) {
1786 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1787 }
1805uint8_t hfp_hf_stop_enhanced_voice_recognition_session(hci_con_handle_t acl_handle){
1806 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1807 if (!hfp_connection) {
1808 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1809 }
1788 if (!hfp_hf_enhanced_voice_recognition_supported(hfp_connection)){
1789 return ERROR_CODE_COMMAND_DISALLOWED;
1810
1811 uint8_t status = hfp_hf_deactivate_enhanced_voice_recognition_for_connection(hfp_connection);
1812 if (status == ERROR_CODE_SUCCESS){
1813 hfp_hf_run_for_context(hfp_connection);
1790 }
1814 }
1791 return hfp_hf_deactivate_voice_recognition(hfp_connection);
1815 return status;
1792}
1793
1794uint8_t hfp_hf_set_microphone_gain(hci_con_handle_t acl_handle, int gain){
1795 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1796 if (!hfp_connection) {
1797 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1798 }
1799

--- 188 unchanged lines hidden ---
1816}
1817
1818uint8_t hfp_hf_set_microphone_gain(hci_con_handle_t acl_handle, int gain){
1819 hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
1820 if (!hfp_connection) {
1821 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
1822 }
1823

--- 188 unchanged lines hidden ---