@@ -592,6 +592,41 @@ static void hf_call_state_update(struct bt_hfp_hf_call *call, int state)
592
592
}
593
593
}
594
594
595
+ static int get_using_call_count (struct bt_hfp_hf * hf )
596
+ {
597
+ struct bt_hfp_hf_call * call ;
598
+ int count = 0 ;
599
+
600
+ ARRAY_FOR_EACH (hf -> calls , i ) {
601
+ call = & hf -> calls [i ];
602
+
603
+ if (atomic_test_bit (call -> flags , BT_HFP_HF_CALL_IN_USING )) {
604
+ count ++ ;
605
+ }
606
+ }
607
+
608
+ return count ;
609
+ }
610
+
611
+ static struct bt_hfp_hf_call * get_new_call (struct bt_hfp_hf * hf )
612
+ {
613
+ struct bt_hfp_hf_call * call ;
614
+
615
+ ARRAY_FOR_EACH (hf -> calls , i ) {
616
+ call = & hf -> calls [i ];
617
+
618
+ if (atomic_test_and_set_bit (call -> flags , BT_HFP_HF_CALL_IN_USING )) {
619
+ continue ;
620
+ }
621
+
622
+ call -> hf = hf ;
623
+
624
+ return call ;
625
+ }
626
+
627
+ return NULL ;
628
+ }
629
+
595
630
#if defined(CONFIG_BT_HFP_HF_ECS )
596
631
static void call_state_update (struct bt_hfp_hf_call * call , uint32_t status )
597
632
{
@@ -645,6 +680,89 @@ static void call_state_update(struct bt_hfp_hf_call *call, uint32_t status)
645
680
}
646
681
}
647
682
683
+ static void new_call_state_update (struct bt_hfp_hf_call * call , bool incoming , uint32_t status )
684
+ {
685
+ switch (status ) {
686
+ case BT_HFP_CLCC_STATUS_ACTIVE :
687
+ case BT_HFP_CLCC_STATUS_HELD :
688
+ case BT_HFP_CLCC_STATUS_DIALING :
689
+ case BT_HFP_CLCC_STATUS_ALERTING :
690
+ case BT_HFP_CLCC_STATUS_INCOMING :
691
+ case BT_HFP_CLCC_STATUS_WAITING :
692
+ case BT_HFP_CLCC_STATUS_CALL_HELD_HOLD :
693
+ if (incoming ) {
694
+ if (bt_hf -> incoming ) {
695
+ bt_hf -> incoming (call -> hf , call );
696
+ }
697
+ } else {
698
+ if (bt_hf -> outgoing ) {
699
+ bt_hf -> outgoing (call -> hf , call );
700
+ }
701
+ }
702
+ break ;
703
+ default :
704
+ LOG_WRN ("Invalid call status %u" , status );
705
+ free_call (call );
706
+ return ;
707
+ }
708
+
709
+ switch (status ) {
710
+ case BT_HFP_CLCC_STATUS_ACTIVE :
711
+ hf_call_state_update (call , BT_HFP_HF_CALL_STATE_ACTIVE );
712
+ if (bt_hf -> accept ) {
713
+ bt_hf -> accept (call );
714
+ }
715
+ break ;
716
+ case BT_HFP_CLCC_STATUS_HELD :
717
+ hf_call_state_update (call , BT_HFP_HF_CALL_STATE_HELD );
718
+ if (bt_hf -> held ) {
719
+ bt_hf -> held (call );
720
+ }
721
+ break ;
722
+ case BT_HFP_CLCC_STATUS_DIALING :
723
+ hf_call_state_update (call , BT_HFP_HF_CALL_STATE_OUTGOING );
724
+ if (bt_hf -> dialing ) {
725
+ bt_hf -> dialing (call -> hf , 0 );
726
+ }
727
+ break ;
728
+ case BT_HFP_CLCC_STATUS_ALERTING :
729
+ hf_call_state_update (call , BT_HFP_HF_CALL_STATE_ALERTING );
730
+ if (bt_hf -> remote_ringing ) {
731
+ bt_hf -> remote_ringing (call );
732
+ }
733
+ break ;
734
+ case BT_HFP_CLCC_STATUS_INCOMING :
735
+ case BT_HFP_CLCC_STATUS_WAITING :
736
+ hf_call_state_update (call , BT_HFP_HF_CALL_STATE_WAITING );
737
+ break ;
738
+ case BT_HFP_CLCC_STATUS_CALL_HELD_HOLD :
739
+ atomic_set_bit (call -> flags , BT_HFP_HF_CALL_INCOMING_HELD );
740
+ hf_call_state_update (call , BT_HFP_HF_CALL_STATE_ACTIVE );
741
+ if (bt_hf -> incoming_held ) {
742
+ bt_hf -> incoming_held (call );
743
+ }
744
+ break ;
745
+ default :
746
+ break ;
747
+ }
748
+ }
749
+
750
+ static void set_call_incoming_flag (struct bt_hfp_hf_call * call , bool incoming )
751
+ {
752
+ int call_count ;
753
+
754
+ call_count = get_using_call_count (call -> hf );
755
+ if (call_count > 1 ) {
756
+ if (incoming ) {
757
+ atomic_test_bit (call -> flags , BT_HFP_HF_CALL_INCOMING_3WAY );
758
+ } else {
759
+ atomic_test_bit (call -> flags , BT_HFP_HF_CALL_OUTGOING_3WAY );
760
+ }
761
+ } else {
762
+ atomic_set_bit_to (call -> flags , BT_HFP_HF_CALL_INCOMING , incoming );
763
+ }
764
+ }
765
+
648
766
static int clcc_handle (struct at_client * hf_at )
649
767
{
650
768
struct bt_hfp_hf * hf = CONTAINER_OF (hf_at , struct bt_hfp_hf , at );
@@ -658,6 +776,7 @@ static int clcc_handle(struct at_client *hf_at)
658
776
char * number = NULL ;
659
777
uint32_t type = 0 ;
660
778
bool incoming = false;
779
+ bool new_call = false;
661
780
662
781
err = at_get_number (hf_at , & index );
663
782
if (err < 0 ) {
@@ -670,8 +789,12 @@ static int clcc_handle(struct at_client *hf_at)
670
789
LOG_INF ("Valid call with index %d not found" , index );
671
790
call = get_call_without_index (hf );
672
791
if (!call ) {
673
- LOG_INF ("Not available call" );
674
- return 0 ;
792
+ call = get_new_call (hf );
793
+ if (!call ) {
794
+ LOG_INF ("Not available call" );
795
+ return 0 ;
796
+ }
797
+ new_call = true;
675
798
}
676
799
call -> index = (uint8_t )index ;
677
800
}
@@ -684,12 +807,16 @@ static int clcc_handle(struct at_client *hf_at)
684
807
return err ;
685
808
}
686
809
810
+ if (new_call ) {
811
+ set_call_incoming_flag (call , dir == BT_HFP_CLCC_DIR_INCOMING );
812
+ }
813
+
687
814
if (atomic_test_bit (call -> flags , BT_HFP_HF_CALL_INCOMING ) ||
688
- atomic_test_bit (call -> flags , BT_HFP_HF_CALL_INCOMING_3WAY )) {
815
+ atomic_test_bit (call -> flags , BT_HFP_HF_CALL_INCOMING_3WAY )) {
689
816
incoming = true;
690
817
}
691
818
692
- if (incoming != !! dir ) {
819
+ if (incoming != ( dir == BT_HFP_CLCC_DIR_INCOMING ) ) {
693
820
LOG_ERR ("Call dir of HF is not aligned with AG" );
694
821
return 0 ;
695
822
}
@@ -718,7 +845,11 @@ static int clcc_handle(struct at_client *hf_at)
718
845
(void )at_get_number (hf_at , & type );
719
846
}
720
847
721
- call_state_update (call , status );
848
+ if (new_call ) {
849
+ new_call_state_update (call , incoming , status );
850
+ } else {
851
+ call_state_update (call , status );
852
+ }
722
853
723
854
LOG_DBG ("CLCC idx %d dir %d status %d mode %d mpty %d number %s type %d" ,
724
855
index , dir , status , mode , mpty , number , type );
@@ -922,43 +1053,6 @@ static void bt_hf_deferred_work(struct k_work *work)
922
1053
hf_query_current_calls (hf );
923
1054
}
924
1055
925
- static struct bt_hfp_hf_call * get_new_call (struct bt_hfp_hf * hf )
926
- {
927
- struct bt_hfp_hf_call * call ;
928
-
929
- for (size_t index = 0 ; index < ARRAY_SIZE (hf -> calls ); index ++ ) {
930
- call = & hf -> calls [index ];
931
-
932
- if (atomic_test_and_set_bit (call -> flags , BT_HFP_HF_CALL_IN_USING )) {
933
- continue ;
934
- }
935
-
936
- call -> hf = hf ;
937
-
938
- return call ;
939
- }
940
-
941
- return NULL ;
942
- }
943
-
944
- static int get_using_call_count (struct bt_hfp_hf * hf )
945
- {
946
- struct bt_hfp_hf_call * call ;
947
- int count = 0 ;
948
-
949
- for (size_t index = 0 ; index < ARRAY_SIZE (hf -> calls ); index ++ ) {
950
- call = & hf -> calls [index ];
951
-
952
- if (!atomic_test_bit (call -> flags , BT_HFP_HF_CALL_IN_USING )) {
953
- continue ;
954
- }
955
-
956
- count ++ ;
957
- }
958
-
959
- return count ;
960
- }
961
-
962
1056
static void set_all_calls_held_state (struct bt_hfp_hf * hf , bool held )
963
1057
{
964
1058
struct bt_hfp_hf_call * call ;
@@ -992,6 +1086,10 @@ static void ag_indicator_handle_call(struct bt_hfp_hf *hf, uint32_t value)
992
1086
993
1087
LOG_DBG ("call %d" , value );
994
1088
1089
+ if (value != 0 ) {
1090
+ atomic_set_bit (hf -> flags , BT_HFP_HF_FLAG_CLCC_PENDING );
1091
+ }
1092
+
995
1093
if (value ) {
996
1094
call = get_dialing_call (hf );
997
1095
if (!call ) {
@@ -1050,6 +1148,10 @@ static void ag_indicator_handle_call_setup(struct bt_hfp_hf *hf, uint32_t value)
1050
1148
1051
1149
LOG_DBG ("call setup %d" , value );
1052
1150
1151
+ if (value != BT_HFP_CALL_SETUP_NONE ) {
1152
+ atomic_set_bit (hf -> flags , BT_HFP_HF_FLAG_CLCC_PENDING );
1153
+ }
1154
+
1053
1155
switch (value ) {
1054
1156
case BT_HFP_CALL_SETUP_NONE :
1055
1157
if (call_count == 1 ) {
@@ -1083,6 +1185,11 @@ static void ag_indicator_handle_call_setup(struct bt_hfp_hf *hf, uint32_t value)
1083
1185
case BT_HFP_CALL_SETUP_INCOMING :
1084
1186
call = get_call_with_state (hf , BT_HFP_HF_CALL_STATE_INCOMING );
1085
1187
if (!call ) {
1188
+ if (!atomic_test_bit (hf -> flags , BT_HFP_HF_FLAG_CONNECTED )) {
1189
+ LOG_INF ("SLC is not connected. Will get call status via AT+CLCC" );
1190
+ break ;
1191
+ }
1192
+
1086
1193
call = get_new_call (hf );
1087
1194
if (!call ) {
1088
1195
break ;
@@ -1103,6 +1210,11 @@ static void ag_indicator_handle_call_setup(struct bt_hfp_hf *hf, uint32_t value)
1103
1210
case BT_HFP_CALL_SETUP_OUTGOING :
1104
1211
call = get_call_with_state (hf , BT_HFP_HF_CALL_STATE_OUTGOING );
1105
1212
if (!call ) {
1213
+ if (!atomic_test_bit (hf -> flags , BT_HFP_HF_FLAG_CONNECTED )) {
1214
+ LOG_INF ("SLC is not connected. Will get call status via AT+CLCC" );
1215
+ break ;
1216
+ }
1217
+
1106
1218
call = get_new_call (hf );
1107
1219
if (!call ) {
1108
1220
break ;
@@ -1141,6 +1253,10 @@ static void ag_indicator_handle_call_held(struct bt_hfp_hf *hf, uint32_t value)
1141
1253
1142
1254
LOG_DBG ("call setup %d" , value );
1143
1255
1256
+ if (value != BT_HFP_CALL_HELD_NONE ) {
1257
+ atomic_set_bit (hf -> flags , BT_HFP_HF_FLAG_CLCC_PENDING );
1258
+ }
1259
+
1144
1260
switch (value ) {
1145
1261
case BT_HFP_CALL_HELD_NONE :
1146
1262
set_all_calls_held_state (hf , false);
@@ -1955,6 +2071,12 @@ static int at_cmd_init_start(struct bt_hfp_hf *hf)
1955
2071
LOG_WRN ("Send next AT command" );
1956
2072
hf -> cmd_init_seq ++ ;
1957
2073
}
2074
+
2075
+ if ((ARRAY_SIZE (cmd_init_list ) <= hf -> cmd_init_seq ) &&
2076
+ atomic_test_and_clear_bit (hf -> flags , BT_HFP_HF_FLAG_CLCC_PENDING )) {
2077
+ k_work_reschedule (& hf -> deferred_work , K_MSEC (HF_ENHANCED_CALL_STATUS_TIMEOUT ));
2078
+ }
2079
+
1958
2080
return err ;
1959
2081
}
1960
2082
0 commit comments