mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	bluez5: hfp-hf: Remove disconnected calls from call list
After AT+CLCC command completion, the calls which has not been listed should be removed. This list the calls returned by AT+CLCC to be able to find the ones which has not been listed but still in the call_list.
This commit is contained in:
		
							parent
							
								
									931b6d9ad8
								
							
						
					
					
						commit
						2cb678edb3
					
				
					 1 changed files with 71 additions and 13 deletions
				
			
		| 
						 | 
					@ -145,7 +145,8 @@ enum hfp_hf_state {
 | 
				
			||||||
	hfp_hf_nrec,
 | 
						hfp_hf_nrec,
 | 
				
			||||||
	hfp_hf_clcc,
 | 
						hfp_hf_clcc,
 | 
				
			||||||
	hfp_hf_vgs,
 | 
						hfp_hf_vgs,
 | 
				
			||||||
	hfp_hf_vgm
 | 
						hfp_hf_done,
 | 
				
			||||||
 | 
						hfp_hf_clcc_update
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum hsp_hs_state {
 | 
					enum hsp_hs_state {
 | 
				
			||||||
| 
						 | 
					@ -175,6 +176,11 @@ struct codec_item {
 | 
				
			||||||
	const struct media_codec *codec;
 | 
						const struct media_codec *codec;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct updated_call {
 | 
				
			||||||
 | 
						struct spa_list link;
 | 
				
			||||||
 | 
						int id;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rfcomm {
 | 
					struct rfcomm {
 | 
				
			||||||
	struct spa_list link;
 | 
						struct spa_list link;
 | 
				
			||||||
	struct spa_source source;
 | 
						struct spa_source source;
 | 
				
			||||||
| 
						 | 
					@ -215,6 +221,7 @@ struct rfcomm {
 | 
				
			||||||
	char *hf_indicators[MAX_HF_INDICATORS];
 | 
						char *hf_indicators[MAX_HF_INDICATORS];
 | 
				
			||||||
	struct spa_bt_telephony_ag *telephony_ag;
 | 
						struct spa_bt_telephony_ag *telephony_ag;
 | 
				
			||||||
	struct spa_list hfp_hf_commands;
 | 
						struct spa_list hfp_hf_commands;
 | 
				
			||||||
 | 
						struct spa_list updated_call_list;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -392,6 +399,13 @@ static void volume_sync_stop_timer(struct rfcomm *rfcomm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void rfcomm_free(struct rfcomm *rfcomm)
 | 
					static void rfcomm_free(struct rfcomm *rfcomm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct updated_call *updated_call;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_list_consume(updated_call, &rfcomm->updated_call_list, link) {
 | 
				
			||||||
 | 
							spa_list_remove(&updated_call->link);
 | 
				
			||||||
 | 
							free(updated_call);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec_switch_stop_timer(rfcomm);
 | 
						codec_switch_stop_timer(rfcomm);
 | 
				
			||||||
	if (rfcomm->telephony_ag) {
 | 
						if (rfcomm->telephony_ag) {
 | 
				
			||||||
		telephony_ag_destroy(rfcomm->telephony_ag);
 | 
							telephony_ag_destroy(rfcomm->telephony_ag);
 | 
				
			||||||
| 
						 | 
					@ -457,6 +471,9 @@ static ssize_t rfcomm_send_cmd(struct rfcomm *rfcomm, const char *format, ...)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rfcomm->hf_state == hfp_hf_done && spa_streq(message, "AT+CLCC"))
 | 
				
			||||||
 | 
							rfcomm->hf_state = hfp_hf_clcc_update;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_debug(backend->log, "RFCOMM >> %s", message);
 | 
						spa_log_debug(backend->log, "RFCOMM >> %s", message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -2064,6 +2081,34 @@ static const struct spa_bt_telephony_ag_callbacks telephony_ag_callbacks = {
 | 
				
			||||||
	.set_microphone_volume = hfp_hf_set_microphone_volume,
 | 
						.set_microphone_volume = hfp_hf_set_microphone_volume,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void hfp_hf_remove_disconnected_calls(struct rfcomm *rfcomm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct spa_bt_telephony_call *call, *call_tmp;
 | 
				
			||||||
 | 
						struct updated_call *updated_call;
 | 
				
			||||||
 | 
						bool found;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_list_for_each_safe(call, call_tmp, &rfcomm->telephony_ag->call_list, link) {
 | 
				
			||||||
 | 
							found = false;
 | 
				
			||||||
 | 
							spa_list_for_each(updated_call, &rfcomm->updated_call_list, link) {
 | 
				
			||||||
 | 
								if (call->id == updated_call->id) {
 | 
				
			||||||
 | 
									found = true;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!found) {
 | 
				
			||||||
 | 
								call->state = CALL_STATE_DISCONNECTED;
 | 
				
			||||||
 | 
								telephony_call_notify_updated_props(call);
 | 
				
			||||||
 | 
								telephony_call_destroy(call);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_list_consume(updated_call, &rfcomm->updated_call_list, link) {
 | 
				
			||||||
 | 
							spa_list_remove(&updated_call->link);
 | 
				
			||||||
 | 
							free(updated_call);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
 | 
					static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
| 
						 | 
					@ -2389,6 +2434,11 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (SPA_LIKELY (parsed)) {
 | 
							if (SPA_LIKELY (parsed)) {
 | 
				
			||||||
 | 
								struct updated_call *updated_call;
 | 
				
			||||||
 | 
								updated_call = calloc(1, sizeof(struct updated_call));
 | 
				
			||||||
 | 
								updated_call->id = idx;
 | 
				
			||||||
 | 
								spa_list_append(&rfcomm->updated_call_list, &updated_call->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			spa_list_for_each(call, &rfcomm->telephony_ag->call_list, link) {
 | 
								spa_list_for_each(call, &rfcomm->telephony_ag->call_list, link) {
 | 
				
			||||||
				if (call->id == idx) {
 | 
									if (call->id == idx) {
 | 
				
			||||||
					bool changed = false;
 | 
										bool changed = false;
 | 
				
			||||||
| 
						 | 
					@ -2430,17 +2480,6 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
 | 
				
			||||||
		rfcomm->hfp_hf_in_progress = false;
 | 
							rfcomm->hfp_hf_in_progress = false;
 | 
				
			||||||
	} else if (spa_strstartswith(token, "OK") || spa_strstartswith(token, "ERROR") ||
 | 
						} else if (spa_strstartswith(token, "OK") || spa_strstartswith(token, "ERROR") ||
 | 
				
			||||||
				spa_strstartswith(token, "+CME ERROR:")) {
 | 
									spa_strstartswith(token, "+CME ERROR:")) {
 | 
				
			||||||
		rfcomm->hfp_hf_cmd_in_progress = false;
 | 
					 | 
				
			||||||
		if (!spa_list_is_empty(&rfcomm->hfp_hf_commands)) {
 | 
					 | 
				
			||||||
			struct rfcomm_cmd *cmd;
 | 
					 | 
				
			||||||
			cmd = spa_list_first(&rfcomm->hfp_hf_commands, struct rfcomm_cmd, link);
 | 
					 | 
				
			||||||
			spa_list_remove(&cmd->link);
 | 
					 | 
				
			||||||
			spa_log_debug(backend->log, "Sending postponed command: %s", cmd->cmd);
 | 
					 | 
				
			||||||
			rfcomm_send_cmd(rfcomm, "%s", cmd->cmd);
 | 
					 | 
				
			||||||
			free(cmd->cmd);
 | 
					 | 
				
			||||||
			free(cmd);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (spa_strstartswith(token, "OK")) {
 | 
							if (spa_strstartswith(token, "OK")) {
 | 
				
			||||||
			switch(rfcomm->hf_state) {
 | 
								switch(rfcomm->hf_state) {
 | 
				
			||||||
			case hfp_hf_brsf:
 | 
								case hfp_hf_brsf:
 | 
				
			||||||
| 
						 | 
					@ -2539,17 +2578,35 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
 | 
				
			||||||
				/* Report volume on SLC establishment */
 | 
									/* Report volume on SLC establishment */
 | 
				
			||||||
				SPA_FALLTHROUGH;
 | 
									SPA_FALLTHROUGH;
 | 
				
			||||||
			case hfp_hf_clcc:
 | 
								case hfp_hf_clcc:
 | 
				
			||||||
 | 
									if (rfcomm->hf_state == hfp_hf_clcc) {
 | 
				
			||||||
 | 
										hfp_hf_remove_disconnected_calls(rfcomm);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				rfcomm_send_volume_cmd(rfcomm, SPA_BT_VOLUME_ID_RX);
 | 
									rfcomm_send_volume_cmd(rfcomm, SPA_BT_VOLUME_ID_RX);
 | 
				
			||||||
				rfcomm->hf_state = hfp_hf_vgs;
 | 
									rfcomm->hf_state = hfp_hf_vgs;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case hfp_hf_vgs:
 | 
								case hfp_hf_vgs:
 | 
				
			||||||
				rfcomm_send_volume_cmd(rfcomm, SPA_BT_VOLUME_ID_TX);
 | 
									rfcomm_send_volume_cmd(rfcomm, SPA_BT_VOLUME_ID_TX);
 | 
				
			||||||
				rfcomm->hf_state = hfp_hf_vgm;
 | 
									rfcomm->hf_state = hfp_hf_done;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case hfp_hf_clcc_update:
 | 
				
			||||||
 | 
									hfp_hf_remove_disconnected_calls(rfcomm);
 | 
				
			||||||
 | 
									rfcomm->hf_state = hfp_hf_done;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rfcomm->hfp_hf_cmd_in_progress = false;
 | 
				
			||||||
 | 
							if (!spa_list_is_empty(&rfcomm->hfp_hf_commands)) {
 | 
				
			||||||
 | 
								struct rfcomm_cmd *cmd;
 | 
				
			||||||
 | 
								cmd = spa_list_first(&rfcomm->hfp_hf_commands, struct rfcomm_cmd, link);
 | 
				
			||||||
 | 
								spa_list_remove(&cmd->link);
 | 
				
			||||||
 | 
								spa_log_debug(backend->log, "Sending postponed command: %s", cmd->cmd);
 | 
				
			||||||
 | 
								rfcomm_send_cmd(rfcomm, "%s", cmd->cmd);
 | 
				
			||||||
 | 
								free(cmd->cmd);
 | 
				
			||||||
 | 
								free(cmd);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
| 
						 | 
					@ -3492,6 +3549,7 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
 | 
				
			||||||
	rfcomm->source.mask = SPA_IO_IN;
 | 
						rfcomm->source.mask = SPA_IO_IN;
 | 
				
			||||||
	rfcomm->source.rmask = 0;
 | 
						rfcomm->source.rmask = 0;
 | 
				
			||||||
	spa_list_init(&rfcomm->hfp_hf_commands);
 | 
						spa_list_init(&rfcomm->hfp_hf_commands);
 | 
				
			||||||
 | 
						spa_list_init(&rfcomm->updated_call_list);
 | 
				
			||||||
	/* By default all indicators are enabled */
 | 
						/* By default all indicators are enabled */
 | 
				
			||||||
	rfcomm->cind_enabled_indicators = 0xFFFFFFFF;
 | 
						rfcomm->cind_enabled_indicators = 0xFFFFFFFF;
 | 
				
			||||||
	memset(rfcomm->hf_indicators, 0, sizeof rfcomm->hf_indicators);
 | 
						memset(rfcomm->hf_indicators, 0, sizeof rfcomm->hf_indicators);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue