mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: telephony: implement asynchronous D-Bus calls
This removes the need to call poll() on the rfcomm socket in order to wait for replies from the AG. Use a queue to buffer all the commands that are to be sent to the AG and match them to replies when they are received. Optionally associate each command with a DBusMessage that is assumed to be a method call from the telephony interface, which is then replied to when the rfcomm command reply is received. Also associate each command with a state, so that it is always deterministic what gets executed after the reply is received. On the telephony module, pass on the DBusMessage on the callbacks and add a method to allow the receiver to send a reply. Only send FAILED directly when the callback is not handled. Also, remove the return value from the Dial() command (it was not advertised on the introspection anyway) to make things easier.
This commit is contained in:
parent
0b647a9009
commit
e4b0f68e0b
4 changed files with 369 additions and 628 deletions
|
|
@ -102,10 +102,10 @@ NOTE: This method is implemented only on the `org.ofono.VoiceCallManager`
|
||||||
interface, for compatibility. Call announcements are normally made available via
|
interface, for compatibility. Call announcements are normally made available via
|
||||||
the standard `org.freedesktop.DBus.ObjectManager` interface.
|
the standard `org.freedesktop.DBus.ObjectManager` interface.
|
||||||
|
|
||||||
`object Dial(string number)`
|
`void Dial(string number)`
|
||||||
|
|
||||||
Initiates a new outgoing call. Returns the object path to the newly created
|
Initiates a new outgoing call. If this succeeds, the new call is announced via
|
||||||
call.
|
the signals.
|
||||||
|
|
||||||
The number must be a string containing the following characters:
|
The number must be a string containing the following characters:
|
||||||
`[0-9+*#,ABCD]{1,80}` In other words, it must be a non-empty string consisting
|
`[0-9+*#,ABCD]{1,80}` In other words, it must be a non-empty string consisting
|
||||||
|
|
@ -176,12 +176,12 @@ Possible Errors:
|
||||||
* org.pipewire.Telephony.Error.InvalidState
|
* org.pipewire.Telephony.Error.InvalidState
|
||||||
* org.freedesktop.DBus.Error.Failed
|
* org.freedesktop.DBus.Error.Failed
|
||||||
|
|
||||||
`array{object} CreateMultiparty()`
|
`void CreateMultiparty()`
|
||||||
|
|
||||||
Joins active and held calls together into a multi-party call. If one of the
|
Joins active and held calls together into a multi-party call. If one of the
|
||||||
calls is already a multi-party call, then the other call is added to the
|
calls is already a multi-party call, then the other call is added to the
|
||||||
multiparty conversation. Returns the new list of calls participating in the
|
multiparty conversation. Changes to the call objects are announced via the
|
||||||
multiparty call.
|
signals.
|
||||||
|
|
||||||
There can only be one subscriber controlled multi-party call according to the
|
There can only be one subscriber controlled multi-party call according to the
|
||||||
GSM specification.
|
GSM specification.
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -203,9 +203,6 @@ struct agimpl {
|
||||||
struct spa_callbacks callbacks;
|
struct spa_callbacks callbacks;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
|
|
||||||
bool dial_in_progress;
|
|
||||||
struct callimpl *dial_return;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int volume[SPA_BT_VOLUME_ID_TERM];
|
int volume[SPA_BT_VOLUME_ID_TERM];
|
||||||
struct spa_bt_telephony_ag_transport transport;
|
struct spa_bt_telephony_ag_transport transport;
|
||||||
|
|
@ -228,22 +225,22 @@ struct callimpl {
|
||||||
} prev;
|
} prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ag_emit(ag,m,v,...) spa_callbacks_call(&ag->callbacks, struct spa_bt_telephony_ag_callbacks, m, v, ##__VA_ARGS__)
|
#define ag_emit(ag,m,v,...) spa_callbacks_call(&ag->callbacks, struct spa_bt_telephony_ag_callbacks, m, v, ##__VA_ARGS__)
|
||||||
#define ag_emit_dial(s,n,e,cme) ag_emit(s,dial,0,n,e,cme)
|
#define ag_emit_dial(s,n,m) ag_emit(s,dial,0,n,m)
|
||||||
#define ag_emit_swap_calls(s,e,cme) ag_emit(s,swap_calls,0,e,cme)
|
#define ag_emit_swap_calls(s,m) ag_emit(s,swap_calls,0,m)
|
||||||
#define ag_emit_release_and_answer(s,e,cme) ag_emit(s,release_and_answer,0,e,cme)
|
#define ag_emit_release_and_answer(s,m) ag_emit(s,release_and_answer,0,m)
|
||||||
#define ag_emit_release_and_swap(s,e,cme) ag_emit(s,release_and_swap,0,e,cme)
|
#define ag_emit_release_and_swap(s,m) ag_emit(s,release_and_swap,0,m)
|
||||||
#define ag_emit_hold_and_answer(s,e,cme) ag_emit(s,hold_and_answer,0,e,cme)
|
#define ag_emit_hold_and_answer(s,m) ag_emit(s,hold_and_answer,0,m)
|
||||||
#define ag_emit_hangup_all(s,e,cme) ag_emit(s,hangup_all,0,e,cme)
|
#define ag_emit_hangup_all(s,m) ag_emit(s,hangup_all,0,m)
|
||||||
#define ag_emit_create_multiparty(s,e,cme) ag_emit(s,create_multiparty,0,e,cme)
|
#define ag_emit_create_multiparty(s,m) ag_emit(s,create_multiparty,0,m)
|
||||||
#define ag_emit_send_tones(s,t,e,cme) ag_emit(s,send_tones,0,t,e,cme)
|
#define ag_emit_send_tones(s,t,m) ag_emit(s,send_tones,0,t,m)
|
||||||
#define ag_emit_transport_activate(s,e,cme) ag_emit(s,transport_activate,0,e,cme)
|
#define ag_emit_transport_activate(s,m) ag_emit(s,transport_activate,0,m)
|
||||||
#define ag_emit_set_speaker_volume(s,v,e,cme) ag_emit(s,set_speaker_volume,0,v,e,cme)
|
#define ag_emit_set_speaker_volume(s,v,m) ag_emit(s,set_speaker_volume,0,v,m)
|
||||||
#define ag_emit_set_microphone_volume(s,v,e,cme) ag_emit(s,set_microphone_volume,0,v,e,cme)
|
#define ag_emit_set_microphone_volume(s,v,m) ag_emit(s,set_microphone_volume,0,v,m)
|
||||||
|
|
||||||
#define call_emit(c,m,v,...) spa_callbacks_call(&c->callbacks, struct spa_bt_telephony_call_callbacks, m, v, ##__VA_ARGS__)
|
#define call_emit(c,m,v,...) spa_callbacks_call(&c->callbacks, struct spa_bt_telephony_call_callbacks, m, v, ##__VA_ARGS__)
|
||||||
#define call_emit_answer(s,e,cme) call_emit(s,answer,0,e,cme)
|
#define call_emit_answer(s,m) call_emit(s,answer,0,m)
|
||||||
#define call_emit_hangup(s,e,cme) call_emit(s,hangup,0,e,cme)
|
#define call_emit_hangup(s,m) call_emit(s,hangup,0,m)
|
||||||
|
|
||||||
static void dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *ag);
|
static void dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *ag);
|
||||||
static void dbus_iter_append_call_properties(DBusMessageIter *i, struct spa_bt_telephony_call *call, bool all);
|
static void dbus_iter_append_call_properties(DBusMessageIter *i, struct spa_bt_telephony_call *call, bool all);
|
||||||
|
|
@ -521,6 +518,21 @@ void telephony_free(struct spa_bt_telephony *telephony)
|
||||||
free(impl);
|
free(impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void telephony_send_dbus_method_reply(struct spa_bt_telephony *telephony, DBusMessage *m,
|
||||||
|
enum spa_bt_telephony_error err, uint8_t cme_error)
|
||||||
|
{
|
||||||
|
struct impl *impl = SPA_CONTAINER_OF(telephony, struct impl, this);
|
||||||
|
spa_autoptr(DBusMessage) reply = NULL;
|
||||||
|
|
||||||
|
if (err == BT_TELEPHONY_ERROR_NONE)
|
||||||
|
reply = dbus_message_new_method_return(m);
|
||||||
|
else
|
||||||
|
reply = dbus_message_new_error(m, telephony_error_to_dbus (err),
|
||||||
|
telephony_error_to_description (err, cme_error));
|
||||||
|
|
||||||
|
dbus_connection_send(impl->conn, reply, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void telephony_ag_commit_properties(struct spa_bt_telephony_ag *ag)
|
static void telephony_ag_commit_properties(struct spa_bt_telephony_ag *ag)
|
||||||
{
|
{
|
||||||
struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
|
struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
|
||||||
|
|
@ -859,9 +871,6 @@ static DBusMessage *ag_properties_set(struct agimpl *agimpl, DBusMessage *m)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (spa_streq(iface, PW_TELEPHONY_AG_IFACE)) {
|
if (spa_streq(iface, PW_TELEPHONY_AG_IFACE)) {
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
|
||||||
uint8_t cme_error;
|
|
||||||
|
|
||||||
if (spa_streq(name, "SpeakerVolume")) {
|
if (spa_streq(name, "SpeakerVolume")) {
|
||||||
dbus_message_iter_init(m, &i);
|
dbus_message_iter_init(m, &i);
|
||||||
dbus_message_iter_next(&i); /* skip iface */
|
dbus_message_iter_next(&i); /* skip iface */
|
||||||
|
|
@ -869,12 +878,10 @@ static DBusMessage *ag_properties_set(struct agimpl *agimpl, DBusMessage *m)
|
||||||
dbus_message_iter_recurse(&i, &variant); /* value */
|
dbus_message_iter_recurse(&i, &variant); /* value */
|
||||||
dbus_message_iter_get_basic(&variant, &agimpl->this.volume[SPA_BT_VOLUME_ID_RX]);
|
dbus_message_iter_get_basic(&variant, &agimpl->this.volume[SPA_BT_VOLUME_ID_RX]);
|
||||||
|
|
||||||
if (ag_emit_set_speaker_volume(agimpl, agimpl->this.volume[SPA_BT_VOLUME_ID_RX], &err, &cme_error) &&
|
return ag_emit_set_speaker_volume(agimpl, agimpl->this.volume[SPA_BT_VOLUME_ID_RX], m) ? NULL :
|
||||||
err == BT_TELEPHONY_ERROR_NONE)
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
return dbus_message_new_method_return(m);
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
} else if (spa_streq(name, "MicrophoneVolume")) {
|
} else if (spa_streq(name, "MicrophoneVolume")) {
|
||||||
dbus_message_iter_init(m, &i);
|
dbus_message_iter_init(m, &i);
|
||||||
dbus_message_iter_next(&i); /* skip iface */
|
dbus_message_iter_next(&i); /* skip iface */
|
||||||
|
|
@ -882,12 +889,9 @@ static DBusMessage *ag_properties_set(struct agimpl *agimpl, DBusMessage *m)
|
||||||
dbus_message_iter_recurse(&i, &variant); /* value */
|
dbus_message_iter_recurse(&i, &variant); /* value */
|
||||||
dbus_message_iter_get_basic(&variant, &agimpl->this.volume[SPA_BT_VOLUME_ID_TX]);
|
dbus_message_iter_get_basic(&variant, &agimpl->this.volume[SPA_BT_VOLUME_ID_TX]);
|
||||||
|
|
||||||
if (ag_emit_set_microphone_volume(agimpl, agimpl->this.volume[SPA_BT_VOLUME_ID_TX], &err, &cme_error) &&
|
return ag_emit_set_microphone_volume(agimpl, agimpl->this.volume[SPA_BT_VOLUME_ID_TX], m) ? NULL :
|
||||||
err == BT_TELEPHONY_ERROR_NONE)
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
return dbus_message_new_method_return(m);
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
} else if (spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE)) {
|
} else if (spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE)) {
|
||||||
if (spa_streq(name, "RejectSCO")) {
|
if (spa_streq(name, "RejectSCO")) {
|
||||||
|
|
@ -939,8 +943,6 @@ static DBusMessage *ag_dial(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
const char *number = NULL;
|
const char *number = NULL;
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
||||||
uint8_t cme_error;
|
|
||||||
spa_autoptr(DBusMessage) r = NULL;
|
|
||||||
|
|
||||||
if (!dbus_message_get_args(m, NULL,
|
if (!dbus_message_get_args(m, NULL,
|
||||||
DBUS_TYPE_STRING, &number,
|
DBUS_TYPE_STRING, &number,
|
||||||
|
|
@ -952,111 +954,60 @@ static DBusMessage *ag_dial(struct agimpl *agimpl, DBusMessage *m)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
agimpl->dial_in_progress = true;
|
if (ag_emit_dial(agimpl, number, m))
|
||||||
if (!ag_emit_dial(agimpl, number, &err, &cme_error)) {
|
|
||||||
agimpl->dial_in_progress = false;
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
agimpl->dial_in_progress = false;
|
|
||||||
|
|
||||||
if (!agimpl->dial_return || !agimpl->dial_return->path)
|
|
||||||
err = BT_TELEPHONY_ERROR_FAILED;
|
|
||||||
|
|
||||||
if (err != BT_TELEPHONY_ERROR_NONE)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
if ((r = dbus_message_new_method_return(m)) == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!dbus_message_append_args(r, DBUS_TYPE_OBJECT_PATH,
|
|
||||||
&agimpl->dial_return->path, DBUS_TYPE_INVALID))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
agimpl->dial_return = NULL;
|
|
||||||
|
|
||||||
return spa_steal_ptr(r);
|
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
||||||
telephony_error_to_description (err, cme_error));
|
telephony_error_to_description (err, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_swap_calls(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_swap_calls(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_swap_calls(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_swap_calls(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_release_and_answer(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_release_and_answer(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_release_and_answer(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_release_and_answer(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_release_and_swap(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_release_and_swap(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_release_and_swap(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_release_and_swap(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_hold_and_answer(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_hold_and_answer(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_hold_and_answer(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_hold_and_answer(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_hangup_all(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_hangup_all(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_hangup_all(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_hangup_all(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_create_multiparty(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_create_multiparty(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_create_multiparty(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_create_multiparty(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_send_tones(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_send_tones(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
const char *tones = NULL;
|
const char *tones = NULL;
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
||||||
uint8_t cme_error;
|
|
||||||
|
|
||||||
if (!dbus_message_get_args(m, NULL,
|
if (!dbus_message_get_args(m, NULL,
|
||||||
DBUS_TYPE_STRING, &tones,
|
DBUS_TYPE_STRING, &tones,
|
||||||
|
|
@ -1068,24 +1019,19 @@ static DBusMessage *ag_send_tones(struct agimpl *agimpl, DBusMessage *m)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ag_emit_send_tones(agimpl, tones, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
if (ag_emit_send_tones(agimpl, tones, m))
|
||||||
return dbus_message_new_method_return(m);
|
return NULL;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
||||||
telephony_error_to_description (err, cme_error));
|
telephony_error_to_description (err, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *ag_transport_activate(struct agimpl *agimpl, DBusMessage *m)
|
static DBusMessage *ag_transport_activate(struct agimpl *agimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return ag_emit_transport_activate(agimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (ag_emit_transport_activate(agimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusHandlerResult ag_handler(DBusConnection *c, DBusMessage *m, void *userdata)
|
static DBusHandlerResult ag_handler(DBusConnection *c, DBusMessage *m, void *userdata)
|
||||||
|
|
@ -1144,9 +1090,7 @@ static DBusHandlerResult ag_handler(DBusConnection *c, DBusMessage *m, void *use
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == NULL)
|
if (r && !dbus_connection_send(impl->conn, r, NULL))
|
||||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
|
||||||
if (!dbus_connection_send(impl->conn, r, NULL))
|
|
||||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
@ -1386,7 +1330,6 @@ void telephony_ag_set_callbacks(struct spa_bt_telephony_ag *ag,
|
||||||
struct spa_bt_telephony_call *
|
struct spa_bt_telephony_call *
|
||||||
telephony_call_new(struct spa_bt_telephony_ag *ag, size_t user_data_size)
|
telephony_call_new(struct spa_bt_telephony_ag *ag, size_t user_data_size)
|
||||||
{
|
{
|
||||||
struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
|
|
||||||
struct callimpl *callimpl;
|
struct callimpl *callimpl;
|
||||||
|
|
||||||
spa_assert(user_data_size < SIZE_MAX - sizeof(*callimpl));
|
spa_assert(user_data_size < SIZE_MAX - sizeof(*callimpl));
|
||||||
|
|
@ -1403,10 +1346,6 @@ telephony_call_new(struct spa_bt_telephony_ag *ag, size_t user_data_size)
|
||||||
if (user_data_size > 0)
|
if (user_data_size > 0)
|
||||||
callimpl->user_data = SPA_PTROFF(callimpl, sizeof(struct callimpl), void);
|
callimpl->user_data = SPA_PTROFF(callimpl, sizeof(struct callimpl), void);
|
||||||
|
|
||||||
/* mark this object as the return value of the Dial method */
|
|
||||||
if (agimpl->dial_in_progress)
|
|
||||||
agimpl->dial_return = callimpl;
|
|
||||||
|
|
||||||
return &callimpl->this;
|
return &callimpl->this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1650,26 +1589,16 @@ static DBusMessage *call_properties_set(struct callimpl *callimpl, DBusMessage *
|
||||||
|
|
||||||
static DBusMessage *call_answer(struct callimpl *callimpl, DBusMessage *m)
|
static DBusMessage *call_answer(struct callimpl *callimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return call_emit_answer(callimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (call_emit_answer(callimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusMessage *call_hangup(struct callimpl *callimpl, DBusMessage *m)
|
static DBusMessage *call_hangup(struct callimpl *callimpl, DBusMessage *m)
|
||||||
{
|
{
|
||||||
enum spa_bt_telephony_error err = BT_TELEPHONY_ERROR_FAILED;
|
return call_emit_hangup(callimpl, m) ? NULL :
|
||||||
uint8_t cme_error;
|
dbus_message_new_error(m, telephony_error_to_dbus (BT_TELEPHONY_ERROR_FAILED),
|
||||||
|
telephony_error_to_description (BT_TELEPHONY_ERROR_FAILED, 0));
|
||||||
if (call_emit_hangup(callimpl, &err, &cme_error) && err == BT_TELEPHONY_ERROR_NONE)
|
|
||||||
return dbus_message_new_method_return(m);
|
|
||||||
|
|
||||||
return dbus_message_new_error(m, telephony_error_to_dbus (err),
|
|
||||||
telephony_error_to_description (err, cme_error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusHandlerResult call_handler(DBusConnection *c, DBusMessage *m, void *userdata)
|
static DBusHandlerResult call_handler(DBusConnection *c, DBusMessage *m, void *userdata)
|
||||||
|
|
@ -1707,9 +1636,7 @@ static DBusHandlerResult call_handler(DBusConnection *c, DBusMessage *m, void *u
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == NULL)
|
if (r && !dbus_connection_send(impl->conn, r, NULL))
|
||||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
|
||||||
if (!dbus_connection_send(impl->conn, r, NULL))
|
|
||||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,33 +67,38 @@ struct spa_bt_telephony_ag_callbacks {
|
||||||
#define SPA_VERSION_BT_TELEPHONY_AG_CALLBACKS 0
|
#define SPA_VERSION_BT_TELEPHONY_AG_CALLBACKS 0
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
void (*dial)(void *data, const char *number, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*dial)(void *data, const char *number, DBusMessage *m);
|
||||||
void (*swap_calls)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*swap_calls)(void *data, DBusMessage *m);
|
||||||
void (*release_and_answer)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*release_and_answer)(void *data, DBusMessage *m);
|
||||||
void (*release_and_swap)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*release_and_swap)(void *data, DBusMessage *m);
|
||||||
void (*hold_and_answer)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*hold_and_answer)(void *data, DBusMessage *m);
|
||||||
void (*hangup_all)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*hangup_all)(void *data, DBusMessage *m);
|
||||||
void (*create_multiparty)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*create_multiparty)(void *data, DBusMessage *m);
|
||||||
void (*send_tones)(void *data, const char *tones, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*send_tones)(void *data, const char *tones, DBusMessage *m);
|
||||||
|
|
||||||
void (*transport_activate)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*transport_activate)(void *data, DBusMessage *m);
|
||||||
|
|
||||||
void (*set_speaker_volume)(void *data, uint8_t volume, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*set_speaker_volume)(void *data, uint8_t volume, DBusMessage *m);
|
||||||
void (*set_microphone_volume)(void *data, uint8_t volume, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*set_microphone_volume)(void *data, uint8_t volume, DBusMessage *m);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spa_bt_telephony_call_callbacks {
|
struct spa_bt_telephony_call_callbacks {
|
||||||
#define SPA_VERSION_BT_TELEPHONY_CALL_CALLBACKS 0
|
#define SPA_VERSION_BT_TELEPHONY_CALL_CALLBACKS 0
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
void (*answer)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*answer)(void *data, DBusMessage *m);
|
||||||
void (*hangup)(void *data, enum spa_bt_telephony_error *err, uint8_t *cme_error);
|
void (*hangup)(void *data, DBusMessage *m);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spa_bt_telephony *telephony_new(struct spa_log *log, struct spa_dbus *dbus,
|
struct spa_bt_telephony *telephony_new(struct spa_log *log, struct spa_dbus *dbus,
|
||||||
const struct spa_dict *info);
|
const struct spa_dict *info);
|
||||||
void telephony_free(struct spa_bt_telephony *telephony);
|
void telephony_free(struct spa_bt_telephony *telephony);
|
||||||
|
|
||||||
|
/* send a reply to any of the methods (they all return void);
|
||||||
|
this is must be called from the callbacks either in sync or async */
|
||||||
|
void telephony_send_dbus_method_reply(struct spa_bt_telephony *telephony,
|
||||||
|
DBusMessage *m, enum spa_bt_telephony_error err, uint8_t cme_error);
|
||||||
|
|
||||||
|
|
||||||
/* create/destroy the ag object */
|
/* create/destroy the ag object */
|
||||||
struct spa_bt_telephony_ag * telephony_ag_new(struct spa_bt_telephony *telephony,
|
struct spa_bt_telephony_ag * telephony_ag_new(struct spa_bt_telephony *telephony,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue