* [PATCH 6/9] Add __btd_error_not_available()
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289197787-16715-6-git-send-email-padovan@profusion.mobi>
---
audio/headset.c | 9 +++------
plugins/service.c | 16 +++-------------
src/error.c | 7 +++++++
src/error.h | 1 +
4 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index fd358a0..017f02e 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1796,8 +1796,7 @@ static DBusMessage *hs_play(DBusConnection *conn, DBusMessage *msg,
if (sco_hci) {
error("Refusing Headset.Play() because SCO HCI routing "
"is enabled");
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Operation not Available");
+ return __btd_error_not_available(msg);
}
switch (hs->state) {
@@ -1842,8 +1841,7 @@ static DBusMessage *hs_get_speaker_gain(DBusConnection *conn,
dbus_uint16_t gain;
if (hs->state < HEADSET_STATE_CONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Operation not Available");
+ return __btd_error_not_available(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1868,8 +1866,7 @@ static DBusMessage *hs_get_mic_gain(DBusConnection *conn,
dbus_uint16_t gain;
if (hs->state < HEADSET_STATE_CONNECTED || slc == NULL)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Operation not Available");
+ return __btd_error_not_available(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
diff --git a/plugins/service.c b/plugins/service.c
index 6f6a275..f4b71ae 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -339,12 +339,6 @@ static void exit_callback(DBusConnection *conn, void *user_data)
g_free(user_record);
}
-static inline DBusMessage *not_available(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
- "Not Available");
-}
-
static inline DBusMessage *failed(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "Failed");
@@ -419,9 +413,7 @@ static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
if (remove_record_from_server(handle) < 0) {
sdp_record_free(sdp_record);
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotAvailable",
- "Not Available");
+ return __btd_error_not_available(msg);
}
if (serv_adapter->adapter)
@@ -465,9 +457,7 @@ static DBusMessage *update_xml_record(DBusConnection *conn,
user_record = find_record(serv_adapter, handle,
dbus_message_get_sender(msg));
if (!user_record)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotAvailable",
- "Not Available");
+ return __btd_error_not_available(msg);
sdp_record = sdp_xml_parse_record(record, len);
if (!sdp_record) {
@@ -552,7 +542,7 @@ static DBusMessage *remove_service_record(DBusConnection *conn,
sender = dbus_message_get_sender(msg);
if (remove_record(conn, sender, serv_adapter, handle) < 0)
- return not_available(msg);
+ return __btd_error_not_available(msg);
return dbus_message_new_method_return(msg);
}
diff --git a/src/error.c b/src/error.c
index 11bc520..8b91a03 100644
--- a/src/error.c
+++ b/src/error.c
@@ -83,3 +83,10 @@ DBusMessage *__btd_error_in_progress(DBusMessage *msg)
".InProgress",
"In Progress");
}
+
+DBusMessage *__btd_error_not_available(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".NotAvailable",
+ "Operation currently not available");
+}
diff --git a/src/error.h b/src/error.h
index e241b92..dfdc933 100644
--- a/src/error.h
+++ b/src/error.h
@@ -34,4 +34,5 @@ DBusMessage *__btd_error_invalid_args(DBusMessage *msg);
DBusMessage *__btd_error_already_exists(DBusMessage *msg);
DBusMessage *__btd_error_not_supported(DBusMessage *msg);
DBusMessage *__btd_error_not_connected(DBusMessage *msg);
+DBusMessage *__btd_error_not_available(DBusMessage *msg);
DBusMessage *__btd_error_in_progress(DBusMessage *msg);
--
1.7.3.1
^ permalink raw reply related
* [PATCH 5/9] Add __btd_error_in_progress()
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289197787-16715-5-git-send-email-padovan@profusion.mobi>
---
audio/device.c | 3 +--
audio/headset.c | 3 +--
input/device.c | 2 +-
src/device.c | 11 ++---------
src/error.c | 7 +++++++
src/error.h | 1 +
6 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/audio/device.c b/audio/device.c
index 97badac..95fa51a 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -519,8 +519,7 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
struct dev_priv *priv = dev->priv;
if (priv->state == AUDIO_STATE_CONNECTING)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
- "Connect in Progress");
+ return __btd_error_in_progress(msg);
else if (priv->state == AUDIO_STATE_CONNECTED)
return g_dbus_create_error(msg, ERROR_INTERFACE
".AlreadyConnected",
diff --git a/audio/headset.c b/audio/headset.c
index 1ec48a4..fd358a0 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1699,8 +1699,7 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
int err;
if (hs->state == HEADSET_STATE_CONNECTING)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
- "Connect in Progress");
+ return __btd_error_in_progress(msg);
else if (hs->state > HEADSET_STATE_CONNECTING)
return g_dbus_create_error(msg, ERROR_INTERFACE
".AlreadyConnected",
diff --git a/input/device.c b/input/device.c
index c85d89c..1ccb2b0 100644
--- a/input/device.c
+++ b/input/device.c
@@ -950,7 +950,7 @@ static DBusMessage *input_device_connect(DBusConnection *conn,
return not_supported(msg);
if (iconn->pending_connect)
- return in_progress(msg);
+ return __btd_error_in_progress(msg);
if (is_connected(iconn))
return already_connected(msg);
diff --git a/src/device.c b/src/device.c
index 3393634..f72a9b5 100644
--- a/src/device.c
+++ b/src/device.c
@@ -180,12 +180,6 @@ static inline DBusMessage *no_such_adapter(DBusMessage *msg)
"No such adapter");
}
-static inline DBusMessage *in_progress(DBusMessage *msg, const char *str)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
- "%s", str);
-}
-
static void browse_request_free(struct browse_req *req)
{
if (req->listener_id)
@@ -613,8 +607,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
int err;
if (device->browse)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
- "Discover in progress");
+ return __btd_error_in_progress(msg);
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
DBUS_TYPE_INVALID) == FALSE)
@@ -1933,7 +1926,7 @@ DBusMessage *device_create_bonding(struct btd_device *device,
ba2str(&device->bdaddr, dstaddr);
if (device->bonding)
- return in_progress(msg, "Bonding in progress");
+ return __btd_error_in_progress(msg);
/* check if a link key already exists */
create_name(filename, PATH_MAX, STORAGEDIR, srcaddr,
diff --git a/src/error.c b/src/error.c
index b2d0ced..11bc520 100644
--- a/src/error.c
+++ b/src/error.c
@@ -76,3 +76,10 @@ DBusMessage *__btd_error_not_connected(DBusMessage *msg)
".NotConnected",
"Not Connected");
}
+
+DBusMessage *__btd_error_in_progress(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".InProgress",
+ "In Progress");
+}
diff --git a/src/error.h b/src/error.h
index 06345da..e241b92 100644
--- a/src/error.h
+++ b/src/error.h
@@ -34,3 +34,4 @@ DBusMessage *__btd_error_invalid_args(DBusMessage *msg);
DBusMessage *__btd_error_already_exists(DBusMessage *msg);
DBusMessage *__btd_error_not_supported(DBusMessage *msg);
DBusMessage *__btd_error_not_connected(DBusMessage *msg);
+DBusMessage *__btd_error_in_progress(DBusMessage *msg);
--
1.7.3.1
^ permalink raw reply related
* [PATCH 4/9] Add __btd_error_not_connected()
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289197787-16715-4-git-send-email-padovan@profusion.mobi>
---
audio/control.c | 8 ++------
audio/device.c | 3 +--
audio/gateway.c | 4 +---
audio/headset.c | 24 ++++++------------------
audio/sink.c | 4 +---
audio/source.c | 4 +---
src/error.c | 7 +++++++
src/error.h | 1 +
8 files changed, 20 insertions(+), 35 deletions(-)
diff --git a/audio/control.c b/audio/control.c
index e9f59fc..043785e 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -1015,9 +1015,7 @@ static DBusMessage *volume_up(DBusConnection *conn, DBusMessage *msg,
return NULL;
if (control->state != AVCTP_STATE_CONNECTED)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
if (!control->target)
return __btd_error_not_supported(msg);
@@ -1043,9 +1041,7 @@ static DBusMessage *volume_down(DBusConnection *conn, DBusMessage *msg,
return NULL;
if (control->state != AVCTP_STATE_CONNECTED)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
if (!control->target)
return __btd_error_not_supported(msg);
diff --git a/audio/device.c b/audio/device.c
index eff8231..97badac 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -562,8 +562,7 @@ static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
struct dev_priv *priv = dev->priv;
if (priv->state == AUDIO_STATE_DISCONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotConnected",
- "Not connected");
+ return __btd_error_not_connected(msg);
if (priv->dc_req)
return dbus_message_new_method_return(msg);
diff --git a/audio/gateway.c b/audio/gateway.c
index ae0ee75..ce1ec53 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -426,9 +426,7 @@ static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg,
return NULL;
if (!gw->rfcomm)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
gateway_close(device);
ba2str(&device->dst, gw_addr);
diff --git a/audio/headset.c b/audio/headset.c
index 2cca5ca..1ec48a4 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1622,9 +1622,7 @@ static DBusMessage *hs_stop(DBusConnection *conn, DBusMessage *msg,
DBusMessage *reply = NULL;
if (hs->state < HEADSET_STATE_PLAY_IN_PROGRESS)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1663,9 +1661,7 @@ static DBusMessage *hs_disconnect(DBusConnection *conn, DBusMessage *msg,
char hs_address[18];
if (hs->state == HEADSET_STATE_DISCONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
headset_shutdown(device);
ba2str(&device->dst, hs_address);
@@ -1741,9 +1737,7 @@ static DBusMessage *hs_ring(DBusConnection *conn, DBusMessage *msg,
int err;
if (hs->state < HEADSET_STATE_CONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1778,9 +1772,7 @@ static DBusMessage *hs_cancel_call(DBusConnection *conn,
DBusMessage *reply = NULL;
if (hs->state < HEADSET_STATE_CONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1812,9 +1804,7 @@ static DBusMessage *hs_play(DBusConnection *conn, DBusMessage *msg,
switch (hs->state) {
case HEADSET_STATE_DISCONNECTED:
case HEADSET_STATE_CONNECTING:
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
case HEADSET_STATE_PLAY_IN_PROGRESS:
if (hs->pending && hs->pending->msg == NULL) {
hs->pending->msg = dbus_message_ref(msg);
@@ -1905,9 +1895,7 @@ static DBusMessage *hs_set_gain(DBusConnection *conn,
int err;
if (hs->state < HEADSET_STATE_CONNECTED)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
err = headset_set_gain(device, gain, type);
if (err < 0)
diff --git a/audio/sink.c b/audio/sink.c
index a9f6307..3c55c74 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -456,9 +456,7 @@ static DBusMessage *sink_disconnect(DBusConnection *conn,
int err;
if (!sink->session)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
if (sink->connect || sink->disconnect)
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
diff --git a/audio/source.c b/audio/source.c
index 8258fcd..4d47853 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -423,9 +423,7 @@ static DBusMessage *source_disconnect(DBusConnection *conn,
int err;
if (!source->session)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".NotConnected",
- "Device not Connected");
+ return __btd_error_not_connected(msg);
if (source->connect || source->disconnect)
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
diff --git a/src/error.c b/src/error.c
index 4429903..b2d0ced 100644
--- a/src/error.c
+++ b/src/error.c
@@ -69,3 +69,10 @@ DBusMessage *__btd_error_not_supported(DBusMessage *msg)
".NotSupported",
"Operation is not supported");
}
+
+DBusMessage *__btd_error_not_connected(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".NotConnected",
+ "Not Connected");
+}
diff --git a/src/error.h b/src/error.h
index 7dbb8b3..06345da 100644
--- a/src/error.h
+++ b/src/error.h
@@ -33,3 +33,4 @@ DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
DBusMessage *__btd_error_invalid_args(DBusMessage *msg);
DBusMessage *__btd_error_already_exists(DBusMessage *msg);
DBusMessage *__btd_error_not_supported(DBusMessage *msg);
+DBusMessage *__btd_error_not_connected(DBusMessage *msg);
--
1.7.3.1
^ permalink raw reply related
* [PATCH 3/9] Add __btd_error_not_supported()
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289197787-16715-3-git-send-email-padovan@profusion.mobi>
---
audio/control.c | 8 ++------
src/device.c | 4 +---
src/error.c | 7 +++++++
src/error.h | 1 +
4 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/audio/control.c b/audio/control.c
index 76f46e9..e9f59fc 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -1020,9 +1020,7 @@ static DBusMessage *volume_up(DBusConnection *conn, DBusMessage *msg,
"Device not Connected");
if (!control->target)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotSupported",
- "AVRCP Target role not supported");
+ return __btd_error_not_supported(msg);
err = avctp_send_passthrough(control, VOL_UP_OP);
if (err < 0)
@@ -1050,9 +1048,7 @@ static DBusMessage *volume_down(DBusConnection *conn, DBusMessage *msg,
"Device not Connected");
if (!control->target)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotSupported",
- "AVRCP Target role not supported");
+ return __btd_error_not_supported(msg);
err = avctp_send_passthrough(control, VOL_DOWN_OP);
if (err < 0)
diff --git a/src/device.c b/src/device.c
index 6d110dc..3393634 100644
--- a/src/device.c
+++ b/src/device.c
@@ -540,9 +540,7 @@ static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
case 0:
return dbus_message_new_method_return(msg);
case EINVAL:
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".NotSupported",
- "Kernel lacks blacklist support");
+ return __btd_error_not_supported(msg);
default:
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
"%s", strerror(-err));
diff --git a/src/error.c b/src/error.c
index e268163..4429903 100644
--- a/src/error.c
+++ b/src/error.c
@@ -62,3 +62,10 @@ DBusMessage *__btd_error_already_exists(DBusMessage *msg)
ERROR_INTERFACE ".AlreadyExists",
"Already Exists");
}
+
+DBusMessage *__btd_error_not_supported(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".NotSupported",
+ "Operation is not supported");
+}
diff --git a/src/error.h b/src/error.h
index 284889f..7dbb8b3 100644
--- a/src/error.h
+++ b/src/error.h
@@ -32,3 +32,4 @@ DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
DBusMessage *__btd_error_invalid_args(DBusMessage *msg);
DBusMessage *__btd_error_already_exists(DBusMessage *msg);
+DBusMessage *__btd_error_not_supported(DBusMessage *msg);
--
1.7.3.1
^ permalink raw reply related
* [PATCH 2/9] Add __btd_error_already_exists()
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289197787-16715-2-git-send-email-padovan@profusion.mobi>
---
audio/gateway.c | 4 +---
audio/media.c | 3 +--
network/server.c | 2 +-
serial/proxy.c | 3 +--
src/adapter.c | 8 ++------
src/device.c | 4 +---
src/error.c | 7 +++++++
src/error.h | 1 +
8 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index ab7d310..ae0ee75 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -488,9 +488,7 @@ static DBusMessage *register_agent(DBusConnection *conn,
const char *path, *name;
if (gw->agent)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".AlreadyExists",
- "Agent already exists");
+ return __btd_error_already_exists(msg);
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
diff --git a/audio/media.c b/audio/media.c
index 862cee6..8821ee1 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -318,8 +318,7 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
dbus_message_iter_next(&args);
if (media_adapter_find_endpoint(adapter, sender, path, NULL) != NULL)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "Endpoint already registered");
+ return __btd_error_already_exists(msg);
dbus_message_iter_recurse(&args, &props);
if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
diff --git a/network/server.c b/network/server.c
index ce1fe5e..41c9ec3 100644
--- a/network/server.c
+++ b/network/server.c
@@ -605,7 +605,7 @@ static DBusMessage *register_server(DBusConnection *conn,
return failed(msg, "Invalid UUID");
if (ns->record_id)
- return failed(msg, "Already registered");
+ return __btd_error_already_exists(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
diff --git a/serial/proxy.c b/serial/proxy.c
index 8e182b6..de82f9a 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -1058,8 +1058,7 @@ static DBusMessage *create_proxy(DBusConnection *conn,
if (err == -EINVAL)
return __btd_error_invalid_args(msg);
else if (err == -EALREADY)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExist",
- "Proxy already exists");
+ return __btd_error_already_exists(msg);
else if (err < 0)
return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
"Proxy creation failed (%s)", strerror(-err));
diff --git a/src/adapter.c b/src/adapter.c
index cc51816..ffbc943 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1742,9 +1742,7 @@ static DBusMessage *create_device(DBusConnection *conn,
return __btd_error_invalid_args(msg);
if (adapter_find_device(adapter, address))
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".AlreadyExists",
- "Device already exists");
+ return __btd_error_already_exists(msg);
DBG("%s", address);
@@ -1906,9 +1904,7 @@ static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg,
return NULL;
if (adapter->agent)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".AlreadyExists",
- "Agent already exists");
+ return __btd_error_already_exists(msg);
cap = parse_io_capability(capability);
if (cap == IO_CAPABILITY_INVALID)
diff --git a/src/device.c b/src/device.c
index ef1a910..6d110dc 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1944,9 +1944,7 @@ DBusMessage *device_create_bonding(struct btd_device *device,
str = textfile_caseget(filename, dstaddr);
if (str) {
free(str);
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".AlreadyExists",
- "Bonding already exists");
+ return __btd_error_already_exists(msg);
}
/* If our IO capability is NoInputNoOutput use medium security
diff --git a/src/error.c b/src/error.c
index a30c050..e268163 100644
--- a/src/error.c
+++ b/src/error.c
@@ -55,3 +55,10 @@ DBusMessage *__btd_error_invalid_args(DBusMessage *msg)
".InvalidArguments",
"Invalid arguments in method call");
}
+
+DBusMessage *__btd_error_already_exists(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg,
+ ERROR_INTERFACE ".AlreadyExists",
+ "Already Exists");
+}
diff --git a/src/error.h b/src/error.h
index 51c094c..284889f 100644
--- a/src/error.h
+++ b/src/error.h
@@ -31,3 +31,4 @@ DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
const char *name, const char *descr);
DBusMessage *__btd_error_invalid_args(DBusMessage *msg);
+DBusMessage *__btd_error_already_exists(DBusMessage *msg);
--
1.7.3.1
^ permalink raw reply related
* [PATCH 1/9] Create __btd_error_invalid_args()
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289197787-16715-1-git-send-email-padovan@profusion.mobi>
DBus error handling in BlueZ is a mess. This is the first patch to unify
all DBus error handling like in ConnMan and oFono. This unifies all
.InvalidArguments errors.
---
attrib/client.c | 20 +++++----------
audio/gateway.c | 8 +----
audio/headset.c | 18 ++++---------
audio/media.c | 9 ++----
audio/telephony-dummy.c | 25 ++++++++------------
audio/telephony-maemo5.c | 11 ++------
audio/telephony-maemo6.c | 11 ++------
audio/transport.c | 14 +++--------
health/hdp.c | 58 ++++++++++++----------------------------------
network/server.c | 7 -----
plugins/service.c | 8 +-----
serial/port.c | 8 ------
serial/proxy.c | 19 ++++----------
src/adapter.c | 52 ++++++++++++++++++-----------------------
src/device.c | 22 ++++++-----------
src/error.c | 7 +++++
src/error.h | 2 +
src/manager.c | 7 -----
18 files changed, 100 insertions(+), 206 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 1f2c217..cd6e401 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -190,12 +190,6 @@ static int watcher_cmp(gconstpointer a, gconstpointer b)
return g_strcmp0(watcher->path, match->path);
}
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static inline DBusMessage *not_authorized(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAuthorized",
@@ -465,7 +459,7 @@ static DBusMessage *register_watcher(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (l2cap_connect(prim->gatt, &gerr, TRUE) < 0) {
DBusMessage *reply;
@@ -499,7 +493,7 @@ static DBusMessage *unregister_watcher(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
match = g_new0(struct watcher, 1);
match->name = g_strdup(sender);
@@ -537,7 +531,7 @@ static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg,
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(iter) != DBUS_TYPE_BYTE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_recurse(iter, &sub);
@@ -586,23 +580,23 @@ static DBusMessage *set_property(DBusConnection *conn,
const char *property;
if (!dbus_message_iter_init(msg, &iter))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&iter, &property);
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_recurse(&iter, &sub);
if (g_str_equal("Value", property))
return set_value(conn, msg, &sub, chr);
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
static GDBusMethodTable char_methods[] = {
diff --git a/audio/gateway.c b/audio/gateway.c
index 07ebdd4..ab7d310 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -494,9 +494,7 @@ static DBusMessage *register_agent(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid argument");
+ return __btd_error_invalid_args(msg);
name = dbus_message_get_sender(msg);
agent = g_new0(struct hf_agent, 1);
@@ -529,9 +527,7 @@ static DBusMessage *unregister_agent(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid argument");
+ return __btd_error_invalid_args(msg);
if (strcmp(gw->agent->path, path) != 0)
return g_dbus_create_error(msg,
diff --git a/audio/headset.c b/audio/headset.c
index 0763585..2cca5ca 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -180,12 +180,6 @@ struct event {
static GSList *headset_callbacks = NULL;
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static DBusHandlerResult error_not_supported(DBusConnection *conn,
DBusMessage *msg)
{
@@ -2026,35 +2020,35 @@ static DBusMessage *hs_set_property(DBusConnection *conn,
uint16_t gain;
if (!dbus_message_iter_init(msg, &iter))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&iter, &property);
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_recurse(&iter, &sub);
if (g_str_equal("SpeakerGain", property)) {
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT16)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &gain);
return hs_set_gain(conn, msg, data, gain,
HEADSET_GAIN_SPEAKER);
} else if (g_str_equal("MicrophoneGain", property)) {
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT16)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &gain);
return hs_set_gain(conn, msg, data, gain,
HEADSET_GAIN_MICROPHONE);
}
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
static GDBusMethodTable headset_methods[] = {
{ "Connect", "", "", hs_connect,
diff --git a/audio/media.c b/audio/media.c
index b6c90f9..862cee6 100644
--- a/audio/media.c
+++ b/audio/media.c
@@ -323,18 +323,15 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
dbus_message_iter_recurse(&args, &props);
if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".Failed", "Invalid argument");
+ return __btd_error_invalid_args(msg);
if (parse_properties(&props, &uuid, &delay_reporting, &codec,
&capabilities, &size) || uuid == NULL)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "Invalid argument");
+ return __btd_error_invalid_args(msg);
if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting,
codec, capabilities, size) == FALSE)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "Invalid argument");
+ return __btd_error_invalid_args(msg);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
diff --git a/audio/telephony-dummy.c b/audio/telephony-dummy.c
index 06cb798..b56b6e7 100644
--- a/audio/telephony-dummy.c
+++ b/audio/telephony-dummy.c
@@ -35,6 +35,7 @@
#include "log.h"
#include "telephony.h"
+#include "error.h"
#define TELEPHONY_DUMMY_IFACE "org.bluez.TelephonyTest"
#define TELEPHONY_DUMMY_PATH "/org/bluez/test"
@@ -69,12 +70,6 @@ static struct indicator dummy_indicators[] =
{ NULL }
};
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
-}
-
void telephony_device_connected(void *telephony_device)
{
DBG("telephony-dummy: device %p connected", telephony_device);
@@ -236,7 +231,7 @@ static DBusMessage *outgoing_call(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
DBG("telephony-dummy: outgoing call to %s", number);
@@ -261,7 +256,7 @@ static DBusMessage *incoming_call(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
DBG("telephony-dummy: incoming call to %s", number);
@@ -307,10 +302,10 @@ static DBusMessage *signal_strength(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &strength,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (strength > 5)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
telephony_update_indicator(dummy_indicators, "signal", strength);
@@ -326,10 +321,10 @@ static DBusMessage *battery_level(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &level,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (level > 5)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
telephony_update_indicator(dummy_indicators, "battchg", level);
@@ -346,7 +341,7 @@ static DBusMessage *roaming_status(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &roaming,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
val = roaming ? EV_ROAM_ACTIVE : EV_ROAM_INACTIVE;
@@ -365,7 +360,7 @@ static DBusMessage *registration_status(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, ®istration,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
val = registration ? EV_SERVICE_PRESENT : EV_SERVICE_NONE;
@@ -384,7 +379,7 @@ static DBusMessage *set_subscriber_number(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
g_free(subscriber_number);
subscriber_number = g_strdup(number);
diff --git a/audio/telephony-maemo5.c b/audio/telephony-maemo5.c
index 4d0134c..0f9819c 100644
--- a/audio/telephony-maemo5.c
+++ b/audio/telephony-maemo5.c
@@ -38,6 +38,7 @@
#include "log.h"
#include "telephony.h"
+#include "error.h"
/* SSC D-Bus definitions */
#define SSC_DBUS_NAME "com.nokia.phone.SSC"
@@ -1880,12 +1881,6 @@ static void csd_init(void)
}
}
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg,"org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
-}
-
static uint32_t get_callflag(const char *callerid_setting)
{
if (callerid_setting != NULL) {
@@ -1950,7 +1945,7 @@ static DBusMessage *set_callerid(DBusConnection *conn, DBusMessage *msg,
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,
&callerid_setting,
DBUS_TYPE_INVALID) == FALSE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (g_str_equal(callerid_setting, "allowed") ||
g_str_equal(callerid_setting, "restricted") ||
@@ -1964,7 +1959,7 @@ static DBusMessage *set_callerid(DBusConnection *conn, DBusMessage *msg,
error("telephony-maemo: invalid argument %s for method call"
" SetCallerId", callerid_setting);
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
static GDBusMethodTable telephony_maemo_methods[] = {
diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 72c8e36..4663b4d 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -38,6 +38,7 @@
#include "log.h"
#include "telephony.h"
+#include "error.h"
/* SSC D-Bus definitions */
#define SSC_DBUS_NAME "com.nokia.phone.SSC"
@@ -1760,12 +1761,6 @@ static void csd_init(void)
}
}
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg,"org.bluez.Error.InvalidArguments",
- "Invalid arguments in method call");
-}
-
static uint32_t get_callflag(const char *callerid_setting)
{
if (callerid_setting != NULL) {
@@ -1830,7 +1825,7 @@ static DBusMessage *set_callerid(DBusConnection *conn, DBusMessage *msg,
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,
&callerid_setting,
DBUS_TYPE_INVALID) == FALSE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (g_str_equal(callerid_setting, "allowed") ||
g_str_equal(callerid_setting, "restricted") ||
@@ -1844,7 +1839,7 @@ static DBusMessage *set_callerid(DBusConnection *conn, DBusMessage *msg,
error("telephony-maemo6: invalid argument %s for method call"
" SetCallerId", callerid_setting);
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
static DBusMessage *clear_lastnumber(DBusConnection *conn, DBusMessage *msg,
diff --git a/audio/transport.c b/audio/transport.c
index eda46e1..0c865f7 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -93,12 +93,6 @@ struct media_transport {
DBusMessageIter *value);
};
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static inline DBusMessage *error_failed(DBusMessage *msg, const char *desc)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", desc);
@@ -549,16 +543,16 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
int err;
if (!dbus_message_iter_init(msg, &iter))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&iter, &property);
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_recurse(&iter, &value);
sender = dbus_message_get_sender(msg);
@@ -577,7 +571,7 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
if (err < 0) {
if (err == -EINVAL)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
return error_failed(msg, strerror(-err));
}
diff --git a/health/hdp.c b/health/hdp.c
index 1eba8e1..6c1fd98 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -321,15 +321,8 @@ static DBusMessage *manager_create_application(DBusConnection *conn,
dbus_message_iter_init(msg, &iter);
app = hdp_get_app_config(&iter, &err);
- if (err) {
- DBusMessage *reply;
-
- reply = g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments: %s", err->message);
- g_error_free(err);
- return reply;
- }
+ if (err)
+ return __btd_error_invalid_args(msg);
name = dbus_message_get_sender(msg);
if (!name) {
@@ -368,11 +361,8 @@ static DBusMessage *manager_destroy_application(DBusConnection *conn,
GSList *l;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID)){
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
- }
+ DBUS_TYPE_INVALID))
+ return __btd_error_invalid_args(msg);
l = g_slist_find_custom(applications, path, cmp_app);
@@ -1801,18 +1791,13 @@ static DBusMessage *device_create_channel(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &app_path,
DBUS_TYPE_STRING, &conf,
- DBUS_TYPE_INVALID)) {
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
- }
+ DBUS_TYPE_INVALID))
+ return __btd_error_invalid_args(msg);
l = g_slist_find_custom(applications, app_path, cmp_app);
if (!l)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call, "
- "no such application");
+ return __btd_error_invalid_args(msg);
+
app = l->data;
if (g_ascii_strcasecmp("Reliable", conf) == 0)
@@ -1822,25 +1807,16 @@ static DBusMessage *device_create_channel(DBusConnection *conn,
else if (g_ascii_strcasecmp("Any", conf) == 0)
config = HDP_NO_PREFERENCE_DC;
else
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
+ return __btd_error_invalid_args(msg);
if (app->role == HDP_SINK && config != HDP_NO_PREFERENCE_DC)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Configuration not valid for sinks");
+ return __btd_error_invalid_args(msg);
if (app->role == HDP_SOURCE && config == HDP_NO_PREFERENCE_DC)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Configuration not valid for sources");
+ return __btd_error_invalid_args(msg);
if (!device->fr && config == HDP_STREAMING_DC)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Configuration not valid, first "
- "channel should be reliable");
+ return __btd_error_invalid_args(msg);
data = g_new0(struct hdp_create_dc, 1);
data->dev = device;
@@ -1924,17 +1900,13 @@ static DBusMessage *device_destroy_channel(DBusConnection *conn,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID)){
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
+ return __btd_error_invalid_args(msg);
}
l = g_slist_find_custom(device->channels, path, cmp_chan_path);
if (!l)
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call, "
- "no such channel");
+ return __btd_error_invalid_args(msg);
+
hdp_chan = l->data;
del_data = g_new0(struct hdp_tmp_dc_data, 1);
del_data->msg = dbus_message_ref(msg);
diff --git a/network/server.c b/network/server.c
index e6706ec..ce1fe5e 100644
--- a/network/server.c
+++ b/network/server.c
@@ -575,13 +575,6 @@ static inline DBusMessage *failed(DBusMessage *msg, const char *description)
"%s", description);
}
-static inline DBusMessage *invalid_arguments(DBusMessage *msg,
- const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "%s", description);
-}
-
static void server_disconnect(DBusConnection *conn, void *user_data)
{
struct network_server *ns = user_data;
diff --git a/plugins/service.c b/plugins/service.c
index f6b9da7..6f6a275 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -339,12 +339,6 @@ static void exit_callback(DBusConnection *conn, void *user_data)
g_free(user_record);
}
-static inline DBusMessage *invalid_arguments(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static inline DBusMessage *not_available(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
@@ -466,7 +460,7 @@ static DBusMessage *update_xml_record(DBusConnection *conn,
len = (record ? strlen(record) : 0);
if (len == 0)
- return invalid_arguments(msg);
+ return __btd_error_invalid_args(msg);
user_record = find_record(serv_adapter, handle,
dbus_message_get_sender(msg));
diff --git a/serial/port.c b/serial/port.c
index 0398f2e..b593311 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -57,7 +57,6 @@
#include "port.h"
#define SERIAL_PORT_INTERFACE "org.bluez.Serial"
-#define ERROR_INVALID_ARGS "org.bluez.Error.InvalidArguments"
#define ERROR_DOES_NOT_EXIST "org.bluez.Error.DoesNotExist"
#define MAX_OPEN_TRIES 5
@@ -243,13 +242,6 @@ static inline DBusMessage *does_not_exist(DBusMessage *msg,
"%s", description);
}
-static inline DBusMessage *invalid_arguments(DBusMessage *msg,
- const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "%s", description);
-}
-
static inline DBusMessage *failed(DBusMessage *msg, const char *description)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
diff --git a/serial/proxy.c b/serial/proxy.c
index 3aaabf3..8e182b6 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -140,13 +140,6 @@ static inline DBusMessage *does_not_exist(DBusMessage *msg,
"%s", description);
}
-static inline DBusMessage *invalid_arguments(DBusMessage *msg,
- const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "%s", description);
-}
-
static inline DBusMessage *failed(DBusMessage *msg, const char *description)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
@@ -755,17 +748,17 @@ static DBusMessage *proxy_set_serial_params(DBusConnection *conn,
return NULL;
if (str2speed(ratestr, &speed) == B0)
- return invalid_arguments(msg, "Invalid baud rate");
+ return __btd_error_invalid_args(msg);
ctrl = prx->proxy_ti.c_cflag;
if (set_databits(databits, &ctrl) < 0)
- return invalid_arguments(msg, "Invalid data bits");
+ return __btd_error_invalid_args(msg);
if (set_stopbits(stopbits, &ctrl) < 0)
- return invalid_arguments(msg, "Invalid stop bits");
+ return __btd_error_invalid_args(msg);
if (set_parity(paritystr, &ctrl) < 0)
- return invalid_arguments(msg, "Invalid parity");
+ return __btd_error_invalid_args(msg);
prx->proxy_ti.c_cflag = ctrl;
prx->proxy_ti.c_cflag |= (CLOCAL | CREAD);
@@ -1057,13 +1050,13 @@ static DBusMessage *create_proxy(DBusConnection *conn,
uuid_str = bt_name2string(pattern);
if (!uuid_str)
- return invalid_arguments(msg, "Invalid UUID");
+ return __btd_error_invalid_args(msg);
err = register_proxy(adapter, uuid_str, address, &proxy);
g_free(uuid_str);
if (err == -EINVAL)
- return invalid_arguments(msg, "Invalid address");
+ return __btd_error_invalid_args(msg);
else if (err == -EALREADY)
return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExist",
"Proxy already exists");
diff --git a/src/adapter.c b/src/adapter.c
index 31014e5..cc51816 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -148,12 +148,6 @@ struct btd_adapter {
static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
guint interval);
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
@@ -1088,7 +1082,7 @@ static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
if (!g_utf8_validate(name, -1, NULL)) {
error("Name change failed: supplied name isn't valid UTF-8");
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
if (strncmp(name, (char *) dev->name, MAX_NAME_LENGTH) == 0)
@@ -1535,23 +1529,23 @@ static DBusMessage *set_property(DBusConnection *conn,
ba2str(&adapter->bdaddr, srcaddr);
if (!dbus_message_iter_init(msg, &iter))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&iter, &property);
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_recurse(&iter, &sub);
if (g_str_equal("Name", property)) {
const char *name;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &name);
return set_name(conn, msg, name, data);
@@ -1559,7 +1553,7 @@ static DBusMessage *set_property(DBusConnection *conn,
gboolean powered;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &powered);
@@ -1568,7 +1562,7 @@ static DBusMessage *set_property(DBusConnection *conn,
gboolean discoverable;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &discoverable);
@@ -1577,7 +1571,7 @@ static DBusMessage *set_property(DBusConnection *conn,
uint32_t timeout;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &timeout);
@@ -1586,7 +1580,7 @@ static DBusMessage *set_property(DBusConnection *conn,
gboolean pairable;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &pairable);
@@ -1595,14 +1589,14 @@ static DBusMessage *set_property(DBusConnection *conn,
uint32_t timeout;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &timeout);
return set_pairable_timeout(conn, msg, timeout, data);
}
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
static DBusMessage *request_session(DBusConnection *conn,
@@ -1676,7 +1670,7 @@ static DBusMessage *list_devices(DBusConnection *conn,
const gchar *dev_path;
if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1709,10 +1703,10 @@ static DBusMessage *cancel_device_creation(DBusConnection *conn,
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_INVALID) == FALSE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (check_address(address) < 0)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
device = adapter_find_device(adapter, address);
if (!device || !device_is_creating(device, NULL))
@@ -1742,10 +1736,10 @@ static DBusMessage *create_device(DBusConnection *conn,
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_INVALID) == FALSE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (check_address(address) < 0)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (adapter_find_device(adapter, address))
return g_dbus_create_error(msg,
@@ -1790,21 +1784,21 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
DBUS_TYPE_OBJECT_PATH, &agent_path,
DBUS_TYPE_STRING, &capability,
DBUS_TYPE_INVALID) == FALSE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (check_address(address) < 0)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
sender = dbus_message_get_sender(msg);
if (adapter->agent &&
agent_matches(adapter->agent, sender, agent_path)) {
error("Refusing adapter agent usage as device specific one");
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
cap = parse_io_capability(capability);
if (cap == IO_CAPABILITY_INVALID)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
device = adapter_get_device(conn, adapter, address);
if (!device)
@@ -1832,7 +1826,7 @@ static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID) == FALSE)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
l = g_slist_find_custom(adapter->devices,
path, (GCompareFunc) device_path_cmp);
@@ -1870,7 +1864,7 @@ static DBusMessage *find_device(DBusConnection *conn, DBusMessage *msg,
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_INVALID))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
l = g_slist_find_custom(adapter->devices,
address, (GCompareFunc) device_address_cmp);
@@ -1918,7 +1912,7 @@ static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg,
cap = parse_io_capability(capability);
if (cap == IO_CAPABILITY_INVALID)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
name = dbus_message_get_sender(msg);
diff --git a/src/device.c b/src/device.c
index c2b6682..ef1a910 100644
--- a/src/device.c
+++ b/src/device.c
@@ -549,12 +549,6 @@ static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
}
}
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static DBusMessage *set_property(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -563,22 +557,22 @@ static DBusMessage *set_property(DBusConnection *conn,
const char *property;
if (!dbus_message_iter_init(msg, &iter))
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&iter, &property);
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_recurse(&iter, &sub);
if (g_str_equal("Trusted", property)) {
dbus_bool_t value;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &value);
return set_trust(conn, msg, value, data);
@@ -586,7 +580,7 @@ static DBusMessage *set_property(DBusConnection *conn,
const char *alias;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &alias);
return set_alias(conn, msg, alias, data);
@@ -594,14 +588,14 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_bool_t value;
if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
dbus_message_iter_get_basic(&sub, &value);
return set_blocked(conn, msg, value, data);
}
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
}
static void discover_services_req_exit(DBusConnection *conn, void *user_data)
@@ -636,7 +630,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
uuid_t uuid;
if (bt_string2uuid(&uuid, pattern) < 0)
- return invalid_args(msg);
+ return __btd_error_invalid_args(msg);
sdp_uuid128_to_uuid(&uuid);
diff --git a/src/error.c b/src/error.c
index c1a2fbf..a30c050 100644
--- a/src/error.c
+++ b/src/error.c
@@ -48,3 +48,10 @@ DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
return DBUS_HANDLER_RESULT_HANDLED;
}
+
+DBusMessage *__btd_error_invalid_args(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".InvalidArguments",
+ "Invalid arguments in method call");
+}
diff --git a/src/error.h b/src/error.h
index 49ec05e..51c094c 100644
--- a/src/error.h
+++ b/src/error.h
@@ -29,3 +29,5 @@
DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
const char *name, const char *descr);
+
+DBusMessage *__btd_error_invalid_args(DBusMessage *msg);
diff --git a/src/manager.c b/src/manager.c
index 3fad9e6..315f5c3 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -66,13 +66,6 @@ void manager_update_svc(struct btd_adapter* adapter, uint8_t svc)
adapter_set_service_classes(adapter, svc);
}
-static inline DBusMessage *invalid_args(DBusMessage *msg)
-{
- return g_dbus_create_error(msg,
- ERROR_INTERFACE ".InvalidArguments",
- "Invalid arguments in method call");
-}
-
static inline DBusMessage *no_such_adapter(DBusMessage *msg)
{
return g_dbus_create_error(msg,
--
1.7.3.1
^ permalink raw reply related
* [PATCH 0/9] Fixing DBus error system in BlueZ
From: Gustavo F. Padovan @ 2010-11-08 6:29 UTC (permalink / raw)
To: linux-bluetooth
Hi,
Here are some patches that try to fix the mess of reporting error to
DBus inside BlueZ. It follows the oFono and ConnMan error system.
The goal is to get ride of any directly call to g_dbus_create_error()
inside bluez code, changing that to __btd_error_*. This patch set
doesn't fix all of them yet, but is a very good start. Please review.
Gustavo F. Padovan (9):
Create __btd_error_invalid_args()
Add __btd_error_already_exists()
Add __btd_error_not_supported()
Add __btd_error_not_connected()
Add __btd_error_in_progress()
Add __btd_error_not_available()
Add __btd_error_busy()
Add __btd_error_does_not_exist()
Add __btd_error_not_authorized()
attrib/client.c | 28 ++++-----------
audio/control.c | 16 ++-------
audio/device.c | 6 +--
audio/gateway.c | 16 ++-------
audio/headset.c | 58 ++++++++++-----------------------
audio/media.c | 12 ++----
audio/sink.c | 10 ++----
audio/source.c | 7 +---
audio/telephony-dummy.c | 25 ++++++--------
audio/telephony-maemo5.c | 11 ++----
audio/telephony-maemo6.c | 11 ++----
audio/transport.c | 14 ++------
health/hdp.c | 58 ++++++++------------------------
input/device.c | 8 +----
network/server.c | 9 +----
plugins/service.c | 56 ++++++++------------------------
serial/port.c | 20 +----------
serial/proxy.c | 31 ++++-------------
src/adapter.c | 81 +++++++++++++++++-----------------------------
src/device.c | 49 ++++++++--------------------
src/error.c | 62 +++++++++++++++++++++++++++++++++++
src/error.h | 10 ++++++
src/manager.c | 7 ----
23 files changed, 221 insertions(+), 384 deletions(-)
--
1.7.3.1
^ permalink raw reply
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Arnd Bergmann @ 2010-11-08 5:24 UTC (permalink / raw)
To: Par-Gunnar Hjalmdahl
Cc: Alan Cox, linus.walleij, linux-bluetooth, linux-kernel,
Lukasz.Rymanowski
In-Reply-To: <AANLkTimEYAmocFh_c-KftpL2zRm+LaHzgJOBX31iicLj@mail.gmail.com>
On Friday 05 November 2010, Par-Gunnar Hjalmdahl wrote:
> 2010/10/31, Alan Cox <alan@lxorguk.ukuu.org.uk>:
> >> It's about the ldisc number. Both bluetooth and cg2900 register themselves
> >> to ldisc 15 (N_HCI). A user doing TIOCSETD can only get one of the two.
> >
> > Ah I see - I had assumed any actual final merge would be assigning it a
> > new LDISC code as is required.
>
> Sorry for not answering quicker. We in my department have been
> discussing new design as well as trying out some solutions.
>
> As an answer to previous comments, both from Arnd and Alan, we would
> like to do the following:
> - Introduce a new ldisc called N_H4_COMBO with a ldisc driver
> accordingly that will be placed under drivers/char
I'm not convinced, although that's what Alan was suggesting. I'd like
to hear from the bluetooth people what they think about this.
Could you summarize why you think that cg2900 is different enough from
an HCI to require a different line discipline? From your previous
explanation it sounded like it was mostly added functionality,
not something entirely different.
> - Keep CG2900 driver as an MFD. We will however register the MFD
> cells in each driver and remove the function API. The functions
> (write, reset, etc) will instead be placed in each MFD cell using
> function pointers. This way we can use different functions for
> different channels as needed. By placing the MFD cell registration in
> each chip driver we will also only expose the channels that are
> actually supported by each chip. This way we can also remove the
> pretty ugly matching between the devices and respective H4 channel as
> well as the add_h4_user function and the similar other functions.
Ok, excellent.
> We were thinking about if we could re-use the existing hci_ldisc
> driver. As stated before the big problem here is however that
> hci_ldisc directly registers to the Bluetooth stack. We could separate
> the data for FM and GPS in the protocol driver, but it is pretty ugly
> to have two separate data paths within the same driver.
One of us must be misreading the code. As far as I can tell, hci_ldisc
does not register to the bluetooth stack at all, it just provides
the basic multiplex for multiple HCI protocols, while hci_h4.c
communicates to the bluetooth stack.
If I read it correctly, that means that you can still use hci_ldisc,
but need to add another protocol next to hci_h4 and hci_bcsp for
your cg2900.
> As I've state earlier this would also not work with other transports
> such as SPI.I appreciate Arnd's suggestion to create a TTY for SPI,
> but I think that would overcomplicate the situation and create a
> solution more complex than actually needed. We think that creating a
> new ldisc creates a cleaner solution. It will to some extent remind of
> hci_ldisc, but it will not register to any framework except tty.
How would registering ony to tty solve the problem of SPI?
If you just add another hci_cg2900 module, it can register to both
the hci_ldisc and the spi code.
> We've thought about if we should switch cg2900 to a bus, but after
> discussing this we feel that CG2900 has such individual
> characteristics that it could be hard to create a bus that would suite
> it. We therefore will keep the MFD type. We might in the future add
> new chips to the driver, but they will most likely not require so much
> rework of the driver that we will have to create something completely
> new. We will rather create a lib file that contains common code to
> reduce total code size of the driver.
Yes, makes sense.
Arnd
^ permalink raw reply
* Re: bluez-4.78 broken for me
From: Johan Hedberg @ 2010-11-08 3:22 UTC (permalink / raw)
To: Stefan Seyfried, linux-bluetooth; +Cc: marcel
In-Reply-To: <20101108003740.GA7213@jh-x301>
Hi,
On Mon, Nov 08, 2010, Johan Hedberg wrote:
> You really should enable debug logs (-d switch) to get more info about
> which code paths are being traveresed here (since there are many places
> which can cause those log messages). However, my suspicion goes to a
> possible mismatch in the adapter address upon initialization and later
> lookups. Could you try if the attached patch fixes the issue? Thanks.
I was able to reproduce the issue myself. Even though reverting the
patch I mentioned should work as a quick fix I went ahead and pushed a
more proper one to git (it essentially makes hciops wait for the
read_bd_addr complete event before calling start_adapter). So please
test with latest git and let me know if things still work fine. If they
do I think we should release 4.79 since I suspect this race condition
will be experienced by quite many people.
Johan
^ permalink raw reply
* Re: bluez-4.78 broken for me
From: Johan Hedberg @ 2010-11-08 0:37 UTC (permalink / raw)
To: Stefan Seyfried; +Cc: linux-bluetooth
In-Reply-To: <20101108003042.35493250@susi.home.s3e.de>
[-- Attachment #1: Type: text/plain, Size: 1841 bytes --]
Hi Stefan,
On Mon, Nov 08, 2010, Stefan Seyfried wrote:
> since I did upgrade to bluez-4.78, all I get when enabling the bluetooth
> adapter on my Thinkpad X200s is:
>
> kernel: [248420.020080] usb 4-2: new full speed USB device using uhci_hcd and address 7
> kernel: [248420.179082] usb 4-2: New USB device found, idVendor=0a5c, idProduct=2145
> kernel: [248420.179087] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> kernel: [248420.179090] usb 4-2: Product: ThinkPad Bluetooth with Enhanced Data Rate II
> kernel: [248420.179094] usb 4-2: Manufacturer: Lenovo Computer Corp
> bluetoothd[4390]: Bluetooth deamon 4.78
> bluetoothd[4393]: Starting SDP server
> bluetoothd[4393]: Parsing /etc/bluetooth/input.conf failed: No such file or directory
> bluetoothd[4393]: Parsing /etc/bluetooth/audio.conf failed: No such file or directory
> bluetoothd[4393]: HCI dev 0 registered
> bluetoothd[4393]: HCI dev 0 up
> bluetoothd[4393]: Starting security manager 0
> bluetoothd[4393]: Parsing /etc/bluetooth/serial.conf failed: No such file or directory
> bluetoothd[4393]: Adapter /org/bluez/4390/hci0 has been enabled
> bluetoothd[4393]: Unable to find matching adapter
> bluetoothd[4393]: No matching adapter found
> bluetoothd[4393]: Unable to find matching adapter
> bluetoothd[4393]: No matching adapter found
> bluetoothd[4393]: Unable to find matching adapter
> bluetoothd[4393]: No matching adapter found
> bluetoothd[4393]: Unable to find matching adapter
You really should enable debug logs (-d switch) to get more info about
which code paths are being traveresed here (since there are many places
which can cause those log messages). However, my suspicion goes to a
possible mismatch in the adapter address upon initialization and later
lookups. Could you try if the attached patch fixes the issue? Thanks.
Johan
[-- Attachment #2: 0001-Revert-Cache-adapter-address-for-quick-lookup.patch --]
[-- Type: text/x-diff, Size: 1350 bytes --]
>From 045cbbe3d50119388afc04abbde514e88138c08a Mon Sep 17 00:00:00 2001
From: Johan Hedberg <johan.hedberg@nokia.com>
Date: Mon, 8 Nov 2010 02:33:50 +0200
Subject: [PATCH] Revert "Cache adapter address for quick lookup"
This reverts commit a352058752e541539b09e55124d411a534cc14af.
---
plugins/hciops.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/plugins/hciops.c b/plugins/hciops.c
index c7be417..73a7455 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -56,12 +56,10 @@ static guint child_io_id = 0;
static guint ctl_io_id = 0;
#define SK(index) devs[(index)].sk
-#define BDADDR(index) devs[(index)].bdaddr
static int max_dev = -1;
static struct dev_info {
int sk;
- bdaddr_t bdaddr;
} *devs = NULL;
static int ignore_device(struct hci_dev_info *di)
@@ -1312,8 +1310,6 @@ static void device_devup_setup(int index)
if (ignore_device(&di))
return;
- bacpy(&BDADDR(index), &di.bdaddr);
-
/* Set page timeout */
if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {
write_page_timeout_cp cp;
@@ -1939,7 +1935,9 @@ static int hciops_write_eir_data(int index, uint8_t *data)
static int hciops_read_bdaddr(int index, bdaddr_t *bdaddr)
{
- bacpy(bdaddr, &BDADDR(index));
+ if (hci_read_bd_addr(SK(index), bdaddr, HCI_REQ_TIMEOUT) < 0)
+ return -errno;
+
return 0;
}
--
1.7.1
^ permalink raw reply related
* bluez-4.78 broken for me
From: Stefan Seyfried @ 2010-11-07 23:30 UTC (permalink / raw)
To: linux-bluetooth
Hi,
since I did upgrade to bluez-4.78, all I get when enabling the bluetooth
adapter on my Thinkpad X200s is:
kernel: [248420.020080] usb 4-2: new full speed USB device using uhci_hcd and address 7
kernel: [248420.179082] usb 4-2: New USB device found, idVendor=0a5c, idProduct=2145
kernel: [248420.179087] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
kernel: [248420.179090] usb 4-2: Product: ThinkPad Bluetooth with Enhanced Data Rate II
kernel: [248420.179094] usb 4-2: Manufacturer: Lenovo Computer Corp
bluetoothd[4390]: Bluetooth deamon 4.78
bluetoothd[4393]: Starting SDP server
bluetoothd[4393]: Parsing /etc/bluetooth/input.conf failed: No such file or directory
bluetoothd[4393]: Parsing /etc/bluetooth/audio.conf failed: No such file or directory
bluetoothd[4393]: HCI dev 0 registered
bluetoothd[4393]: HCI dev 0 up
bluetoothd[4393]: Starting security manager 0
bluetoothd[4393]: Parsing /etc/bluetooth/serial.conf failed: No such file or directory
bluetoothd[4393]: Adapter /org/bluez/4390/hci0 has been enabled
bluetoothd[4393]: Unable to find matching adapter
bluetoothd[4393]: No matching adapter found
bluetoothd[4393]: Unable to find matching adapter
bluetoothd[4393]: No matching adapter found
bluetoothd[4393]: Unable to find matching adapter
bluetoothd[4393]: No matching adapter found
bluetoothd[4393]: Unable to find matching adapter
And it does not work at all. Downgrading to 4.77 brings:
kernel: [248504.361041] usb 4-2: new full speed USB device using uhci_hcd and address 8
kernel: [248504.517100] usb 4-2: New USB device found, idVendor=0a5c, idProduct=2145
kernel: [248504.517104] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
kernel: [248504.517107] usb 4-2: Product: ThinkPad Bluetooth with Enhanced Data Rate II
kernel: [248504.517109] usb 4-2: Manufacturer: Lenovo Computer Corp
bluetoothd[4570]: Bluetooth deamon 4.77
bluetoothd[4573]: Starting SDP server
bluetoothd[4573]: Parsing /etc/bluetooth/input.conf failed: No such file or directory
bluetoothd[4573]: Parsing /etc/bluetooth/audio.conf failed: No such file or directory
bluetoothd[4573]: HCI dev 0 registered
bluetoothd[4573]: HCI dev 0 up
bluetoothd[4573]: Starting security manager 0
bluetoothd[4573]: Parsing /etc/bluetooth/serial.conf failed: No such file or directory
bluetoothd[4573]: probe failed with driver input-headset for device /org/bluez/4570/hci0/dev_00_24_EF_D1_B3_23
bluetoothd[4573]: probe failed with driver input-headset for device /org/bluez/4570/hci0/dev_C0_E4_22_68_82_5E
bluetoothd[4573]: probe failed with driver input-headset for device /org/bluez/4570/hci0/dev_00_12_EE_23_CE_EA
bluetoothd[4573]: Adapter /org/bluez/4570/hci0 has been enabled
and then the usual messages from NetworkManager:
kernel: [248504.741917] NetworkManager[1228]: <warn> (00:24:EF:D1:B3:23): failed to look up interface index
kernel: [248504.741929] NetworkManager[1228]: <info> BT device seife C510 (00:24:EF:D1:B3:23) added (DUN NAP)
kernel: [248504.741939] NetworkManager[1228]: <info> (00:24:EF:D1:B3:23): new Bluetooth device (driver: 'bluez' ifindex: -1)
kernel: [248504.741948] NetworkManager[1228]: <info> (00:24:EF:D1:B3:23): exported as /org/freedesktop/NetworkManager/Devices/9
....
and moving the mouse gives:
kernel: [248514.682684] input: Bluetooth Travel Mouse as /devices/pci0000:00/0000:00:1a.1/usb4/4-2/4-2:1.0/bluetooth/hci0/hci0:11/input24
kernel: [248514.682950] generic-bluetooth 0005:046D:B002.000B: input,hidraw0: BLUETOOTH HID v48.09 Mouse [Bluetooth Travel Mouse] on 0C:60:76:88:2C:4C
This all is missing with 4.78
--
Stefan Seyfried
"Any ideas, John?"
"Well, surrounding them's out."
^ permalink raw reply
* [PATCH v2 6/6] Bluetooth: Fix not returning proper error in SCO
From: Gustavo F. Padovan @ 2010-11-06 21:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289079891-4795-5-git-send-email-padovan@profusion.mobi>
Return 0 in that situation could lead to errors in the caller.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/sco.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3d5f009..dc25faa 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -880,7 +880,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
int lm = 0;
if (type != SCO_LINK && type != ESCO_LINK)
- return 0;
+ return -EINVAL;
BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
@@ -906,7 +906,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
- return 0;
+ return -EINVAL;
if (!status) {
struct sco_conn *conn;
@@ -925,7 +925,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
BT_DBG("hcon %p reason %d", hcon, reason);
if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
- return 0;
+ return -EINVAL;
sco_conn_del(hcon, bt_err(reason));
--
1.7.3.1
^ permalink raw reply related
* [PATCH v2 5/6] Bluetooth: Get ride of __rfcomm_get_sock_by_channel()
From: Gustavo F. Padovan @ 2010-11-06 21:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289079891-4795-4-git-send-email-padovan@profusion.mobi>
rfcomm_get_sock_by_channel() was the only user of this function, so I merged
both into rfcomm_get_sock_by_channel(). The socket lock now should be hold
outside of rfcomm_get_sock_by_channel() once we hold and release it inside the
same function now.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/rfcomm/sock.c | 19 +++++++------------
1 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 5a061d3..9c2fffa 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -142,11 +142,13 @@ static struct sock *rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
/* Find socket with channel and source bdaddr.
* Returns closest match.
*/
-static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
+static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
{
struct sock *sk = NULL, *sk1 = NULL;
struct hlist_node *node;
+ read_lock(&rfcomm_sk_list.lock);
+
sk_for_each(sk, node, &rfcomm_sk_list.head) {
if (state && sk->sk_state != state)
continue;
@@ -161,19 +163,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t
sk1 = sk;
}
}
- return node ? sk : sk1;
-}
-/* Find socket with given address (channel, src).
- * Returns locked socket */
-static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-{
- struct sock *s;
- read_lock(&rfcomm_sk_list.lock);
- s = __rfcomm_get_sock_by_channel(state, channel, src);
- if (s) bh_lock_sock(s);
read_unlock(&rfcomm_sk_list.lock);
- return s;
+
+ return node ? sk : sk1;
}
static void rfcomm_sock_destruct(struct sock *sk)
@@ -939,6 +932,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if (!parent)
return 0;
+ bh_lock_sock(parent);
+
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
--
1.7.3.1
^ permalink raw reply related
* [PATCH v2 4/6] Bluetooth: Get ride of __l2cap_get_sock_by_psm()
From: Gustavo F. Padovan @ 2010-11-06 21:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289079891-4795-3-git-send-email-padovan@profusion.mobi>
l2cap_get_sock_by_psm() was the only user of this function, so I merged
both into l2cap_get_sock_by_psm(). The socket lock now should be hold
outside of l2cap_get_sock_by_psm() once we hold and release it inside the
same function now.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 22 +++++++++-------------
1 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 2f72b0d..77c5449 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -746,11 +746,13 @@ found:
/* Find socket with psm and source bdaddr.
* Returns closest match.
*/
-static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
+static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
{
struct sock *sk = NULL, *sk1 = NULL;
struct hlist_node *node;
+ read_lock(&l2cap_sk_list.lock);
+
sk_for_each(sk, node, &l2cap_sk_list.head) {
if (state && sk->sk_state != state)
continue;
@@ -765,20 +767,10 @@ static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src
sk1 = sk;
}
}
- return node ? sk : sk1;
-}
-/* Find socket with given address (psm, src).
- * Returns locked socket */
-static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
-{
- struct sock *s;
- read_lock(&l2cap_sk_list.lock);
- s = __l2cap_get_sock_by_psm(state, psm, src);
- if (s)
- bh_lock_sock(s);
read_unlock(&l2cap_sk_list.lock);
- return s;
+
+ return node ? sk : sk1;
}
static void l2cap_sock_destruct(struct sock *sk)
@@ -2921,6 +2913,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto sendresp;
}
+ bh_lock_sock(parent);
+
/* Check if the ACL is secure enough (if not SDP) */
if (psm != cpu_to_le16(0x0001) &&
!hci_conn_check_link_mode(conn->hcon)) {
@@ -4425,6 +4419,8 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
if (!sk)
goto drop;
+ bh_lock_sock(sk);
+
BT_DBG("sk %p, len %d", sk, skb->len);
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED)
--
1.7.3.1
^ permalink raw reply related
* [PATCH v2 3/6] Bluetooth: Hold the lock inside rfcomm_get_sock_by_addr()
From: Gustavo F. Padovan @ 2010-11-06 21:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289079891-4795-2-git-send-email-padovan@profusion.mobi>
It also have to change the name of the function to
rfcomm_get_sock_by_addr() because we do hold the lock inside it now.
rfcomm_get_sock_by_addr() just read data, so the lock now is
read_lock_bh().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/rfcomm/sock.c | 16 +++++-----------
1 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index aec505f..5a061d3 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -123,16 +123,18 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
}
/* ---- Socket functions ---- */
-static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
+static struct sock *rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
{
struct sock *sk = NULL;
struct hlist_node *node;
+ read_lock_bh(&rfcomm_sk_list.lock);
sk_for_each(sk, node, &rfcomm_sk_list.head) {
if (rfcomm_pi(sk)->channel == channel &&
!bacmp(&bt_sk(sk)->src, src))
break;
}
+ read_unlock_bh(&rfcomm_sk_list.lock);
return node ? sk : NULL;
}
@@ -374,9 +376,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
goto done;
}
- write_lock_bh(&rfcomm_sk_list.lock);
-
- if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
+ if (sa->rc_channel && rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
err = -EADDRINUSE;
} else {
/* Save source address */
@@ -385,8 +385,6 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
sk->sk_state = BT_BOUND;
}
- write_unlock_bh(&rfcomm_sk_list.lock);
-
done:
release_sock(sk);
return err;
@@ -459,17 +457,13 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
err = -EINVAL;
- write_lock_bh(&rfcomm_sk_list.lock);
-
for (channel = 1; channel < 31; channel++)
- if (!__rfcomm_get_sock_by_addr(channel, src)) {
+ if (!rfcomm_get_sock_by_addr(channel, src)) {
rfcomm_pi(sk)->channel = channel;
err = 0;
break;
}
- write_unlock_bh(&rfcomm_sk_list.lock);
-
if (err < 0)
goto done;
}
--
1.7.3.1
^ permalink raw reply related
* [PATCH v2 2/6] Bluetooth: Hold the lock inside sco_get_sock_by_addr()
From: Gustavo F. Padovan @ 2010-11-06 21:44 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1289079891-4795-1-git-send-email-padovan@profusion.mobi>
It also have to change the name of the function to
sco_get_sock_by_addr() because we do hold the lock inside it now.
sco_get_sock_by_addr() just read data, so the lock now is
read_lock_bh().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/sco.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index d0927d1..3d5f009 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -276,16 +276,18 @@ drop:
}
/* -------- Socket interface ---------- */
-static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
+static struct sock *sco_get_sock_by_addr(bdaddr_t *ba)
{
struct sock *sk;
struct hlist_node *node;
+ read_lock_bh(&sco_sk_list.lock);
sk_for_each(sk, node, &sco_sk_list.head)
if (!bacmp(&bt_sk(sk)->src, ba))
goto found;
sk = NULL;
found:
+ read_unlock_bh(&sco_sk_list.lock);
return sk;
}
@@ -469,9 +471,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
goto done;
}
- write_lock_bh(&sco_sk_list.lock);
-
- if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
+ if (bacmp(src, BDADDR_ANY) && sco_get_sock_by_addr(src)) {
err = -EADDRINUSE;
} else {
/* Save source address */
@@ -479,8 +479,6 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
sk->sk_state = BT_BOUND;
}
- write_unlock_bh(&sco_sk_list.lock);
-
done:
release_sock(sk);
return err;
--
1.7.3.1
^ permalink raw reply related
* [PATCH v2 1/6] Bluetooth: Hold the lock inside l2cap_get_sock_by_addr()
From: Gustavo F. Padovan @ 2010-11-06 21:44 UTC (permalink / raw)
To: linux-bluetooth
It also have to change the name of the function to
l2cap_get_sock_by_addr() because we do hold the lock inside it now.
l2cap_get_sock_by_addr() just read data, so the lock now is
read_lock_bh().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 17 ++++++-----------
1 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index cd8f6ea..2f72b0d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -728,15 +728,18 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
}
/* ---- Socket interface ---- */
-static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
+static struct sock *l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
{
struct sock *sk;
struct hlist_node *node;
+
+ read_lock_bh(&l2cap_sk_list.lock);
sk_for_each(sk, node, &l2cap_sk_list.head)
if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src))
goto found;
sk = NULL;
found:
+ read_unlock_bh(&l2cap_sk_list.lock);
return sk;
}
@@ -1024,9 +1027,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
}
}
- write_lock_bh(&l2cap_sk_list.lock);
-
- if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
+ if (la.l2_psm && l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) {
err = -EADDRINUSE;
} else {
/* Save source address */
@@ -1040,8 +1041,6 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
}
- write_unlock_bh(&l2cap_sk_list.lock);
-
done:
release_sock(sk);
return err;
@@ -1257,18 +1256,14 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
err = -EINVAL;
- write_lock_bh(&l2cap_sk_list.lock);
-
for (psm = 0x1001; psm < 0x1100; psm += 2)
- if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
+ if (!l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
l2cap_pi(sk)->psm = cpu_to_le16(psm);
l2cap_pi(sk)->sport = cpu_to_le16(psm);
err = 0;
break;
}
- write_unlock_bh(&l2cap_sk_list.lock);
-
if (err < 0)
goto done;
}
--
1.7.3.1
^ permalink raw reply related
* Re: Socket type in audio IPC
From: Johan Hedberg @ 2010-11-06 11:08 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <4CD26B4F.8070709@tieto.com>
Hi Andrzej,
On Thu, Nov 04, 2010, Andrzej Kaczmarek wrote:
> We have a problem with audio IPC, sometimes following printout can be
> seen in logs when A2DP connection fails:
> external/bluetooth/bluez/audio/pcm_bluetooth.c:1609:(audioservice_recv)
> Too short (1 bytes) IPC packet from bluetoothd
>
> I was not able to catch this issue on my workstation for debugging so
> far, but it does not seem like ipc.h mismatch between BlueZ and ALSA
> plugin - we use one BlueZ version for a long time. Perhaps it's
> because of some unusual fragmentation (not sure how exactly sockets
> work internally) so my questions is why SOCK_STREAM sockets are used
> in audio IPC? Doesn't SOCK_SEQPACKET fit better here since we're
> dealing with messages rather than byte stream? There's no handling of
> fragmented packets in pcm_bluetooth.c at all so in case recv() returns
> less bytes than expected this is immediately returned as an error.
You're right that SOCK_SEQPACKET would be a better choice. However,
changing it would break all existing clients that use SOCK_STREAM. Since
we've already introduced the new D-Bus based solution for this which
requires updating the clients anyway I don't think it's worth trying to
fix this for the old unix socket based solution. FWIW, there are no
current plans to keep maintaining pcm_bluetooth.c since most people use
pulseaudio or some other solution and since it's quite tricky to make an
ALSA userspace plugin use D-Bus properly. Feel free to try to come up
with a patch to update pcm_bluetooth.c to use the new Media API though,
and it might just live a little bit longer ;)
Johan
^ permalink raw reply
* Re: [PATCH 1/2] Add Application property to HealthChannel
From: Johan Hedberg @ 2010-11-06 10:56 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1288793188-11514-1-git-send-email-epx@signove.com>
Hi Elvis,
On Wed, Nov 03, 2010, Elvis Pfützenreuter wrote:
> This patch adds the Application property to HealthChannel, which
> allows to unambiguously relate a channel to an application.
>
> This property is useful when there are several processes interested
> in accepting HealthChannels but device address is not sufficient
> criteria to engage upon, or ignore, the ChannelConnected signal.
> Having the application path allows to determine role and data type,
> in the context of the process that has created that application.
> ---
> doc/health-api.txt | 5 +++++
> health/hdp.c | 3 +++
> 2 files changed, 8 insertions(+), 0 deletions(-)
Both patches have been pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Alan Cox @ 2010-11-05 17:19 UTC (permalink / raw)
To: Par-Gunnar Hjalmdahl
Cc: Arnd Bergmann, linus.walleij, linux-bluetooth, linux-kernel,
Lukasz.Rymanowski
In-Reply-To: <AANLkTimEYAmocFh_c-KftpL2zRm+LaHzgJOBX31iicLj@mail.gmail.com>
> - Introduce a new ldisc called N_H4_COMBO with a ldisc driver
> accordingly that will be placed under drivers/char
That seems sensible. That code should also be entirely hardware
independent.
> solution more complex than actually needed. We think that creating a
> new ldisc creates a cleaner solution. It will to some extent remind of
> hci_ldisc, but it will not register to any framework except tty.
Ok. So presumably both the SPI and the tty interfaces would then use the
same library code to do the demux - or are the protocols different ?
> We've thought about if we should switch cg2900 to a bus, but after
> discussing this we feel that CG2900 has such individual
> characteristics that it could be hard to create a bus that would suite
> it. We therefore will keep the MFD type. We might in the future add
> new chips to the driver, but they will most likely not require so much
> rework of the driver that we will have to create something completely
> new. We will rather create a lib file that contains common code to
> reduce total code size of the driver.
No particular opinion either way. Whatever works best and keeps it
modular.
^ permalink raw reply
* Re: [PATCH 5/9] mfd: Add UART support for the ST-Ericsson CG2900.
From: Par-Gunnar Hjalmdahl @ 2010-11-05 17:02 UTC (permalink / raw)
To: Alan Cox
Cc: Arnd Bergmann, linus.walleij, linux-bluetooth, linux-kernel,
Lukasz.Rymanowski
In-Reply-To: <20101031120429.1ca38140@pyx>
2010/10/31, Alan Cox <alan@lxorguk.ukuu.org.uk>:
>> It's about the ldisc number. Both bluetooth and cg2900 register themselves
>> to ldisc 15 (N_HCI). A user doing TIOCSETD can only get one of the two.
>
> Ah I see - I had assumed any actual final merge would be assigning it a
> new LDISC code as is required.
>
Hi,
Sorry for not answering quicker. We in my department have been
discussing new design as well as trying out some solutions.
As an answer to previous comments, both from Arnd and Alan, we would
like to do the following:
- Introduce a new ldisc called N_H4_COMBO with a ldisc driver
accordingly that will be placed under drivers/char
- Keep CG2900 driver as an MFD. We will however register the MFD
cells in each driver and remove the function API. The functions
(write, reset, etc) will instead be placed in each MFD cell using
function pointers. This way we can use different functions for
different channels as needed. By placing the MFD cell registration in
each chip driver we will also only expose the channels that are
actually supported by each chip. This way we can also remove the
pretty ugly matching between the devices and respective H4 channel as
well as the add_h4_user function and the similar other functions.
We were thinking about if we could re-use the existing hci_ldisc
driver. As stated before the big problem here is however that
hci_ldisc directly registers to the Bluetooth stack. We could separate
the data for FM and GPS in the protocol driver, but it is pretty ugly
to have two separate data paths within the same driver.
As I've state earlier this would also not work with other transports
such as SPI.I appreciate Arnd's suggestion to create a TTY for SPI,
but I think that would overcomplicate the situation and create a
solution more complex than actually needed. We think that creating a
new ldisc creates a cleaner solution. It will to some extent remind of
hci_ldisc, but it will not register to any framework except tty.
We've thought about if we should switch cg2900 to a bus, but after
discussing this we feel that CG2900 has such individual
characteristics that it could be hard to create a bus that would suite
it. We therefore will keep the MFD type. We might in the future add
new chips to the driver, but they will most likely not require so much
rework of the driver that we will have to create something completely
new. We will rather create a lib file that contains common code to
reduce total code size of the driver.
Do you see any problems with our suggestions?
/P-G
^ permalink raw reply
* RE: [PATCH 4/4] Sim Access Profile dummy driver
From: Waldemar.Rymarkiewicz @ 2010-11-05 15:14 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, suraj, joakim.xj.ceder
In-Reply-To: <20101105101600.GC32149@jh-x301>
[-- Attachment #1: Type: text/plain, Size: 948 bytes --]
Hi Johan,
>
>Never mind the previous comment I had about this. I checked
>the rest of the tree and it seems this inline convention for
>D-Bus error generating functions is quite common (though imho
>might not be needed at all).
>
>> + if(sim_card_connection_status != SIM_CONNECTED)
>
>Space before (
>
>> +}
>> +
>> +
>> +static GDBusMethodTable dummy_methods[] = {
>
>Remove the other empty line.
>
>> + { "OngoingCall", "b", "", ongoing_call},
>> + { "MaxMessageSize", "u", "", max_msg_size},
>> + { "Disconnect", "", "", disconnect},
>> + { "CardStatus", "u", "", card_status},
>> + { }
>
>> +static GDBusSignalTable dummy_signals[] = {
>> + { "","" },
>> + { }
>> +};
>
>If you have no signals just pass NULL to
>g_dbus_register_interface instead of declaring an (almost)
>empty table. Also, "" isn't a valid value for the signal name.
Thanks again for comments and see attached patch.
/Waldek
[-- Attachment #2: 0004-Sim-Access-Profile-dummy-driver.patch --]
[-- Type: application/octet-stream, Size: 12326 bytes --]
From 7e2e1e832e51d22a3acac76a76db1a5c2d95dffe Mon Sep 17 00:00:00 2001
From: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Date: Wed, 20 Oct 2010 12:42:48 +0200
Subject: [PATCH 4/4] Sim Access Profile dummy driver
Add SAP dummy driver implementation and extend configure
with --with-sap=<driver>.
---
.gitignore | 1 +
Makefile.am | 13 +++-
acinclude.m4 | 6 ++
sap/sap-dummy.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 257 insertions(+), 17 deletions(-)
diff --git a/.gitignore b/.gitignore
index 07e239f..3e36a59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ lib/bluetooth
src/builtin.h
src/bluetoothd
audio/telephony.c
+sap/sap.c
scripts/bluetooth.rules
scripts/97-bluetooth.rules
scripts/97-bluetooth-hid2hci.rules
diff --git a/Makefile.am b/Makefile.am
index fe077f7..1d3dd53 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -147,7 +147,13 @@ builtin_modules += sap
builtin_sources += sap/main.c \
sap/manager.h sap/manager.c \
sap/server.h sap/server.c \
- sap/sap.h sap/sap-dummy.c
+ sap/sap.h
+
+builtin_nodist += sap/sap.c
+
+noinst_LIBRARIES = sap/libsap.a
+
+sap_libsap_a_SOURCES = sap/sap.h sap/sap-dummy.c
endif
if INPUTPLUGIN
@@ -271,7 +277,7 @@ EXTRA_DIST += src/genbuiltin src/bluetooth.conf \
input/input.conf serial/serial.conf \
audio/audio.conf audio/telephony-dummy.c \
audio/telephony-maemo5.c audio/telephony-ofono.c \
- audio/telephony-maemo6.c
+ audio/telephony-maemo6.c sap/sap-dummy.c
if ALSA
@@ -395,6 +401,9 @@ src/builtin.h: src/genbuiltin $(builtin_sources)
audio/telephony.c: audio/@TELEPHONY_DRIVER@
$(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
+sap/sap.c: sap/@SAP_DRIVER@
+ $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
+
scripts/%.rules:
$(AM_V_GEN)cp $(subst 97-,,$@) $@
diff --git a/acinclude.m4 b/acinclude.m4
index 1f76b4d..0ebeb11 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -194,6 +194,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
configfiles_enable=yes
telephony_driver=dummy
maemo6_enable=no
+ sap_driver=dummy
AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
optimization_enable=${enableval}
@@ -219,6 +220,11 @@ AC_DEFUN([AC_ARG_BLUEZ], [
serial_enable=${enableval}
])
+ AC_ARG_WITH(sap, AC_HELP_STRING([--with-sap=DRIVER], [select SAP driver]), [
+ sap_driver=${withval}
+ ])
+ AC_SUBST([SAP_DRIVER], [sap-${sap_driver}.c])
+
AC_ARG_ENABLE(input, AC_HELP_STRING([--disable-input], [disable input plugin]), [
input_enable=${enableval}
])
diff --git a/sap/sap-dummy.c b/sap/sap-dummy.c
index 92d73ef..c9897f5 100644
--- a/sap/sap-dummy.c
+++ b/sap/sap-dummy.c
@@ -3,11 +3,13 @@
*
* Copyright (C) 2010 ST-Ericsson SA
*
- * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for ST-Ericsson
+ * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
+ * for ST-Ericsson
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,65 +21,287 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
#include "log.h"
#include "sap.h"
+#define SAP_DUMMY_IFACE "org.bluez.SimAccessTest"
+#define SAP_DUMMY_PATH "/org/bluez/test"
+
+enum {
+ SIM_CONNECTED = 0x00,
+ SIM_DISCONNECTED= 0x01,
+ SIM_POWERED_OFF = 0x02,
+ SIM_MISSING = 0x03
+};
+
+static DBusConnection *connection = NULL;
+
+static int sim_card_conn_status = SIM_DISCONNECTED;
+static void *sap_data = NULL; /* SAP server private data.*/
+static gboolean ongoing_call_status = FALSE;
+static int max_msg_size_supported = 512;
+
void sap_connect_req(void *sap_device, uint16_t maxmsgsize)
{
- sap_connect_rsp(sap_device, SAP_STATUS_OK, maxmsgsize);
- sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+ if (sim_card_conn_status != SIM_CONNECTED) {
+ sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED,
+ maxmsgsize);
+ return;
+ } else if (max_msg_size_supported > maxmsgsize) {
+ sap_connect_rsp(sap_device, SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL,
+ max_msg_size_supported);
+ return;
+ } else if (max_msg_size_supported < maxmsgsize) {
+ sap_connect_rsp(sap_device,
+ SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED,
+ max_msg_size_supported);
+ return;
+ } else if (ongoing_call_status) {
+ sap_connect_rsp(sap_device, SAP_STATUS_OK_ONGOING_CALL,
+ maxmsgsize);
+ return;
+ } else {
+ sim_card_conn_status = SIM_CONNECTED;
+ sap_data = sap_device;
+
+ sap_connect_rsp(sap_device, SAP_STATUS_OK, maxmsgsize);
+ sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+ }
}
void sap_disconnect_req(void *sap_device, uint8_t linkloss)
{
+ sim_card_conn_status = SIM_DISCONNECTED;
+ sap_data = NULL;
+ ongoing_call_status = FALSE;
+
+ if (linkloss)
+ return;
+
sap_disconnect_rsp(sap_device);
}
void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param)
{
- sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
+ if (sim_card_conn_status == SIM_MISSING)
+ sap_transfer_apdu_rsp(sap_device,
+ SAP_RESULT_ERROR_CARD_REMOVED, NULL, 0);
+ else if (sim_card_conn_status == SIM_POWERED_OFF)
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF,
+ NULL, 0);
+ else if (sim_card_conn_status != SIM_CONNECTED)
+ sap_transfer_apdu_rsp(sap_device,
+ SAP_RESULT_ERROR_NOT_ACCESSIBLE, NULL, 0);
+ else
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
}
void sap_transfer_atr_req(void *sap_device)
{
- sap_transfer_atr_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
+ if (sim_card_conn_status == SIM_MISSING)
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED,
+ NULL, 0);
+ else if (sim_card_conn_status == SIM_POWERED_OFF)
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF,
+ NULL, 0);
+ else if (sim_card_conn_status != SIM_CONNECTED)
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON,
+ NULL, 0);
+ else
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
}
void sap_power_sim_off_req(void *sap_device)
{
- sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK);
+ if (sim_card_conn_status == SIM_MISSING) {
+ sap_power_sim_off_rsp(sap_device,
+ SAP_RESULT_ERROR_CARD_REMOVED);
+ } else if (sim_card_conn_status == SIM_POWERED_OFF) {
+ sap_power_sim_off_rsp(sap_device,
+ SAP_RESULT_ERROR_POWERED_OFF);
+ } else if (sim_card_conn_status != SIM_CONNECTED) {
+ sap_power_sim_off_rsp(sap_device,
+ SAP_RESULT_ERROR_NO_REASON);
+ } else {
+ sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK);
+ sim_card_conn_status = SIM_POWERED_OFF;
+ }
}
void sap_power_sim_on_req(void *sap_device)
{
- sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK);
+ if (sim_card_conn_status == SIM_MISSING) {
+ sap_power_sim_on_rsp(sap_device,
+ SAP_RESULT_ERROR_CARD_REMOVED);
+ } else if (sim_card_conn_status == SIM_POWERED_OFF) {
+ sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK);
+ sim_card_conn_status = SIM_CONNECTED;
+ return;
+ } else if (sim_card_conn_status != SIM_CONNECTED) {
+ sap_power_sim_on_rsp(sap_device,
+ SAP_RESULT_ERROR_NOT_ACCESSIBLE);
+ } else {
+ sap_power_sim_on_rsp(sap_device,
+ SAP_RESULT_ERROR_NO_REASON);
+ }
}
void sap_reset_sim_req(void *sap_device)
{
- sap_reset_sim_rsp(sap_device, SAP_RESULT_OK);
- sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+ if (sim_card_conn_status == SIM_MISSING) {
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED);
+ } else if (sim_card_conn_status == SIM_POWERED_OFF) {
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF);
+ } else if (sim_card_conn_status != SIM_CONNECTED) {
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
+ } else {
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_OK);
+ sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+ }
}
void sap_transfer_card_reader_status_req(void *sap_device)
{
- sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK,
- ICC_READER_CARD_POWERED_ON);
+ if (sim_card_conn_status != SIM_CONNECTED) {
+ sap_transfer_card_reader_status_rsp(sap_device,
+ SAP_RESULT_ERROR_NO_REASON, 0xF1);
+ return;
+ }
+ sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK, 0xF1);
}
-void sap_set_transport_protocol_req(void * sap_device,
+void sap_set_transport_protocol_req(void *sap_device,
struct sap_parameter *param)
{
sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
}
+static inline DBusMessage *invalid_args(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
+ "Invalid arguments in method call");
+}
+
+static DBusMessage *ongoing_call(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ dbus_bool_t ongoing;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &ongoing,
+ DBUS_TYPE_INVALID))
+ return invalid_args(msg);
+
+ if (ongoing_call_status && !ongoing) {
+ /* An ongoing call has finished. Continue connection.*/
+ sap_connect_rsp(sap_data, SAP_STATUS_OK,
+ max_msg_size_supported);
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_RESET);
+ ongoing_call_status = ongoing;
+ } else if (!ongoing_call_status && ongoing) {
+ /* An ongoing call has started.*/
+ ongoing_call_status = ongoing;
+ }
+
+ DBG("sap-dummy: OngoingCall status set to %d", ongoing_call_status);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *max_msg_size(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ dbus_uint32_t size;
+
+ if (sim_card_conn_status == SIM_CONNECTED)
+ return g_dbus_create_error(msg, "org.bluez.Error.Failed",
+ "Can't change msg size when connected.");
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &size,
+ DBUS_TYPE_INVALID))
+ return invalid_args(msg);
+
+ max_msg_size_supported = size;
+
+ DBG("sap-dummy: MaxMessageSize set to %d", max_msg_size_supported);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ sim_card_conn_status = SIM_DISCONNECTED;
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ dbus_uint32_t status;
+
+ if (sim_card_conn_status != SIM_CONNECTED)
+ return g_dbus_create_error(msg, "org.bluez.Error.Failed",
+ "Can't change msg size when connected.");
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &status,
+ DBUS_TYPE_INVALID))
+ return invalid_args(msg);
+
+ if (status) {
+ if (sim_card_conn_status == SIM_MISSING) {
+ sim_card_conn_status = SIM_CONNECTED;
+ sap_status_ind(sap_data,
+ SAP_STATUS_CHANGE_CARD_INSERTED);
+ }
+ } else {
+ sim_card_conn_status = SIM_MISSING;
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED);
+ }
+
+ DBG("sap-dummy: Card status changed to %d", status);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable dummy_methods[] = {
+ { "OngoingCall", "b", "", ongoing_call},
+ { "MaxMessageSize", "u", "", max_msg_size},
+ { "Disconnect", "", "", disconnect},
+ { "CardStatus", "u", "", card_status},
+ { }
+};
+
int sap_init(void)
{
- DBG("SAP driver init.");
+ connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+
+ if (g_dbus_register_interface(connection, SAP_DUMMY_PATH,
+ SAP_DUMMY_IFACE,
+ dummy_methods, NULL,
+ NULL, NULL, NULL) == FALSE) {
+ error("sap-dummy interface %s init failed on path %s",
+ SAP_DUMMY_IFACE, SAP_DUMMY_PATH);
+ return -1;
+ }
+
return 0;
}
void sap_exit(void)
{
- DBG("SAP driver exit.");
+ dbus_connection_unref(connection);
+ connection = NULL;
}
--
1.7.0.4
^ permalink raw reply related
* RE: [PATCH 3/4] Sim Access Profile Server
From: Waldemar.Rymarkiewicz @ 2010-11-05 15:12 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, suraj, joakim.xj.ceder
In-Reply-To: <20101105100548.GB32149@jh-x301>
[-- Attachment #1: Type: text/plain, Size: 733 bytes --]
Hi Johan,
>> + val = (uint16_t *) ¶m->val;
>> + maxmsgsize = ntohs(*val);
>
>Is this unaligned access safe?
In theory this is safe :) param-> val should be always aligned to 4 bytes according to sap spec
struct sap_parameter {
uint8_t id;
uint8_t reserved;
uint16_t len;
uint8_t val[0];
/*
* Padding bytes 0-3 bytes
*/
} __attribute__ ((packed));
However, I tried
maxmsgsize = ntohs(bt_get_unaligned((uint16_t *) ¶m->val));
and got gcc error: dereferencing type-punned pointer will break strict-aliasing rules.
Strange as it's already used in bluetoothd and it compiles without such errors. Do I missed something ?
Thanks for comments and have a look on fixed patch.
/Waldek
[-- Attachment #2: 0003-Sim-Access-Profile-Server.patch --]
[-- Type: application/octet-stream, Size: 48824 bytes --]
From f29febfca6b2c3faae6d8d8a9c53b90e5f6d39a7 Mon Sep 17 00:00:00 2001
From: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Date: Wed, 20 Oct 2010 12:21:40 +0200
Subject: [PATCH 3/4] Sim Access Profile Server
Add a Sim Access Server to the SAP plugin and a framework for the dummy
sap driver as well.
---
Makefile.am | 3 +-
sap/sap-dummy.c | 83 ++++
sap/sap.h | 192 ++++++++
sap/server.c | 1470 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 1741 insertions(+), 7 deletions(-)
create mode 100644 sap/sap-dummy.c
create mode 100644 sap/sap.h
diff --git a/Makefile.am b/Makefile.am
index c767b4c..fe077f7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,7 +146,8 @@ if SAPPLUGIN
builtin_modules += sap
builtin_sources += sap/main.c \
sap/manager.h sap/manager.c \
- sap/server.h sap/server.c
+ sap/server.h sap/server.c \
+ sap/sap.h sap/sap-dummy.c
endif
if INPUTPLUGIN
diff --git a/sap/sap-dummy.c b/sap/sap-dummy.c
new file mode 100644
index 0000000..92d73ef
--- /dev/null
+++ b/sap/sap-dummy.c
@@ -0,0 +1,83 @@
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2010 ST-Ericsson SA
+ *
+ * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "log.h"
+#include "sap.h"
+
+void sap_connect_req(void *sap_device, uint16_t maxmsgsize)
+{
+ sap_connect_rsp(sap_device, SAP_STATUS_OK, maxmsgsize);
+ sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+}
+
+void sap_disconnect_req(void *sap_device, uint8_t linkloss)
+{
+ sap_disconnect_rsp(sap_device);
+}
+
+void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param)
+{
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
+}
+
+void sap_transfer_atr_req(void *sap_device)
+{
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
+}
+
+void sap_power_sim_off_req(void *sap_device)
+{
+ sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK);
+}
+
+void sap_power_sim_on_req(void *sap_device)
+{
+ sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK);
+}
+
+void sap_reset_sim_req(void *sap_device)
+{
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_OK);
+ sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+}
+
+void sap_transfer_card_reader_status_req(void *sap_device)
+{
+ sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK,
+ ICC_READER_CARD_POWERED_ON);
+}
+
+void sap_set_transport_protocol_req(void * sap_device,
+ struct sap_parameter *param)
+{
+ sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
+}
+
+int sap_init(void)
+{
+ DBG("SAP driver init.");
+ return 0;
+}
+
+void sap_exit(void)
+{
+ DBG("SAP driver exit.");
+}
diff --git a/sap/sap.h b/sap/sap.h
new file mode 100644
index 0000000..7154e96
--- /dev/null
+++ b/sap/sap.h
@@ -0,0 +1,192 @@
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2010 Instituto Nokia de Tecnologia - INdT
+ * Copyright (C) 2010 ST-Ericsson SA
+ *
+ * Author: Marek Skowron <marek.skowron@tieto.com> for ST-Ericsson.
+ * Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
+ * for ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <glib.h>
+
+ #define SAP_VERSION 0x0101
+
+/* Connection Status - SAP v1.1 section 5.2.2 */
+typedef enum {
+ SAP_STATUS_OK = 0x00,
+ SAP_STATUS_CONNECTION_FAILED = 0x01,
+ SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED = 0x02,
+ SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL = 0x03,
+ SAP_STATUS_OK_ONGOING_CALL = 0x04
+} sap_status_t;
+
+/* Disconnection Type - SAP v1.1 section 5.2.3 */
+typedef enum {
+ SAP_DISCONNECTION_TYPE_GRACEFUL = 0x00,
+ SAP_DISCONNECTION_TYPE_IMMEDIATE = 0x01,
+ SAP_DISCONNECTION_TYPE_CLIENT = 0xFF
+} sap_disconnection_type_t;
+
+/* Result codes - SAP v1.1 section 5.2.4 */
+typedef enum {
+ SAP_RESULT_OK = 0x00,
+ SAP_RESULT_ERROR_NO_REASON = 0x01,
+ SAP_RESULT_ERROR_NOT_ACCESSIBLE = 0x02,
+ SAP_RESULT_ERROR_POWERED_OFF = 0x03,
+ SAP_RESULT_ERROR_CARD_REMOVED = 0x04,
+ SAP_RESULT_ERROR_POWERED_ON = 0x05,
+ SAP_RESULT_ERROR_NO_DATA = 0x06,
+ SAP_RESULT_NOT_SUPPORTED = 0x07
+} sap_result_t;
+
+/* Status Change - SAP v1.1 section 5.2.8 */
+typedef enum {
+ SAP_STATUS_CHANGE_UNKNOWN_ERROR = 0x00,
+ SAP_STATUS_CHANGE_CARD_RESET = 0x01,
+ SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE = 0x02,
+ SAP_STATUS_CHANGE_CARD_REMOVED = 0x03,
+ SAP_STATUS_CHANGE_CARD_INSERTED = 0x04,
+ SAP_STATUS_CHANGE_CARD_RECOVERED = 0x05
+} sap_status_change_t;
+
+/* Message format - SAP v1.1 section 5.1 */
+struct sap_parameter {
+ uint8_t id;
+ uint8_t reserved;
+ uint16_t len;
+ uint8_t val[0];
+ /*
+ * Padding bytes 0-3 bytes
+ */
+} __attribute__ ((packed));
+
+struct sap_message {
+ uint8_t id;
+ uint8_t nparam;
+ uint16_t reserved;
+ struct sap_parameter param[0];
+} __attribute__ ((packed));
+
+typedef enum {
+ ICC_READER_UNSPECIFIED_ERROR, /* No further information available */
+ ICC_READER_NOT_PRESENT, /* Card Reader removed or not present */
+ ICC_READER_BUSY, /* Card Reader in use */
+ ICC_READER_CARD_POWERED_ON, /* Card in reader and is powered on */
+ ICC_READER_DEACTIVATED, /* Card Reader deactivated */
+ ICC_READER_CARD_POWERED_OFF, /* Card in reader, but powered off */
+ ICC_READER_NO_CARD, /* No card in reader */
+ ICC_READER_LAST
+} icc_reader_status_t;
+
+#define SAP_BUF_SIZE 512
+
+#define SAP_MSG_HEADER_SIZE 4
+
+enum sap_protocol {
+ SAP_CONNECT_REQ = 0x00,
+ SAP_CONNECT_RESP = 0x01,
+ SAP_DISCONNECT_REQ = 0x02,
+ SAP_DISCONNECT_RESP = 0x03,
+ SAP_DISCONNECT_IND = 0x04,
+ SAP_TRANSFER_APDU_REQ = 0x05,
+ SAP_TRANSFER_APDU_RESP = 0x06,
+ SAP_TRANSFER_ATR_REQ = 0x07,
+ SAP_TRANSFER_ATR_RESP = 0x08,
+ SAP_POWER_SIM_OFF_REQ = 0x09,
+ SAP_POWER_SIM_OFF_RESP = 0x0A,
+ SAP_POWER_SIM_ON_REQ = 0x0B,
+ SAP_POWER_SIM_ON_RESP = 0x0C,
+ SAP_RESET_SIM_REQ = 0x0D,
+ SAP_RESET_SIM_RESP = 0x0E,
+ SAP_TRANSFER_CARD_READER_STATUS_REQ = 0x0F,
+ SAP_TRANSFER_CARD_READER_STATUS_RESP = 0x10,
+ SAP_STATUS_IND = 0x11,
+ SAP_ERROR_RESP = 0x12,
+ SAP_SET_TRANSPORT_PROTOCOL_REQ = 0x13,
+ SAP_SET_TRANSPORT_PROTOCOL_RESP = 0x14,
+};
+
+/* Parameters Ids - SAP 1.1 section 5.2 */
+#define SAP_PARAM_ID_MAX_MSG_SIZE 0x00
+#define SAP_PARAM_ID_MAX_MSG_SIZE_LEN 0x02
+
+#define SAP_PARAM_ID_CONN_STATUS 0x01
+#define SAP_PARAM_ID_CONN_STATUS_LEN 0x01
+
+#define SAP_PARAM_ID_RESULT_CODE 0x02
+#define SAP_PARAM_ID_RESULT_CODE_LEN 0x01
+
+#define SAP_PARAM_ID_DISCONNECT_IND 0x03
+#define SAP_PARAM_ID_DISCONNECT_IND_LEN 0x01
+
+#define SAP_PARAM_ID_COMMAND_APDU 0x04
+#define SAP_PARAM_ID_RESPONSE_APDU 0x05
+#define SAP_PARAM_ID_ATR 0x06
+
+#define SAP_PARAM_ID_CARD_READER_STATUS 0x07
+#define SAP_PARAM_ID_CARD_READER_STATUS_LEN 0x01
+
+#define SAP_PARAM_ID_STATUS_CHANGE 0x08
+#define SAP_PARAM_ID_STATUS_CHANGE_LEN 0x01
+
+#define SAP_PARAM_ID_TRANSPORT_PROTOCOL 0x09
+#define SAP_PARAM_ID_TRANSPORT_PROTOCOL_LEN 0x01
+
+#define SAP_PARAM_ID_COMMAND_APDU7816 0x10
+
+/* Transport Protocol - SAP v1.1 section 5.2.9 */
+#define SAP_TRANSPORT_PROTOCOL_T0 0x00
+#define SAP_TRANSPORT_PROTOCOL_T1 0x01
+
+/*SAP driver init and exit routines. Implemented by sap-*.c */
+int sap_init(void);
+void sap_exit(void);
+
+/* SAP requests implemented by sap-*.c */
+void sap_connect_req(void *sap_device, uint16_t maxmsgsize);
+void sap_disconnect_req(void *sap_device, uint8_t linkloss);
+void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param);
+void sap_transfer_atr_req(void *sap_device);
+void sap_power_sim_off_req(void *sap_device);
+void sap_power_sim_on_req(void *sap_device);
+void sap_reset_sim_req(void *sap_device);
+void sap_transfer_card_reader_status_req(void *sap_device);
+void sap_set_transport_protocol_req(void *sap_device,
+ struct sap_parameter *param);
+
+/*SAP responses to SAP requests. Implemented by server.c */
+int sap_connect_rsp(void *sap_device, sap_status_t status,
+ uint16_t maxmsgsize);
+int sap_disconnect_rsp(void *sap_device);
+int sap_transfer_apdu_rsp(void *sap_device, sap_result_t result,
+ uint8_t *sap_apdu_resp, uint16_t length);
+int sap_transfer_atr_rsp(void *sap_device, sap_result_t result,
+ uint8_t *sap_atr, uint16_t length);
+int sap_power_sim_off_rsp(void *sap_device, sap_result_t result);
+int sap_power_sim_on_rsp(void *sap_device, sap_result_t result);
+int sap_reset_sim_rsp(void *sap_device, sap_result_t result);
+int sap_transfer_card_reader_status_rsp(void *sap_device, sap_result_t result,
+ icc_reader_status_t status);
+int sap_error_rsp(void *sap_device);
+int sap_transport_protocol_rsp(void *sap_device, sap_result_t result);
+
+/* Event indication. Implemented by server.c*/
+int sap_status_ind(void *sap_device, sap_status_change_t status_change);
+
diff --git a/sap/server.c b/sap/server.c
index 2728778..395aeaa 100644
--- a/sap/server.c
+++ b/sap/server.c
@@ -1,13 +1,16 @@
/*
* BlueZ - Bluetooth protocol stack for Linux
*
+ * Copyright (C) 2010 Instituto Nokia de Tecnologia - INdT
* Copyright (C) 2010 ST-Ericsson SA
*
+ * Author: Marek Skowron <marek.skowron@tieto.com> for ST-Ericsson.
* Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for ST-Ericsson.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,30 +22,1485 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "bluetooth.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <glib.h>
+#include <netinet/in.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include "adapter.h"
+#include "btio.h"
+#include "sdpd.h"
#include "log.h"
+#include "error.h"
+#include "dbus-common.h"
+#include "sap.h"
#include "server.h"
+#define SAP_SERVER_INTERFACE "org.bluez.SimAccess"
+#define SAP_UUID "0000112D-0000-1000-8000-00805F9B34FB"
+#define SAP_SERVER_CHANNEL 8
+#define SAP_BUF_SIZE 512
+
+#define PADDING4(x) (4 - (x & 0x03))
+#define PARAMETER_SIZE(x) (sizeof(struct sap_parameter) + x + PADDING4(x))
+
+#define SAP_NO_REQ 0xFF
+
+#define SAP_TIMER_GRACEFUL_DISCONNECT 30
+#define SAP_TIMER_NO_ACTIVITY 30
+
+enum {
+ SAP_STATE_DISCONNECTED,
+ SAP_STATE_CONNECT_IN_PROGRESS,
+ SAP_STATE_CONNECTED,
+ SAP_STATE_GRACEFUL_DISCONNECT,
+ SAP_STATE_IMMEDIATE_DISCONNECT,
+ SAP_STATE_CLIENT_DISCONNECT
+};
+
+struct sap_server {
+ bdaddr_t src;
+ char *path;
+ gboolean enable;
+ uint32_t record_id;
+ GIOChannel *listen_io;
+ GIOChannel *io; /* Connected client channel.*/
+ uint32_t state;
+ uint8_t processing_req;
+ guint timer_id;
+};
+
+static DBusConnection *connection = NULL;
+
+static void start_guard_timer(struct sap_server *server, guint interval);
+static void stop_guard_timer(struct sap_server *server);
+static gboolean guard_timeout(gpointer data);
+
+static size_t add_result_parameter(sap_result_t result,
+ struct sap_parameter *param)
+{
+ param->id = SAP_PARAM_ID_RESULT_CODE;
+ param->len = htons(SAP_PARAM_ID_RESULT_CODE_LEN);
+ *param->val = (uint8_t) result;
+ return PARAMETER_SIZE(SAP_PARAM_ID_RESULT_CODE_LEN);
+}
+
+static int is_power_sim_off_req_allowed(uint8_t processing_req)
+{
+ switch (processing_req) {
+ case SAP_NO_REQ:
+ case SAP_TRANSFER_APDU_REQ:
+ case SAP_TRANSFER_ATR_REQ:
+ case SAP_POWER_SIM_ON_REQ:
+ case SAP_RESET_SIM_REQ:
+ case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int is_reset_sim_req_allowed(uint8_t processing_req)
+{
+ switch (processing_req) {
+ case SAP_NO_REQ:
+ case SAP_TRANSFER_APDU_REQ:
+ case SAP_TRANSFER_ATR_REQ:
+ case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int check_msg(struct sap_message *msg)
+{
+ if (!msg)
+ return -EFAULT;
+
+ switch (msg->id) {
+ case SAP_CONNECT_REQ:
+ if (msg->nparam == 0x01 &&
+ msg->param->id == SAP_PARAM_ID_MAX_MSG_SIZE &&
+ ntohs(msg->param->len) == SAP_PARAM_ID_MAX_MSG_SIZE_LEN)
+ return 0;
+ break;
+ case SAP_TRANSFER_APDU_REQ:
+ if (msg->nparam == 0x01 &&
+ (msg->param->id == SAP_PARAM_ID_COMMAND_APDU ||
+ msg->param->id == SAP_PARAM_ID_COMMAND_APDU7816) &&
+ msg->param->len != 0x00)
+ return 0;
+ break;
+ case SAP_SET_TRANSPORT_PROTOCOL_REQ:
+ if (msg->nparam == 0x01 &&
+ msg->param->id == SAP_PARAM_ID_TRANSPORT_PROTOCOL &&
+ ntohs(msg->param->len) == SAP_PARAM_ID_TRANSPORT_PROTOCOL_LEN &&
+ (*msg->param->val == SAP_TRANSPORT_PROTOCOL_T0 ||
+ *msg->param->val == SAP_TRANSPORT_PROTOCOL_T1))
+ return 0;
+ break;
+ case SAP_DISCONNECT_REQ:
+ case SAP_TRANSFER_ATR_REQ:
+ case SAP_POWER_SIM_OFF_REQ:
+ case SAP_POWER_SIM_ON_REQ:
+ case SAP_RESET_SIM_REQ:
+ case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+ if (msg->nparam == 0x00)
+ return 0;
+ break;
+ }
+
+ error("Invalid message");
+ return -EBADMSG;
+}
+
+static sdp_record_t *create_sap_record(uint8_t channel)
+{
+ sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
+ uuid_t sap_uuid, gt_uuid, root_uuid, l2cap, rfcomm;
+ sdp_profile_desc_t profile;
+ sdp_record_t *record;
+ sdp_data_t *ch;
+
+ record = sdp_record_alloc();
+ if (!record)
+ return NULL;
+
+ root = sdp_list_append(NULL, &root_uuid);
+ sdp_set_browse_groups(record, root);
+ sdp_list_free(root, NULL);
+
+ sdp_uuid16_create(&sap_uuid, SAP_SVCLASS_ID);
+ svclass_id = sdp_list_append(NULL, &sap_uuid);
+ sdp_uuid16_create(>_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
+ svclass_id = sdp_list_append(svclass_id, >_uuid);
+
+ sdp_set_service_classes(record, svclass_id);
+ sdp_list_free(svclass_id, NULL);
+
+ sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
+ profile.version = SAP_VERSION;
+ profiles = sdp_list_append(NULL, &profile);
+ sdp_set_profile_descs(record, profiles);
+ sdp_list_free(profiles, NULL);
+
+ sdp_uuid16_create(&l2cap, L2CAP_UUID);
+ proto[0] = sdp_list_append(NULL, &l2cap);
+ apseq = sdp_list_append(NULL, proto[0]);
+
+ sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
+ proto[1] = sdp_list_append(NULL, &rfcomm);
+ ch = sdp_data_alloc(SDP_UINT8, &channel);
+ proto[1] = sdp_list_append(proto[1], ch);
+ apseq = sdp_list_append(apseq, proto[1]);
+
+ aproto = sdp_list_append(NULL, apseq);
+ sdp_set_access_protos(record, aproto);
+
+ sdp_set_info_attr(record, "SIM Access Server",
+ NULL, NULL);
+
+ sdp_data_free(ch);
+ sdp_list_free(proto[0], NULL);
+ sdp_list_free(proto[1], NULL);
+ sdp_list_free(apseq, NULL);
+ sdp_list_free(aproto, NULL);
+
+ return record;
+}
+
+static int send_message(struct sap_server *server, void *buf, gssize size)
+{
+ gsize written = 0;
+ GError *gerr;
+ GIOStatus gstatus;
+
+ if (!server || !buf)
+ return -1;
+
+ DBG("send_message: size=%x",(unsigned int)size);
+
+ gstatus = g_io_channel_write_chars(server->io, buf, size, &written,
+ &gerr);
+
+ if (gstatus != G_IO_STATUS_NORMAL) {
+ if (gerr)
+ g_error_free(gerr);
+
+ error("send_message:write error (%d)", gstatus);
+ return -1;
+ }
+
+ if (written != (gsize)size)
+ error("send_message:write error. written %d size %d",
+ written, size);
+
+ DBG("send_message: written=%x",(unsigned int)written);
+
+ return 0;
+}
+
+static int disconnect_ind(void *sap_device, sap_disconnection_type_t type)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ struct sap_parameter *param = (struct sap_parameter *) msg->param;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("disconnect_ind: data %p state %d disc_type %d",
+ server, server->state, type);
+
+ if (server->state != SAP_STATE_GRACEFUL_DISCONNECT &&
+ server->state != SAP_STATE_IMMEDIATE_DISCONNECT)
+ goto error_ind;
+
+ memset(buf, 0, sizeof(buf));
+ msg->id = SAP_DISCONNECT_IND;
+ msg->nparam = 0x01;
+
+ /* Add disconnection type. */
+ param->id = SAP_PARAM_ID_DISCONNECT_IND;
+ param->len = htons(SAP_PARAM_ID_DISCONNECT_IND_LEN);
+ *param->val = (uint8_t) type;
+ size += PARAMETER_SIZE(SAP_PARAM_ID_DISCONNECT_IND_LEN);
+
+ return send_message(sap_device, buf, size);
+
+error_ind:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ return -EPERM;
+}
+
+static void connect_req(void *data, struct sap_parameter *param)
+{
+ struct sap_server *server = data;
+ uint16_t maxmsgsize, *val;
+
+ if (!server || !param)
+ goto error_rsp;
+
+ if (server->state != SAP_STATE_DISCONNECTED)
+ goto error_rsp;
+
+ stop_guard_timer(server);
+
+ val = (uint16_t *) ¶m->val;
+ maxmsgsize = ntohs(*val);
+
+ DBG("Connect MaxMsgSize: 0x%04X(%d)", maxmsgsize, maxmsgsize);
+
+ server->state = SAP_STATE_CONNECT_IN_PROGRESS;
+
+ if (maxmsgsize <= SAP_BUF_SIZE){
+ server->processing_req = SAP_CONNECT_REQ;
+ sap_connect_req(server, maxmsgsize);
+ } else {
+ sap_connect_rsp(server, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED,
+ SAP_BUF_SIZE);
+ }
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(data);
+}
+
+static int disconnect_req(void *data, sap_disconnection_type_t disc_type)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ goto error_rsp;
+
+ DBG("disconnect_req: type 0x%x state %d", disc_type, server->state);
+
+ switch (disc_type) {
+ case SAP_DISCONNECTION_TYPE_GRACEFUL:
+
+ if (server->state == SAP_STATE_DISCONNECTED ||
+ server->state == SAP_STATE_CONNECT_IN_PROGRESS)
+ goto error_req;
+
+ if (server->state == SAP_STATE_CONNECTED) {
+ server->state = SAP_STATE_GRACEFUL_DISCONNECT;
+ server->processing_req = SAP_NO_REQ;
+ disconnect_ind(server, disc_type);
+
+ /* Start guard timer - timer will disconnect
+ * connection if client doesn't do it. */
+ start_guard_timer(server,
+ SAP_TIMER_GRACEFUL_DISCONNECT);
+
+ return 0;
+ }
+ /* Disconnection is ongoing - do nothing. */
+ return 0;
+
+ case SAP_DISCONNECTION_TYPE_IMMEDIATE:
+
+ if (server->state == SAP_STATE_DISCONNECTED ||
+ server->state == SAP_STATE_CONNECT_IN_PROGRESS)
+ goto error_req;
+
+ if (server->state == SAP_STATE_CONNECTED ||
+ server->state == SAP_STATE_GRACEFUL_DISCONNECT
+ ) {
+ server->state = SAP_STATE_IMMEDIATE_DISCONNECT;
+ server->processing_req = SAP_NO_REQ;
+
+ stop_guard_timer(server);
+
+ disconnect_ind(server, disc_type);
+ sap_disconnect_req(server, 0);
+
+ return 0;
+ }
+ /* Disconnection is ongoing - do nothing. */
+ return 0;
+
+ case SAP_DISCONNECTION_TYPE_CLIENT:
+
+ if (server->state != SAP_STATE_CONNECTED &&
+ server->state != SAP_STATE_GRACEFUL_DISCONNECT)
+ goto error_rsp;
+
+ server->state = SAP_STATE_CLIENT_DISCONNECT;
+ server->processing_req = SAP_NO_REQ;
+
+ stop_guard_timer(server);
+
+ sap_disconnect_req(server, 0);
+
+ return 0;
+
+ default:
+ error("Unknown disconnection type (type %x).", disc_type);
+ return -EINVAL;
+ }
+
+error_rsp:
+ sap_error_rsp(server);
+error_req:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ return -EPERM;
+}
+
+static void transfer_apdu_req(void *data, struct sap_parameter *param)
+{
+ struct sap_server *server = data;
+
+ if (!server || !param)
+ goto error_rsp;
+
+ param->len = ntohs(param->len);
+
+ DBG("transfer_apdu_req: data %p state %d", data, server->state);
+ DBG("transfer_apdu_req: apdu param id %d val %s len %d ",
+ param->id, param->val, param->len);
+
+ if (server->state != SAP_STATE_CONNECTED &&
+ server->state != SAP_STATE_GRACEFUL_DISCONNECT)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_TRANSFER_APDU_REQ;
+ sap_transfer_apdu_req(server, param);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void transfer_atr_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ goto error_rsp;
+
+ DBG("transfer_atr_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_TRANSFER_ATR_REQ;
+ sap_transfer_atr_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void power_sim_off_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ goto error_rsp;
+
+ DBG("power_sim_off_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (!is_power_sim_off_req_allowed(server->processing_req))
+ goto error_rsp;
+
+ server->processing_req = SAP_POWER_SIM_OFF_REQ;
+ sap_power_sim_off_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void power_sim_on_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ goto error_rsp;
+
+ DBG("power_sim_on_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_POWER_SIM_ON_REQ;
+ sap_power_sim_on_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void reset_sim_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ goto error_rsp;
+
+ DBG("reset_sim_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (!is_reset_sim_req_allowed(server->processing_req))
+ goto error_rsp;
+
+ server->processing_req = SAP_RESET_SIM_REQ;
+ sap_reset_sim_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void transfer_card_reader_status_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ goto error_rsp;
+
+ DBG("transfer_card_reader_status_req: data %p state %d",
+ data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_TRANSFER_CARD_READER_STATUS_REQ;
+ sap_transfer_card_reader_status_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void set_transport_protocol_req(void *data, struct sap_parameter *param)
+{
+ struct sap_server *server = data;
+
+ if (!server || !param)
+ goto error_rsp;
+
+ DBG("set_transport_protocol_req: data %p state %d param %p",
+ data, server->state, param);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_SET_TRANSPORT_PROTOCOL_REQ;
+ sap_set_transport_protocol_req(server, param);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void start_guard_timer(struct sap_server *server, guint interval)
+{
+ if (!server)
+ return;
+
+ if (!server->timer_id)
+ server->timer_id = g_timeout_add_seconds(interval,
+ guard_timeout, server);
+ else
+ error("Timer is already active.");
+}
+
+static void stop_guard_timer(struct sap_server *server)
+{
+ if (server && server->timer_id) {
+ g_source_remove(server->timer_id);
+ server->timer_id = 0;
+ }
+}
+
+static gboolean guard_timeout(gpointer data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ return FALSE;
+
+ DBG("guard_timeout: state: %x pr %x", server->state,
+ server->processing_req);
+
+ server->timer_id = 0;
+
+ switch (server->state) {
+ case SAP_STATE_DISCONNECTED:
+ /* Client opened RFCOMM channel but didn't send CONNECT_REQ,
+ * in fixed time or client disconnected SAP connection but
+ * didn't closed RFCOMM channel in fixed time.*/
+ if (server->io)
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ break;
+ case SAP_STATE_GRACEFUL_DISCONNECT:
+ /* Client didn't disconnect SAP connection in fixed time,
+ * so close SAP connection immediately. */
+ disconnect_req(server, SAP_DISCONNECTION_TYPE_IMMEDIATE);
+ break;
+ default:
+ error("guard_timeout: Unexpected state.");
+ break;
+ }
+
+ return FALSE;
+}
+
+
+int sap_connect_rsp(void *sap_device, sap_status_t status, uint16_t maxmsgsize)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ struct sap_parameter *param = (struct sap_parameter *) msg->param;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_connect_rsp: state %x pr %x status %x", server->state,
+ server->processing_req, status);
+
+ if (server->state != SAP_STATE_CONNECT_IN_PROGRESS)
+ return -EPERM;
+
+ memset(buf, 0, sizeof(buf));
+ msg->id = SAP_CONNECT_RESP;
+ msg->nparam = 0x01;
+
+ /* Add connection status */
+ param->id = SAP_PARAM_ID_CONN_STATUS;
+ param->len = htons(SAP_PARAM_ID_CONN_STATUS_LEN);
+ *param->val = (uint8_t)status;
+ size += PARAMETER_SIZE(SAP_PARAM_ID_CONN_STATUS_LEN);
+
+ /* Add MaxMsgSize */
+ if (maxmsgsize && (status == SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED ||
+ status == SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL)) {
+ uint16_t *len;
+ msg->nparam++;
+ /* Skip the first param */
+ param = (struct sap_parameter *) &buf[size];
+ param->id = SAP_PARAM_ID_MAX_MSG_SIZE;
+ param->len = htons(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
+ len = (uint16_t *) ¶m->val;
+ *len = htons(maxmsgsize);
+ size += PARAMETER_SIZE(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
+ }
+
+ if (status == SAP_STATUS_OK) {
+ gboolean connected = TRUE;
+ emit_property_changed(connection, server->path,
+ SAP_SERVER_INTERFACE,
+ "Connected", DBUS_TYPE_BOOLEAN, &connected);
+
+ server->state = SAP_STATE_CONNECTED;
+ } else {
+ server->state = SAP_STATE_DISCONNECTED;
+
+ /* Timer will shutdown channel if client doesn't send
+ * CONNECT_REQ or doesn't shutdown channel itself.*/
+ start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
+ }
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_disconnect_rsp(void *sap_device)
+{
+ struct sap_server *server = sap_device;
+ struct sap_message msg;
+
+ if (!server)
+ return -1;
+
+ DBG("sap_disconnect_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ switch (server->state) {
+ case SAP_STATE_CLIENT_DISCONNECT:
+ msg.id = SAP_DISCONNECT_RESP;
+
+ server->state = SAP_STATE_DISCONNECTED;
+ server->processing_req = SAP_NO_REQ;
+
+ /* Timer will close channel if client doesn't do it.*/
+ start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
+
+ return send_message(sap_device, &msg, sizeof(msg));
+
+ case SAP_STATE_IMMEDIATE_DISCONNECT:
+ server->state = SAP_STATE_DISCONNECTED;
+ server->processing_req = SAP_NO_REQ;
+
+ if (server->io)
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ return 0;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int sap_transfer_apdu_rsp(void *sap_device, sap_result_t result,
+ uint8_t *apdu, uint16_t length)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ struct sap_parameter *param = (struct sap_parameter *) msg->param;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_transfer_apdu_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_TRANSFER_APDU_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ if (result == SAP_RESULT_OK && (!apdu || (apdu && length == 0x00)))
+ return -EINVAL;
+
+ msg->id = SAP_TRANSFER_APDU_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, param);
+
+ /* Add APDU response. */
+ if (result == SAP_RESULT_OK) {
+ msg->nparam++;
+ /* Skipping the first param. */
+ param = (struct sap_parameter *) &buf[size];
+ param->id = SAP_PARAM_ID_RESPONSE_APDU;
+ param->len = htons(length);
+
+ size += PARAMETER_SIZE(length);
+ if (size > SAP_BUF_SIZE)
+ return -EOVERFLOW;
+
+ memcpy(param->val, apdu, length);
+ }
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_transfer_atr_rsp(void *sap_device, sap_result_t result,
+ uint8_t *atr, uint16_t length)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ struct sap_parameter *param = (struct sap_parameter *) msg->param;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_transfer_atr_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_TRANSFER_ATR_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ if (result == SAP_RESULT_OK && (!atr || (atr && length == 0x00)))
+ return -EINVAL;
+
+ msg->id = SAP_TRANSFER_ATR_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, param);
+
+ /* Add ATR response */
+ if (result == SAP_RESULT_OK) {
+ msg->nparam++;
+ /* Skip the first param */
+ param = (struct sap_parameter *) &buf[size];
+ param->id = SAP_PARAM_ID_ATR;
+ param->len = htons(length);
+
+ size += PARAMETER_SIZE(length);
+ if (size > SAP_BUF_SIZE)
+ return -EOVERFLOW;
+
+ memcpy(param->val, atr, length);
+ }
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_power_sim_off_rsp(void *sap_device, sap_result_t result)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_power_sim_off_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_POWER_SIM_OFF_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ msg->id = SAP_POWER_SIM_OFF_RESP;
+
+ /* Add result code.*/
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_power_sim_on_rsp(void *sap_device, sap_result_t result)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_power_sim_on_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_POWER_SIM_ON_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ msg->id = SAP_POWER_SIM_ON_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_reset_sim_rsp(void *sap_device, sap_result_t result)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_reset_sim_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_RESET_SIM_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ msg->id = SAP_RESET_SIM_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_transfer_card_reader_status_rsp(void *sap_device, sap_result_t result,
+ icc_reader_status_t status)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ struct sap_parameter *param = (struct sap_parameter *) msg->param;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_transfer_card_reader_status_rsp: state %x pr %x",
+ server->state, server->processing_req);
+
+ if (server->processing_req != SAP_TRANSFER_CARD_READER_STATUS_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ msg->id = SAP_TRANSFER_CARD_READER_STATUS_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, param);
+
+ /* Add card reader status. */
+ if (result == SAP_RESULT_OK) {
+ msg->nparam++;
+ /* Skipp the first param. */
+ param = (struct sap_parameter *) &buf[size];
+ param->id = SAP_PARAM_ID_CARD_READER_STATUS;
+ param->len = htons(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
+ *param->val = (uint8_t) status;
+ size += PARAMETER_SIZE(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
+ }
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_transport_protocol_rsp(void *sap_device, sap_result_t result)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_transport_protocol_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_SET_TRANSPORT_PROTOCOL_REQ)
+ /* Ignore this response because processing (state) request
+ * has been changed. This situation can happen e.g. when
+ * client sends disconnect request while server is processing
+ * another request.*/
+ return 0;
+
+ msg->id = SAP_SET_TRANSPORT_PROTOCOL_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_error_rsp(void *sap_device)
+{
+ struct sap_message msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.id = SAP_ERROR_RESP;
+
+ return send_message(sap_device, &msg, sizeof(msg));
+}
+
+int sap_status_ind(void *sap_device, sap_status_change_t status_change)
+{
+ struct sap_server *server = sap_device;
+ char buf[SAP_BUF_SIZE];
+ struct sap_message *msg = (struct sap_message *) buf;
+ struct sap_parameter *param = (struct sap_parameter *) msg->param;
+ size_t size = sizeof(struct sap_message);
+
+ if (!server)
+ return -1;
+
+ DBG("sap_status_ind: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->state != SAP_STATE_CONNECTED &&
+ server->state != SAP_STATE_GRACEFUL_DISCONNECT)
+ /* Don't propagate status ind. if client is not connected */
+ return 0;
+
+ msg->id = SAP_STATUS_IND;
+ msg->nparam = 0x01;
+
+ /* Add status change. */
+ param->id = SAP_PARAM_ID_STATUS_CHANGE;
+ param->len = htons(SAP_PARAM_ID_STATUS_CHANGE_LEN);
+ *param->val = (uint8_t) status_change;
+ size += PARAMETER_SIZE(SAP_PARAM_ID_STATUS_CHANGE_LEN);
+
+ return send_message(sap_device, buf, size);
+}
+
+static int handle_cmd(void *data, void *buf, size_t size)
+{
+ struct sap_message *msg = buf;
+
+ if (size < sizeof(struct sap_message))
+ goto error_rsp;
+
+ if (msg->nparam != 0 &&
+ size < (sizeof(struct sap_message) +
+ sizeof(struct sap_parameter) + 4))
+ goto error_rsp;
+
+ if (check_msg(msg) < 0)
+ goto error_rsp;
+
+ switch (msg->id) {
+ case SAP_CONNECT_REQ:
+ DBG("SAP Connect.");
+ connect_req(data, msg->param);
+ return 0;
+ case SAP_DISCONNECT_REQ:
+ DBG("SAP Disconnect.");
+ disconnect_req(data, SAP_DISCONNECTION_TYPE_CLIENT);
+ return 0;
+ case SAP_TRANSFER_APDU_REQ:
+ DBG("SAP Transfer APDU.");
+ transfer_apdu_req(data, msg->param);
+ return 0;
+ case SAP_TRANSFER_ATR_REQ:
+ DBG("SAP Transfer ATR.");
+ transfer_atr_req(data);
+ return 0;
+ case SAP_POWER_SIM_OFF_REQ:
+ DBG("SAP SIM off.");
+ power_sim_off_req(data);
+ return 0;
+ case SAP_POWER_SIM_ON_REQ:
+ DBG("SAP SIM on.");
+ power_sim_on_req(data);
+ return 0;
+ case SAP_RESET_SIM_REQ:
+ DBG("SAP SIM reset.");
+ reset_sim_req(data);
+ return 0;
+ case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+ DBG("SAP reader status.");
+ transfer_card_reader_status_req(data);
+ return 0;
+ case SAP_SET_TRANSPORT_PROTOCOL_REQ:
+ DBG("SAP set proto request.");
+ set_transport_protocol_req(data, msg->param);
+ return 0;
+ default:
+ DBG("SAP unknown message.");
+ break;
+ }
+
+error_rsp:
+ DBG("SAP ERROR RSP");
+ sap_error_rsp(data);
+ return -EBADMSG;
+}
+
+static gboolean sap_io_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+ char buf[SAP_BUF_SIZE];
+ size_t bytes_read = 0;
+ GError *gerr;
+ GIOStatus gstatus;
+
+ if (cond & G_IO_NVAL){
+ DBG("ERR (G_IO_NVAL) on rfcomm socket.");
+ return FALSE;
+ }
+
+ if (cond & G_IO_ERR) {
+ DBG("ERR (G_IO_ERR) on rfcomm socket.");
+ return FALSE;
+ }
+
+ if (cond & G_IO_HUP ) {
+ DBG("HUP on rfcomm socket.");
+ return FALSE;
+ }
+
+ gstatus = g_io_channel_read_chars(chan, buf, sizeof(buf) - 1,
+ &bytes_read, &gerr);
+
+ if (gstatus != G_IO_STATUS_NORMAL) {
+ if (gerr)
+ g_error_free(gerr);
+ return TRUE;
+ }
+
+ if (handle_cmd(data, buf, bytes_read) < 0)
+ error("Invalid SAP message.");
+
+ return TRUE;
+}
+
+static void sap_io_destroy(void *data)
+{
+ struct sap_server *server = data;
+
+ if (server && server->io) {
+ gboolean connected = FALSE;
+
+ stop_guard_timer(server);
+
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ g_io_channel_unref(server->io);
+
+ server->io = NULL;
+
+ if (server->state != SAP_STATE_CONNECT_IN_PROGRESS)
+ emit_property_changed(connection, server->path,
+ SAP_SERVER_INTERFACE,"Connected",
+ DBUS_TYPE_BOOLEAN, &connected);
+
+ if (server->state == SAP_STATE_CONNECT_IN_PROGRESS ||
+ server->state == SAP_STATE_CONNECTED ||
+ server->state == SAP_STATE_GRACEFUL_DISCONNECT)
+ {
+ sap_disconnect_req(NULL, 1);
+ }
+
+ server->state = SAP_STATE_DISCONNECTED;
+ }
+}
+
+static void sap_connect_cb(GIOChannel *chan, GError *gerr, gpointer data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ return;
+
+ /* Timer will shutdown the channel in case of lack of client
+ activity */
+ start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
+
+ g_io_add_watch_full(chan, G_PRIORITY_DEFAULT,
+ G_IO_IN | G_IO_ERR | G_IO_HUP| G_IO_NVAL,
+ sap_io_cb, server, sap_io_destroy);
+}
+
+static void connect_auth_cb(DBusError *derr, void *data)
+{
+ struct sap_server *server = data;
+ GError *gerr;
+
+ if (!server || !server->io)
+ return;
+
+ if (derr && dbus_error_is_set(derr)) {
+ error("Access denied: %s", derr->message);
+ goto drop;
+ }
+
+ if (!bt_io_accept(server->io, sap_connect_cb, server, NULL, &gerr)) {
+ error("bt_io_accept: %s", gerr->message);
+ g_error_free(gerr);
+ goto drop;
+ }
+
+ return;
+
+drop:
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ g_io_channel_unref(server->io);
+ server->io = NULL;
+}
+
+static void connect_confirm_cb(GIOChannel *chan, gpointer data)
+{
+ struct sap_server *server = data;
+ GError *gerr;
+ bdaddr_t src, dst;
+ int err;
+
+ if (!chan || !server)
+ return;
+
+ if (server->io)
+ goto drop;
+
+ bt_io_get(chan, BT_IO_RFCOMM, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ goto drop;
+ }
+
+ server->io = g_io_channel_ref(chan);
+
+ err = btd_request_authorization(&src, &dst, SAP_UUID,
+ connect_auth_cb, server);
+
+ if (err < 0) {
+ DBG("Authorization denied: %s", strerror(err));
+ goto drop;
+ }
+
+ DBG("SAP incoming connection (sock %d) authorization.",
+ g_io_channel_unix_get_fd(chan));
+
+ return;
+
+drop:
+ g_io_channel_shutdown(chan, TRUE, NULL);
+ if (server->io && server->io == chan) {
+ g_io_channel_unref(server->io);
+ server->io = NULL;
+ }
+}
+
+static inline DBusMessage *message_failed(DBusMessage *msg,
+ const char *description)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
+ "%s", description);
+}
+
+static DBusMessage *enable(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ sdp_record_t *record;
+ GIOChannel *io;
+ GError *gerr;
+
+ if (!server)
+ return message_failed(msg, "Server internal error.");
+
+ if (server->enable)
+ return message_failed(msg, "Server already enabled.");
+
+ record = create_sap_record(SAP_SERVER_CHANNEL);
+ if (!record)
+ return message_failed(msg, "Can't create SDP record for SAP.");
+
+ if (add_record_to_server(&server->src, record) < 0) {
+ sdp_record_free(record);
+ return message_failed(msg, "SDP record registration failed.");
+ }
+
+ io = bt_io_listen(BT_IO_RFCOMM, NULL, connect_confirm_cb, server,
+ NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &server->src,
+ BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
+ BT_IO_OPT_MASTER, TRUE,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ g_error_free(gerr);
+ sdp_record_free(record);
+ return message_failed(msg, "Listen rfcomm channel failed.");
+ }
+
+ DBG("Listen socket %x", g_io_channel_unix_get_fd(io));
+
+ server->enable = TRUE;
+ server->record_id = record->handle;
+ server->listen_io = io;
+
+ emit_property_changed(connection, server->path, SAP_SERVER_INTERFACE,
+ "Enabled", DBUS_TYPE_BOOLEAN, &server->enable);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *disable(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ DBusMessage *reply;
+
+ if (!server)
+ return message_failed(msg, "Server internal error.");
+
+ if (!server->enable)
+ return message_failed(msg, "Server already disabled.");
+
+ if (server->state != SAP_STATE_DISCONNECTED)
+ return message_failed(msg, "Ongoing connection exists.");
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ remove_record_from_server(server->record_id);
+
+ if (server->listen_io) {
+ g_io_channel_shutdown(server->listen_io, TRUE, NULL);
+ g_io_channel_unref(server->listen_io);
+ server->listen_io = NULL;
+ }
+
+ server->enable = FALSE;
+
+ emit_property_changed(connection, server->path, SAP_SERVER_INTERFACE,
+ "Enabled", DBUS_TYPE_BOOLEAN, &server->enable);
+
+ return reply;
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter dict;
+ dbus_bool_t connected;
+
+ if (!server)
+ return message_failed(msg, "Server internal error.");
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ dict_append_entry(&dict, "Enabled", DBUS_TYPE_BOOLEAN,
+ &server->enable);
+
+ connected = (server->state == SAP_STATE_CONNECTED ||
+ server->state == SAP_STATE_GRACEFUL_DISCONNECT);
+ dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &connected);
+
+ dbus_message_iter_close_container(&iter, &dict);
+
+ return reply;
+}
+
+static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ struct sap_server *server = data;
+ dbus_bool_t disc_type;
+ sap_disconnection_type_t sap_disc_type;
+
+ if (!server)
+ return message_failed(msg, "Server internal error.");
+
+ if (!server->enable)
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".Failed",
+ "Server already disabled");
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &disc_type,
+ DBUS_TYPE_INVALID) == FALSE)
+ return NULL;
+
+ sap_disc_type = disc_type ? SAP_DISCONNECTION_TYPE_GRACEFUL :
+ SAP_DISCONNECTION_TYPE_IMMEDIATE;
+ if (disconnect_req(server, sap_disc_type) < 0)
+ return g_dbus_create_error(msg, ERROR_INTERFACE
+ ".Failed",
+ "There is no active connection");
+
+ return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable server_methods[] = {
+ { "Enable","","", enable },
+ { "Disable","","", disable },
+ { "GetProperties","","a{sv}",get_properties },
+ { "Disconnect","b","", disconnect },
+ { }
+};
+
+static GDBusSignalTable server_signals[] = {
+ { "PropertyChanged", "sv"},
+ { }
+};
+
+static void server_free(struct sap_server *server)
+{
+ DBG("[%s::%s]", __FILE__, __FUNCTION__);
+
+ if (!server)
+ return;
+
+ g_free(server->path);
+ g_free(server);
+}
+
+static void destroy_sap_interface(void *data)
+{
+ struct sap_server *server = data;
+
+ DBG("Unregistered interface %s on path %s",
+ SAP_SERVER_INTERFACE, server->path);
+
+ server_free(server);
+}
+
int sap_server_register(const char *path, bdaddr_t *src)
{
- DBG("Register SAP server.");
+ struct sap_server *server;
+
+ if (sap_init() < 0) {
+ error("Sap driver initialization failed.");
+ return -1;
+ }
+
+ server = g_try_new0(struct sap_server, 1);
+
+ if (!server) {
+ sap_exit();
+ return -ENOMEM;
+ }
+
+ server->enable = FALSE;
+
+ if (!g_dbus_register_interface(connection, path, SAP_SERVER_INTERFACE,
+ server_methods, server_signals, NULL,
+ server, destroy_sap_interface)) {
+ error("D-Bus failed to register %s interface",
+ SAP_SERVER_INTERFACE);
+ server_free(server);
+ sap_exit();
+ return -1;
+ }
+
+ server->path = g_strdup(path);
+ bacpy(&server->src, src);
+
return 0;
}
int sap_server_unregister(const char *path)
{
- DBG("Unregister SAP server.");
+ g_dbus_unregister_interface(connection, path, SAP_SERVER_INTERFACE);
+ sap_exit();
return 0;
}
int sap_server_init(DBusConnection *conn)
{
- DBG("Init SAP server.");
+ connection = dbus_connection_ref(conn);
return 0;
}
void sap_server_exit(void)
{
- DBG("Exit SAP server.");
+ dbus_connection_unref(connection);
+ connection = NULL;
}
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 1/7] Bluetooth: Hold the lock inside l2cap_get_sock_by_addr()
From: Gustavo F. Padovan @ 2010-11-05 14:37 UTC (permalink / raw)
To: Ville Tervo; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20101105134935.GD19903@null>
Hi Ville,
* Ville Tervo <ville.tervo@nokia.com> [2010-11-05 15:49:35 +0200]:
> Hi Gustavo,
>
> On Tue, Nov 02, 2010 at 04:03:12PM +0100, ext Gustavo F. Padovan wrote:
> > It also have to change the name of the function to
> > l2cap_get_sock_by_addr() because we do hold the lock inside it now.
> >
> > Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> > ---
> > net/bluetooth/l2cap.c | 17 ++++++-----------
> > 1 files changed, 6 insertions(+), 11 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> > index 6f931cc..3d48867 100644
> > --- a/net/bluetooth/l2cap.c
> > +++ b/net/bluetooth/l2cap.c
> > @@ -728,15 +728,18 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
> > }
> >
> > /* ---- Socket interface ---- */
> > -static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
> > +static struct sock *l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
> > {
> > struct sock *sk;
> > struct hlist_node *node;
> > +
> > + write_lock_bh(&l2cap_sk_list.lock);
>
> Code is only reading so read_lock_bh would be enough?
Sure, I didn't looked to that, I just keept the same code that we were
using before. I'll fix it.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 7/7] Bluetooth: Fix not returning proper error in RFCOMM
From: Gustavo F. Padovan @ 2010-11-05 14:26 UTC (permalink / raw)
To: Ville Tervo; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20101105140158.GE19903@null>
Hi Ville,
* Ville Tervo <ville.tervo@nokia.com> [2010-11-05 16:01:58 +0200]:
> Hi Gustavo,
>
> On Tue, Nov 02, 2010 at 04:03:18PM +0100, ext Gustavo F. Padovan wrote:
> > Return 0 in that situation could lead to errors in the caller.
> >
> > Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> > ---
> > net/bluetooth/rfcomm/sock.c | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
> > index e48fbca..cd7e27a 100644
> > --- a/net/bluetooth/rfcomm/sock.c
> > +++ b/net/bluetooth/rfcomm/sock.c
> > @@ -930,7 +930,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
> > /* Check if we have socket listening on channel */
> > parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
> > if (!parent)
> > - return 0;
> > + return -EINVAL;
>
> Did you check rfcomm/core.c?
>
> I think this change breaks the logic in there. IOW continues connection
> establisment instead of tearing down the link.
I understood that part of the code wrong, I'm going to drop this patch.
Thanks fo looking into this.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox