2021-06-18 03:08:21

by Miao-chen Chou

[permalink] [raw]
Subject: [BlueZ PATCH v1 0/3] Detailed error code

Hi BlueZ maintainers,

Chromium OS has been working closely with Linux Bluetooth community to
improve BlueZ stack, and there are increasing needs from applications
building their features around Bluetooth. One of the major feedback
from these application is the lack of the detailed failure reasons as
return for D-Bus method call, and these failure reasons can be used in
metrics, optimizing retry mechanism, hinting the reproduce scenario to
improve BlueZ stack. The current org.bluez.Error.* are serving the
generic errors well. However,g given org.bluez.Error.* errors are used
across different interface context which does not serve the detailed
failure reasons well. (See https://github.com/bluez/bluez/issues/131)


Miao-chen Chou (3):
BR/EDR and LE connection failure reasons
Include BtdError code in Connect() return
Print error code for connect methods

client/main.c | 3 +-
src/device.c | 52 +++++++++------
src/error.c | 124 ++++++++++++++++++++++++++++++++++++
src/error.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 331 insertions(+), 19 deletions(-)

--
2.32.0.288.g62a8d224e6-goog


2021-06-18 03:08:21

by Miao-chen Chou

[permalink] [raw]
Subject: [BlueZ PATCH v1 1/3] error: BR/EDR and LE connection failure reasons

The source of Connect() failures can be divided into the following
three.
- bluetoothd's device interface state transition and profile state
transition
- Kernel's L2CAP layer state transition
- Potential HCI error codes returned by the remote device

Reviewed-by: Alain Michaud <[email protected]>
Reviewed-by: Howard Chung <[email protected]>
---

src/error.c | 124 +++++++++++++++++++++++++++++++++++++
src/error.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 295 insertions(+)

diff --git a/src/error.c b/src/error.c
index 89517075e..b72e3d764 100644
--- a/src/error.c
+++ b/src/error.c
@@ -27,6 +27,7 @@
#include <config.h>
#endif

+#include <stdio.h>
#include "gdbus/gdbus.h"

#include "error.h"
@@ -43,6 +44,15 @@ DBusMessage *btd_error_invalid_args_str(DBusMessage *msg, const char *str)
"%s", str);
}

+DBusMessage *btd_error_invalid_args_err(DBusMessage *msg, uint16_t err)
+{
+ char str[16];
+
+ sprintf(str, "BtdError:0x%04X", err);
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
+ "%s", str);
+}
+
DBusMessage *btd_error_busy(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
@@ -79,12 +89,30 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg)
"In Progress");
}

+DBusMessage *btd_error_in_progress_err(DBusMessage *msg, uint16_t err)
+{
+ char str[16];
+
+ sprintf(str, "BtdError:0x%04X", err);
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", "%s",
+ str);
+}
+
DBusMessage *btd_error_not_available(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
"Operation currently not available");
}

+DBusMessage *btd_error_not_available_err(DBusMessage *msg, uint16_t err)
+{
+ char str[16];
+
+ sprintf(str, "BtdError:0x%04X", err);
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable", "%s",
+ str);
+}
+
DBusMessage *btd_error_does_not_exist(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
@@ -121,8 +149,104 @@ DBusMessage *btd_error_not_ready(DBusMessage *msg)
"Resource Not Ready");
}

+DBusMessage *btd_error_not_ready_err(DBusMessage *msg, uint16_t err)
+{
+ char str[16];
+
+ sprintf(str, "BtdError:0x%04X", err);
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady", "%s", str);
+}
+
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
{
return g_dbus_create_error(msg, ERROR_INTERFACE
".Failed", "%s", str);
}
+
+DBusMessage *btd_error_failed_err(DBusMessage *msg, uint16_t err)
+{
+ char str[16];
+
+ sprintf(str, "BtdError:0x%04X", err);
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", str);
+}
+
+uint16_t btd_error_bredr_conn_from_errno(int errno_code)
+{
+ switch (-errno_code) {
+ case EALREADY:
+ case EISCONN: // Fall through
+ return BTD_ERR_BREDR_CONN_ALREADY_CONNECTED;
+ case EHOSTDOWN:
+ return BTD_ERR_BREDR_CONN_PAGE_TIMEOUT;
+ case ENOPROTOOPT:
+ return BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE;
+ case EIO:
+ return BTD_ERR_BREDR_CONN_CREATE_SOCKET;
+ case EINVAL:
+ return BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS;
+ case EHOSTUNREACH:
+ return BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED;
+ case EOPNOTSUPP:
+ case EPROTONOSUPPORT: // Fall through
+ return BTD_ERR_BREDR_CONN_NOT_SUPPORTED;
+ case EBADFD:
+ return BTD_ERR_BREDR_CONN_BAD_SOCKET;
+ case ENOMEM:
+ return BTD_ERR_BREDR_CONN_MEMORY_ALLOC;
+ case EBUSY:
+ return BTD_ERR_BREDR_CONN_BUSY;
+ case EMLINK:
+ return BTD_ERR_BREDR_CONN_SYNC_CONNECT_LIMIT;
+ case ETIMEDOUT:
+ return BTD_ERR_BREDR_CONN_TIMEOUT;
+ case ECONNREFUSED:
+ return BTD_ERR_BREDR_CONN_REFUSED;
+ case ECONNRESET:
+ return BTD_ERR_BREDR_CONN_TERM_BY_REMOTE;
+ case ECONNABORTED:
+ return BTD_ERR_BREDR_CONN_TERM_BY_LOCAL;
+ case EPROTO:
+ return BTD_ERR_BREDR_CONN_PROTO_ERROR;
+ default:
+ return BTD_ERR_BREDR_CONN_UNKNOWN;
+ }
+}
+
+uint16_t btd_error_le_conn_from_errno(int errno_code)
+{
+ switch (-errno_code) {
+ case EINVAL:
+ return BTD_ERR_LE_CONN_INVALID_ARGUMENTS;
+ case EHOSTUNREACH:
+ return BTD_ERR_LE_CONN_ADAPTER_NOT_POWERED;
+ case EOPNOTSUPP:
+ case EPROTONOSUPPORT: // Fall through
+ return BTD_ERR_LE_CONN_NOT_SUPPORTED;
+ case EALREADY:
+ case EISCONN: // Fall through
+ return BTD_ERR_LE_CONN_ALREADY_CONNECTED;
+ case EBADFD:
+ return BTD_ERR_LE_CONN_BAD_SOCKET;
+ case ENOMEM:
+ return BTD_ERR_LE_CONN_MEMORY_ALLOC;
+ case EBUSY:
+ return BTD_ERR_LE_CONN_BUSY;
+ case ECONNREFUSED:
+ return BTD_ERR_LE_CONN_REFUSED;
+ case EIO:
+ return BTD_ERR_LE_CONN_CREATE_SOCKET;
+ case ETIMEDOUT:
+ return BTD_ERR_LE_CONN_TIMEOUT;
+ case EMLINK:
+ return BTD_ERR_LE_CONN_SYNC_CONNECT_LIMIT;
+ case ECONNRESET:
+ return BTD_ERR_LE_CONN_TERM_BY_REMOTE;
+ case ECONNABORTED:
+ return BTD_ERR_LE_CONN_TERM_BY_LOCAL;
+ case EPROTO:
+ return BTD_ERR_LE_CONN_PROTO_ERROR;
+ default:
+ return BTD_ERR_LE_CONN_UNKNOWN;
+ }
+}
diff --git a/src/error.h b/src/error.h
index 7c8cad066..f258cc4e7 100644
--- a/src/error.h
+++ b/src/error.h
@@ -24,22 +24,193 @@
*/

#include <dbus/dbus.h>
+#include <stdint.h>

#define ERROR_INTERFACE "org.bluez.Error"

+/* BR/EDR connection failure reasons
+ * BT_ERR_* should be used as one of the parameters to btd_error_*_err().
+ */
+
+/* Either the profile is already connected or ACL connection is in
+ * place.
+ * errno: EALREADY, EISCONN
+ */
+#define BTD_ERR_BREDR_CONN_ALREADY_CONNECTED 0x0001
+/* Failed due to page timeout.
+ * errno: EHOSTDOWN
+ */
+#define BTD_ERR_BREDR_CONN_PAGE_TIMEOUT 0x0002
+/* Failed to find connectable services or the target service.
+ * errno: ENOPROTOOPT
+ */
+#define BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE 0x0003
+/* Failed to complete the SDP search.
+ * errno: none
+ */
+#define BTD_ERR_BREDR_CONN_SDP_SEARCH 0x0004
+/* Failed to create or connect to BT IO socket. This can also indicate
+ * hardware failure in the controller.
+ * errno: EIO
+ */
+#define BTD_ERR_BREDR_CONN_CREATE_SOCKET 0x0005
+/* Failed due to invalid arguments.
+ * errno: EINVAL
+ */
+#define BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS 0x0006
+/* Failed due to adapter not powered.
+ * errno: EHOSTUNREACH
+ */
+#define BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED 0x0007
+/* Failed due to unsupported state transition of L2CAP channel or other
+ * features either by the local host or the remote.
+ * errno: EOPNOTSUPP, EPROTONOSUPPORT
+ */
+#define BTD_ERR_BREDR_CONN_NOT_SUPPORTED 0x0008
+/* Failed due to the socket is in bad state.
+ * errno: EBADFD
+ */
+#define BTD_ERR_BREDR_CONN_BAD_SOCKET 0x0009
+/* Failed to allocate memory in either host stack or controller.
+ * errno: ENOMEM
+ */
+#define BTD_ERR_BREDR_CONN_MEMORY_ALLOC 0x000A
+/* Failed due to other ongoing operations, such as pairing, busy L2CAP
+ * channel or the operation disallowed by the controller.
+ * errno: EBUSY
+ */
+#define BTD_ERR_BREDR_CONN_BUSY 0x000B
+/* Failed due to reaching the synchronous connection limit to a device.
+ * errno: EMLINK
+ */
+#define BTD_ERR_BREDR_CONN_SYNC_CONNECT_LIMIT 0x000C
+/* Failed due to connection timeout
+ * errno: ETIMEDOUT
+ */
+#define BTD_ERR_BREDR_CONN_TIMEOUT 0x000D
+/* Refused by the remote device due to limited resource, security reason
+ * or unacceptable address type.
+ * errno: ECONNREFUSED
+ */
+#define BTD_ERR_BREDR_CONN_REFUSED 0x000E
+/* Terminated by the remote device due to limited resource or power
+ * off.
+ * errno: ECONNRESET
+ */
+#define BTD_ERR_BREDR_CONN_TERM_BY_REMOTE 0x000F
+/* Terminated by the local host.
+ * errno: ECONNABORTED
+ */
+#define BTD_ERR_BREDR_CONN_TERM_BY_LOCAL 0x0010
+/* Failed due to LMP protocol error.
+ * errno: EPROTO
+ */
+#define BTD_ERR_BREDR_CONN_PROTO_ERROR 0x0011
+/* Failed due to cancellation caused by adapter drop, unexpected device drop,
+ * or incoming disconnection request before connection request is completed.
+ * errno: none
+ */
+#define BTD_ERR_BREDR_CONN_CANCELED 0x0012
+/* Failed due to unknown reason.
+ * errno: ENOSYS
+ */
+#define BTD_ERR_BREDR_CONN_UNKNOWN 0x0013
+
+/* LE connection failure reasons
+ * BT_ERR_* should be used as one of the parameters to btd_error_*_err().
+ */
+
+/* Failed due to invalid arguments.
+ * errno: EINVAL
+ */
+#define BTD_ERR_LE_CONN_INVALID_ARGUMENTS 0x0101
+/* Failed due to adapter not powered.
+ * errno: EHOSTUNREACH
+ */
+#define BTD_ERR_LE_CONN_ADAPTER_NOT_POWERED 0x0102
+/* Failed due to unsupported state transition of L2CAP channel or other
+ * features (e.g. LE features) either by the local host or the remote.
+ * errno: EOPNOTSUPP, EPROTONOSUPPORT
+ */
+#define BTD_ERR_LE_CONN_NOT_SUPPORTED 0x0103
+/* Either the BT IO is already connected or LE link connection in place.
+ * errno: EALREADY, EISCONN
+ */
+#define BTD_ERR_LE_CONN_ALREADY_CONNECTED 0x0104
+/* Failed due to the socket is in bad state.
+ * errno: EBADFD
+ */
+#define BTD_ERR_LE_CONN_BAD_SOCKET 0x0105
+/* Failed to allocate memory in either host stack or controller.
+ * errno: ENOMEM
+ */
+#define BTD_ERR_LE_CONN_MEMORY_ALLOC 0x0106
+/* Failed due to other ongoing operations, such as pairing, connecting, busy
+ * L2CAP channel or the operation disallowed by the controller.
+ * errno: EBUSY
+ */
+#define BTD_ERR_LE_CONN_BUSY 0x0107
+/* Failed due to that LE is not enabled or the attempt is refused by the remote
+ * device due to limited resource, security reason or unacceptable address type.
+ * errno: ECONNREFUSED
+ */
+#define BTD_ERR_LE_CONN_REFUSED 0x0108
+/* Failed to create or connect to BT IO socket. This can also indicate
+ * hardware failure in the controller.
+ * errno: EIO
+ */
+#define BTD_ERR_LE_CONN_CREATE_SOCKET 0x0109
+/* Failed due to connection timeout
+ * errno: ETIMEDOUT
+ */
+#define BTD_ERR_LE_CONN_TIMEOUT 0x010A
+/* Failed due to reaching the synchronous connection limit to a device.
+ * errno: EMLINK
+ */
+#define BTD_ERR_LE_CONN_SYNC_CONNECT_LIMIT 0x010B
+/* Terminated by the remote device due to limited resource or power
+ * off.
+ * errno: ECONNRESET
+ */
+#define BTD_ERR_LE_CONN_TERM_BY_REMOTE 0x010C
+/* Terminated by the local host.
+ * errno: ECONNABORTED
+ */
+#define BTD_ERR_LE_CONN_TERM_BY_LOCAL 0x010D
+/* Failed due to LL protocol error.
+ * errno: EPROTO
+ */
+#define BTD_ERR_LE_CONN_PROTO_ERROR 0x010E
+/* Failed to complete the GATT browsing.
+ * errno: none
+ */
+#define BTD_ERR_LE_CONN_GATT_BROWSE 0x010F
+/* Failed due to unknown reason.
+ * errno: ENOSYS
+ */
+#define BTD_ERR_LE_CONN_UNKNOWN 0x0110
+
DBusMessage *btd_error_invalid_args(DBusMessage *msg);
DBusMessage *btd_error_invalid_args_str(DBusMessage *msg, const char *str);
+DBusMessage *btd_error_invalid_args_err(DBusMessage *msg, uint16_t err);
DBusMessage *btd_error_busy(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_already_connected(DBusMessage *msg);
DBusMessage *btd_error_not_available(DBusMessage *msg);
+DBusMessage *btd_error_not_available_err(DBusMessage *msg, uint16_t err);
DBusMessage *btd_error_in_progress(DBusMessage *msg);
+DBusMessage *btd_error_in_progress_err(DBusMessage *msg, uint16_t err);
DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
DBusMessage *btd_error_not_authorized(DBusMessage *msg);
DBusMessage *btd_error_not_permitted(DBusMessage *msg, const char *str);
DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
DBusMessage *btd_error_agent_not_available(DBusMessage *msg);
DBusMessage *btd_error_not_ready(DBusMessage *msg);
+DBusMessage *btd_error_not_ready_err(DBusMessage *msg, uint16_t err);
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
+DBusMessage *btd_error_failed_err(DBusMessage *msg, uint16_t err);
+
+uint16_t btd_error_bredr_conn_from_errno(int errno_code);
+uint16_t btd_error_le_conn_from_errno(int errno_code);
--
2.32.0.288.g62a8d224e6-goog

2021-06-18 03:10:54

by Miao-chen Chou

[permalink] [raw]
Subject: [BlueZ PATCH v1 2/3] device: Include BtdError code in Connect() return

This replaces generic strerror message with context specific BtdError
code to better indicate the detailed failure reason so that the D-Bus
clients can optimize their application to work better with BlueZ, e.g.
introducing retry mechanism or building metrics.

Reviewed-by: Alain Michaud <[email protected]>
Reviewed-by: Howard Chung <[email protected]>
---

src/device.c | 52 ++++++++++++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/src/device.c b/src/device.c
index df440ce09..c9dc616a2 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1607,8 +1607,8 @@ void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
}

if (device->connect) {
- DBusMessage *reply = btd_error_failed(device->connect,
- "Cancelled");
+ DBusMessage *reply = btd_error_failed_err(device->connect,
+ BTD_ERR_BREDR_CONN_CANCELED);
g_dbus_send_message(dbus_conn, reply);
dbus_message_unref(device->connect);
device->connect = NULL;
@@ -1802,7 +1802,8 @@ done:
}

g_dbus_send_message(dbus_conn,
- btd_error_failed(dev->connect, strerror(-err)));
+ btd_error_failed_err(dev->connect,
+ btd_error_bredr_conn_from_errno(err)));
} else {
/* Start passive SDP discovery to update known services */
if (dev->bredr && !dev->svc_refreshed && dev->refresh_discovery)
@@ -2003,10 +2004,12 @@ static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type
dbus_message_get_sender(msg));

if (dev->pending || dev->connect || dev->browse)
- return btd_error_in_progress(msg);
+ return btd_error_in_progress_err(msg, BTD_ERR_BREDR_CONN_BUSY);

- if (!btd_adapter_get_powered(dev->adapter))
- return btd_error_not_ready(msg);
+ if (!btd_adapter_get_powered(dev->adapter)) {
+ return btd_error_not_ready_err(msg,
+ BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED);
+ }

btd_device_set_temporary(dev, false);

@@ -2019,10 +2022,12 @@ static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type
if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
"Connect") &&
find_service_with_state(dev->services,
- BTD_SERVICE_STATE_CONNECTED))
+ BTD_SERVICE_STATE_CONNECTED)) {
return dbus_message_new_method_return(msg);
- else
- return btd_error_not_available(msg);
+ } else {
+ return btd_error_not_available_err(msg,
+ BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE);
+ }
}

goto resolve_services;
@@ -2032,7 +2037,8 @@ static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type
if (err < 0) {
if (err == -EALREADY)
return dbus_message_new_method_return(msg);
- return btd_error_failed(msg, strerror(-err));
+ return btd_error_failed_err(msg,
+ btd_error_bredr_conn_from_errno(err));
}

dev->connect = dbus_message_ref(msg);
@@ -2046,8 +2052,11 @@ resolve_services:
err = device_browse_sdp(dev, msg);
else
err = device_browse_gatt(dev, msg);
- if (err < 0)
- return btd_error_failed(msg, strerror(-err));
+ if (err < 0) {
+ return btd_error_failed_err(msg, bdaddr_type == BDADDR_BREDR ?
+ BTD_ERR_BREDR_CONN_SDP_SEARCH :
+ BTD_ERR_LE_CONN_GATT_BROWSE);
+ }

return NULL;
}
@@ -2157,8 +2166,10 @@ static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
DBusMessage *reply;

if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
- DBUS_TYPE_INVALID))
- return btd_error_invalid_args(msg);
+ DBUS_TYPE_INVALID)) {
+ return btd_error_invalid_args_err(msg,
+ BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS);
+ }

uuid = bt_name2string(pattern);
reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
@@ -2541,7 +2552,11 @@ static void browse_request_complete(struct browse_req *req, uint8_t type,
if (err == 0)
goto done;
}
- reply = btd_error_failed(req->msg, strerror(-err));
+ reply = (bdaddr_type == BDADDR_BREDR ?
+ btd_error_failed_err(req->msg,
+ btd_error_bredr_conn_from_errno(err)) :
+ btd_error_failed_err(req->msg,
+ btd_error_le_conn_from_errno(err)));
goto done;
}

@@ -3027,7 +3042,8 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
*/
if (device->connect) {
DBG("connection removed while Connect() is waiting reply");
- reply = btd_error_failed(device->connect, "Disconnected early");
+ reply = btd_error_failed_err(device->connect,
+ BTD_ERR_BREDR_CONN_CANCELED);
g_dbus_send_message(dbus_conn, reply);
dbus_message_unref(device->connect);
device->connect = NULL;
@@ -5413,8 +5429,8 @@ done:

if (device->connect) {
if (err < 0)
- reply = btd_error_failed(device->connect,
- strerror(-err));
+ reply = btd_error_failed_err(device->connect,
+ btd_error_le_conn_from_errno(err));
else
reply = dbus_message_new_method_return(device->connect);

--
2.32.0.288.g62a8d224e6-goog

2021-06-18 03:31:38

by bluez.test.bot

[permalink] [raw]
Subject: RE: Detailed error code

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=502869

---Test result---

Test Summary:
CheckPatch FAIL 1.22 seconds
GitLint PASS 0.42 seconds
Prep - Setup ELL PASS 49.88 seconds
Build - Prep PASS 0.17 seconds
Build - Configure PASS 9.15 seconds
Build - Make FAIL 190.37 seconds
Make Check FAIL 0.62 seconds
Make Distcheck FAIL 174.13 seconds
Build w/ext ELL - Configure PASS 8.79 seconds
Build w/ext ELL - Make FAIL 174.89 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script with rule in .checkpatch.conf
Output:
error: BR/EDR and LE connection failure reasons
WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment
#105: FILE: src/error.c:165:
+ case EISCONN: // Fall through

WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment
#118: FILE: src/error.c:178:
+ case EPROTONOSUPPORT: // Fall through

WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment
#151: FILE: src/error.c:211:
+ case EPROTONOSUPPORT: // Fall through

WARNING:PREFER_FALLTHROUGH: Prefer 'fallthrough;' over fallthrough comment
#154: FILE: src/error.c:214:
+ case EISCONN: // Fall through

- total: 0 errors, 4 warnings, 349 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

"[PATCH] error: BR/EDR and LE connection failure reasons" has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - PASS
Desc: Run gitlint with rule in .gitlint

##############################
Test: Prep - Setup ELL - PASS
Desc: Clone, build, and install ELL

##############################
Test: Build - Prep - PASS
Desc: Prepare environment for build

##############################
Test: Build - Configure - PASS
Desc: Configure the BlueZ source tree

##############################
Test: Build - Make - FAIL
Desc: Build the BlueZ source tree
Output:
src/error.c: In function ‘btd_error_bredr_conn_from_errno’:
src/error.c:164:7: error: ‘EALREADY’ undeclared (first use in this function)
164 | case EALREADY:
| ^~~~~~~~
src/error.c:164:7: note: each undeclared identifier is reported only once for each function it appears in
src/error.c:165:7: error: ‘EISCONN’ undeclared (first use in this function)
165 | case EISCONN: // Fall through
| ^~~~~~~
src/error.c:167:7: error: ‘EHOSTDOWN’ undeclared (first use in this function)
167 | case EHOSTDOWN:
| ^~~~~~~~~
src/error.c:169:7: error: ‘ENOPROTOOPT’ undeclared (first use in this function)
169 | case ENOPROTOOPT:
| ^~~~~~~~~~~
src/error.c:171:7: error: ‘EIO’ undeclared (first use in this function)
171 | case EIO:
| ^~~
src/error.c:173:7: error: ‘EINVAL’ undeclared (first use in this function)
173 | case EINVAL:
| ^~~~~~
src/error.c:175:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
175 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
src/error.c:177:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
177 | case EOPNOTSUPP:
| ^~~~~~~~~~
src/error.c:178:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
178 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
src/error.c:180:7: error: ‘EBADFD’ undeclared (first use in this function)
180 | case EBADFD:
| ^~~~~~
src/error.c:182:7: error: ‘ENOMEM’ undeclared (first use in this function)
182 | case ENOMEM:
| ^~~~~~
src/error.c:184:7: error: ‘EBUSY’ undeclared (first use in this function)
184 | case EBUSY:
| ^~~~~
src/error.c:186:7: error: ‘EMLINK’ undeclared (first use in this function)
186 | case EMLINK:
| ^~~~~~
src/error.c:188:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
188 | case ETIMEDOUT:
| ^~~~~~~~~
src/error.c:190:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
190 | case ECONNREFUSED:
| ^~~~~~~~~~~~
src/error.c:192:7: error: ‘ECONNRESET’ undeclared (first use in this function)
192 | case ECONNRESET:
| ^~~~~~~~~~
src/error.c:194:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
194 | case ECONNABORTED:
| ^~~~~~~~~~~~
src/error.c:196:7: error: ‘EPROTO’ undeclared (first use in this function)
196 | case EPROTO:
| ^~~~~~
src/error.c: In function ‘btd_error_le_conn_from_errno’:
src/error.c:206:7: error: ‘EINVAL’ undeclared (first use in this function)
206 | case EINVAL:
| ^~~~~~
src/error.c:208:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
208 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
src/error.c:210:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
210 | case EOPNOTSUPP:
| ^~~~~~~~~~
src/error.c:211:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
211 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
src/error.c:213:7: error: ‘EALREADY’ undeclared (first use in this function)
213 | case EALREADY:
| ^~~~~~~~
src/error.c:214:7: error: ‘EISCONN’ undeclared (first use in this function)
214 | case EISCONN: // Fall through
| ^~~~~~~
src/error.c:216:7: error: ‘EBADFD’ undeclared (first use in this function)
216 | case EBADFD:
| ^~~~~~
src/error.c:218:7: error: ‘ENOMEM’ undeclared (first use in this function)
218 | case ENOMEM:
| ^~~~~~
src/error.c:220:7: error: ‘EBUSY’ undeclared (first use in this function)
220 | case EBUSY:
| ^~~~~
src/error.c:222:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
222 | case ECONNREFUSED:
| ^~~~~~~~~~~~
src/error.c:224:7: error: ‘EIO’ undeclared (first use in this function)
224 | case EIO:
| ^~~
src/error.c:226:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
226 | case ETIMEDOUT:
| ^~~~~~~~~
src/error.c:228:7: error: ‘EMLINK’ undeclared (first use in this function)
228 | case EMLINK:
| ^~~~~~
src/error.c:230:7: error: ‘ECONNRESET’ undeclared (first use in this function)
230 | case ECONNRESET:
| ^~~~~~~~~~
src/error.c:232:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
232 | case ECONNABORTED:
| ^~~~~~~~~~~~
src/error.c:234:7: error: ‘EPROTO’ undeclared (first use in this function)
234 | case EPROTO:
| ^~~~~~
make[1]: *** [Makefile:9301: src/bluetoothd-error.o] Error 1
make: *** [Makefile:4134: all] Error 2


##############################
Test: Make Check - FAIL
Desc: Run 'make check'
Output:
src/error.c: In function ‘btd_error_bredr_conn_from_errno’:
src/error.c:164:7: error: ‘EALREADY’ undeclared (first use in this function)
164 | case EALREADY:
| ^~~~~~~~
src/error.c:164:7: note: each undeclared identifier is reported only once for each function it appears in
src/error.c:165:7: error: ‘EISCONN’ undeclared (first use in this function)
165 | case EISCONN: // Fall through
| ^~~~~~~
src/error.c:167:7: error: ‘EHOSTDOWN’ undeclared (first use in this function)
167 | case EHOSTDOWN:
| ^~~~~~~~~
src/error.c:169:7: error: ‘ENOPROTOOPT’ undeclared (first use in this function)
169 | case ENOPROTOOPT:
| ^~~~~~~~~~~
src/error.c:171:7: error: ‘EIO’ undeclared (first use in this function)
171 | case EIO:
| ^~~
src/error.c:173:7: error: ‘EINVAL’ undeclared (first use in this function)
173 | case EINVAL:
| ^~~~~~
src/error.c:175:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
175 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
src/error.c:177:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
177 | case EOPNOTSUPP:
| ^~~~~~~~~~
src/error.c:178:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
178 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
src/error.c:180:7: error: ‘EBADFD’ undeclared (first use in this function)
180 | case EBADFD:
| ^~~~~~
src/error.c:182:7: error: ‘ENOMEM’ undeclared (first use in this function)
182 | case ENOMEM:
| ^~~~~~
src/error.c:184:7: error: ‘EBUSY’ undeclared (first use in this function)
184 | case EBUSY:
| ^~~~~
src/error.c:186:7: error: ‘EMLINK’ undeclared (first use in this function)
186 | case EMLINK:
| ^~~~~~
src/error.c:188:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
188 | case ETIMEDOUT:
| ^~~~~~~~~
src/error.c:190:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
190 | case ECONNREFUSED:
| ^~~~~~~~~~~~
src/error.c:192:7: error: ‘ECONNRESET’ undeclared (first use in this function)
192 | case ECONNRESET:
| ^~~~~~~~~~
src/error.c:194:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
194 | case ECONNABORTED:
| ^~~~~~~~~~~~
src/error.c:196:7: error: ‘EPROTO’ undeclared (first use in this function)
196 | case EPROTO:
| ^~~~~~
src/error.c: In function ‘btd_error_le_conn_from_errno’:
src/error.c:206:7: error: ‘EINVAL’ undeclared (first use in this function)
206 | case EINVAL:
| ^~~~~~
src/error.c:208:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
208 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
src/error.c:210:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
210 | case EOPNOTSUPP:
| ^~~~~~~~~~
src/error.c:211:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
211 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
src/error.c:213:7: error: ‘EALREADY’ undeclared (first use in this function)
213 | case EALREADY:
| ^~~~~~~~
src/error.c:214:7: error: ‘EISCONN’ undeclared (first use in this function)
214 | case EISCONN: // Fall through
| ^~~~~~~
src/error.c:216:7: error: ‘EBADFD’ undeclared (first use in this function)
216 | case EBADFD:
| ^~~~~~
src/error.c:218:7: error: ‘ENOMEM’ undeclared (first use in this function)
218 | case ENOMEM:
| ^~~~~~
src/error.c:220:7: error: ‘EBUSY’ undeclared (first use in this function)
220 | case EBUSY:
| ^~~~~
src/error.c:222:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
222 | case ECONNREFUSED:
| ^~~~~~~~~~~~
src/error.c:224:7: error: ‘EIO’ undeclared (first use in this function)
224 | case EIO:
| ^~~
src/error.c:226:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
226 | case ETIMEDOUT:
| ^~~~~~~~~
src/error.c:228:7: error: ‘EMLINK’ undeclared (first use in this function)
228 | case EMLINK:
| ^~~~~~
src/error.c:230:7: error: ‘ECONNRESET’ undeclared (first use in this function)
230 | case ECONNRESET:
| ^~~~~~~~~~
src/error.c:232:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
232 | case ECONNABORTED:
| ^~~~~~~~~~~~
src/error.c:234:7: error: ‘EPROTO’ undeclared (first use in this function)
234 | case EPROTO:
| ^~~~~~
make[1]: *** [Makefile:9301: src/bluetoothd-error.o] Error 1
make: *** [Makefile:10406: check] Error 2


##############################
Test: Make Distcheck - FAIL
Desc: Run distcheck to check the distribution
Output:
../../src/error.c: In function ‘btd_error_bredr_conn_from_errno’:
../../src/error.c:164:7: error: ‘EALREADY’ undeclared (first use in this function)
164 | case EALREADY:
| ^~~~~~~~
../../src/error.c:164:7: note: each undeclared identifier is reported only once for each function it appears in
../../src/error.c:165:7: error: ‘EISCONN’ undeclared (first use in this function)
165 | case EISCONN: // Fall through
| ^~~~~~~
../../src/error.c:167:7: error: ‘EHOSTDOWN’ undeclared (first use in this function)
167 | case EHOSTDOWN:
| ^~~~~~~~~
../../src/error.c:169:7: error: ‘ENOPROTOOPT’ undeclared (first use in this function)
169 | case ENOPROTOOPT:
| ^~~~~~~~~~~
../../src/error.c:171:7: error: ‘EIO’ undeclared (first use in this function)
171 | case EIO:
| ^~~
../../src/error.c:173:7: error: ‘EINVAL’ undeclared (first use in this function)
173 | case EINVAL:
| ^~~~~~
../../src/error.c:175:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
175 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
../../src/error.c:177:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
177 | case EOPNOTSUPP:
| ^~~~~~~~~~
../../src/error.c:178:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
178 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
../../src/error.c:180:7: error: ‘EBADFD’ undeclared (first use in this function)
180 | case EBADFD:
| ^~~~~~
../../src/error.c:182:7: error: ‘ENOMEM’ undeclared (first use in this function)
182 | case ENOMEM:
| ^~~~~~
../../src/error.c:184:7: error: ‘EBUSY’ undeclared (first use in this function)
184 | case EBUSY:
| ^~~~~
../../src/error.c:186:7: error: ‘EMLINK’ undeclared (first use in this function)
186 | case EMLINK:
| ^~~~~~
../../src/error.c:188:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
188 | case ETIMEDOUT:
| ^~~~~~~~~
../../src/error.c:190:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
190 | case ECONNREFUSED:
| ^~~~~~~~~~~~
../../src/error.c:192:7: error: ‘ECONNRESET’ undeclared (first use in this function)
192 | case ECONNRESET:
| ^~~~~~~~~~
../../src/error.c:194:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
194 | case ECONNABORTED:
| ^~~~~~~~~~~~
../../src/error.c:196:7: error: ‘EPROTO’ undeclared (first use in this function)
196 | case EPROTO:
| ^~~~~~
../../src/error.c: In function ‘btd_error_le_conn_from_errno’:
../../src/error.c:206:7: error: ‘EINVAL’ undeclared (first use in this function)
206 | case EINVAL:
| ^~~~~~
../../src/error.c:208:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
208 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
../../src/error.c:210:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
210 | case EOPNOTSUPP:
| ^~~~~~~~~~
../../src/error.c:211:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
211 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
../../src/error.c:213:7: error: ‘EALREADY’ undeclared (first use in this function)
213 | case EALREADY:
| ^~~~~~~~
../../src/error.c:214:7: error: ‘EISCONN’ undeclared (first use in this function)
214 | case EISCONN: // Fall through
| ^~~~~~~
../../src/error.c:216:7: error: ‘EBADFD’ undeclared (first use in this function)
216 | case EBADFD:
| ^~~~~~
../../src/error.c:218:7: error: ‘ENOMEM’ undeclared (first use in this function)
218 | case ENOMEM:
| ^~~~~~
../../src/error.c:220:7: error: ‘EBUSY’ undeclared (first use in this function)
220 | case EBUSY:
| ^~~~~
../../src/error.c:222:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
222 | case ECONNREFUSED:
| ^~~~~~~~~~~~
../../src/error.c:224:7: error: ‘EIO’ undeclared (first use in this function)
224 | case EIO:
| ^~~
../../src/error.c:226:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
226 | case ETIMEDOUT:
| ^~~~~~~~~
../../src/error.c:228:7: error: ‘EMLINK’ undeclared (first use in this function)
228 | case EMLINK:
| ^~~~~~
../../src/error.c:230:7: error: ‘ECONNRESET’ undeclared (first use in this function)
230 | case ECONNRESET:
| ^~~~~~~~~~
../../src/error.c:232:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
232 | case ECONNABORTED:
| ^~~~~~~~~~~~
../../src/error.c:234:7: error: ‘EPROTO’ undeclared (first use in this function)
234 | case EPROTO:
| ^~~~~~
make[2]: *** [Makefile:9301: src/bluetoothd-error.o] Error 1
make[1]: *** [Makefile:4134: all] Error 2
make: *** [Makefile:10327: distcheck] Error 1


##############################
Test: Build w/ext ELL - Configure - PASS
Desc: Configure BlueZ source with '--enable-external-ell' configuration

##############################
Test: Build w/ext ELL - Make - FAIL
Desc: Build BlueZ source with '--enable-external-ell' configuration
Output:
src/error.c: In function ‘btd_error_bredr_conn_from_errno’:
src/error.c:164:7: error: ‘EALREADY’ undeclared (first use in this function)
164 | case EALREADY:
| ^~~~~~~~
src/error.c:164:7: note: each undeclared identifier is reported only once for each function it appears in
src/error.c:165:7: error: ‘EISCONN’ undeclared (first use in this function)
165 | case EISCONN: // Fall through
| ^~~~~~~
src/error.c:167:7: error: ‘EHOSTDOWN’ undeclared (first use in this function)
167 | case EHOSTDOWN:
| ^~~~~~~~~
src/error.c:169:7: error: ‘ENOPROTOOPT’ undeclared (first use in this function)
169 | case ENOPROTOOPT:
| ^~~~~~~~~~~
src/error.c:171:7: error: ‘EIO’ undeclared (first use in this function)
171 | case EIO:
| ^~~
src/error.c:173:7: error: ‘EINVAL’ undeclared (first use in this function)
173 | case EINVAL:
| ^~~~~~
src/error.c:175:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
175 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
src/error.c:177:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
177 | case EOPNOTSUPP:
| ^~~~~~~~~~
src/error.c:178:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
178 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
src/error.c:180:7: error: ‘EBADFD’ undeclared (first use in this function)
180 | case EBADFD:
| ^~~~~~
src/error.c:182:7: error: ‘ENOMEM’ undeclared (first use in this function)
182 | case ENOMEM:
| ^~~~~~
src/error.c:184:7: error: ‘EBUSY’ undeclared (first use in this function)
184 | case EBUSY:
| ^~~~~
src/error.c:186:7: error: ‘EMLINK’ undeclared (first use in this function)
186 | case EMLINK:
| ^~~~~~
src/error.c:188:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
188 | case ETIMEDOUT:
| ^~~~~~~~~
src/error.c:190:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
190 | case ECONNREFUSED:
| ^~~~~~~~~~~~
src/error.c:192:7: error: ‘ECONNRESET’ undeclared (first use in this function)
192 | case ECONNRESET:
| ^~~~~~~~~~
src/error.c:194:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
194 | case ECONNABORTED:
| ^~~~~~~~~~~~
src/error.c:196:7: error: ‘EPROTO’ undeclared (first use in this function)
196 | case EPROTO:
| ^~~~~~
src/error.c: In function ‘btd_error_le_conn_from_errno’:
src/error.c:206:7: error: ‘EINVAL’ undeclared (first use in this function)
206 | case EINVAL:
| ^~~~~~
src/error.c:208:7: error: ‘EHOSTUNREACH’ undeclared (first use in this function)
208 | case EHOSTUNREACH:
| ^~~~~~~~~~~~
src/error.c:210:7: error: ‘EOPNOTSUPP’ undeclared (first use in this function)
210 | case EOPNOTSUPP:
| ^~~~~~~~~~
src/error.c:211:7: error: ‘EPROTONOSUPPORT’ undeclared (first use in this function)
211 | case EPROTONOSUPPORT: // Fall through
| ^~~~~~~~~~~~~~~
src/error.c:213:7: error: ‘EALREADY’ undeclared (first use in this function)
213 | case EALREADY:
| ^~~~~~~~
src/error.c:214:7: error: ‘EISCONN’ undeclared (first use in this function)
214 | case EISCONN: // Fall through
| ^~~~~~~
src/error.c:216:7: error: ‘EBADFD’ undeclared (first use in this function)
216 | case EBADFD:
| ^~~~~~
src/error.c:218:7: error: ‘ENOMEM’ undeclared (first use in this function)
218 | case ENOMEM:
| ^~~~~~
src/error.c:220:7: error: ‘EBUSY’ undeclared (first use in this function)
220 | case EBUSY:
| ^~~~~
src/error.c:222:7: error: ‘ECONNREFUSED’ undeclared (first use in this function)
222 | case ECONNREFUSED:
| ^~~~~~~~~~~~
src/error.c:224:7: error: ‘EIO’ undeclared (first use in this function)
224 | case EIO:
| ^~~
src/error.c:226:7: error: ‘ETIMEDOUT’ undeclared (first use in this function)
226 | case ETIMEDOUT:
| ^~~~~~~~~
src/error.c:228:7: error: ‘EMLINK’ undeclared (first use in this function)
228 | case EMLINK:
| ^~~~~~
src/error.c:230:7: error: ‘ECONNRESET’ undeclared (first use in this function)
230 | case ECONNRESET:
| ^~~~~~~~~~
src/error.c:232:7: error: ‘ECONNABORTED’ undeclared (first use in this function)
232 | case ECONNABORTED:
| ^~~~~~~~~~~~
src/error.c:234:7: error: ‘EPROTO’ undeclared (first use in this function)
234 | case EPROTO:
| ^~~~~~
make[1]: *** [Makefile:9301: src/bluetoothd-error.o] Error 1
make: *** [Makefile:4134: all] Error 2




---
Regards,
Linux Bluetooth

2021-06-18 19:44:34

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [BlueZ PATCH v1 0/3] Detailed error code

Hi Miao,

On Thu, Jun 17, 2021 at 8:08 PM Miao-chen Chou <[email protected]> wrote:
>
> Hi BlueZ maintainers,
>
> Chromium OS has been working closely with Linux Bluetooth community to
> improve BlueZ stack, and there are increasing needs from applications
> building their features around Bluetooth. One of the major feedback
> from these application is the lack of the detailed failure reasons as
> return for D-Bus method call, and these failure reasons can be used in
> metrics, optimizing retry mechanism, hinting the reproduce scenario to
> improve BlueZ stack. The current org.bluez.Error.* are serving the
> generic errors well. However,g given org.bluez.Error.* errors are used
> across different interface context which does not serve the detailed
> failure reasons well. (See https://github.com/bluez/bluez/issues/131)

I would suggest adding some documentation on the errors e.g.
doc/error-code.txt, so we can document what are the errors and how
they are included on the reply (encoded within the error message as
string using hexadecimal values as in 0x04X, etc.), also we we want to
be crystal clear it would probably be a good idea to inform what
errors codes can appear on each Method like we do for the error
interface.

>
>
> Miao-chen Chou (3):
> BR/EDR and LE connection failure reasons
> Include BtdError code in Connect() return
> Print error code for connect methods
>
> client/main.c | 3 +-
> src/device.c | 52 +++++++++------
> src/error.c | 124 ++++++++++++++++++++++++++++++++++++
> src/error.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 331 insertions(+), 19 deletions(-)
>
> --
> 2.32.0.288.g62a8d224e6-goog
>


--
Luiz Augusto von Dentz

2021-06-18 23:07:00

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [BlueZ PATCH v1 1/3] error: BR/EDR and LE connection failure reasons

Hi Miao,

On Thu, Jun 17, 2021 at 8:08 PM Miao-chen Chou <[email protected]> wrote:
>
> The source of Connect() failures can be divided into the following
> three.
> - bluetoothd's device interface state transition and profile state
> transition
> - Kernel's L2CAP layer state transition
> - Potential HCI error codes returned by the remote device
>
> Reviewed-by: Alain Michaud <[email protected]>
> Reviewed-by: Howard Chung <[email protected]>
> ---
>
> src/error.c | 124 +++++++++++++++++++++++++++++++++++++
> src/error.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 295 insertions(+)
>
> diff --git a/src/error.c b/src/error.c
> index 89517075e..b72e3d764 100644
> --- a/src/error.c
> +++ b/src/error.c
> @@ -27,6 +27,7 @@
> #include <config.h>
> #endif
>
> +#include <stdio.h>
> #include "gdbus/gdbus.h"
>
> #include "error.h"
> @@ -43,6 +44,15 @@ DBusMessage *btd_error_invalid_args_str(DBusMessage *msg, const char *str)
> "%s", str);
> }
>
> +DBusMessage *btd_error_invalid_args_err(DBusMessage *msg, uint16_t err)
> +{
> + char str[16];
> +
> + sprintf(str, "BtdError:0x%04X", err);
> + return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
> + "%s", str);
> +}
> +
> DBusMessage *btd_error_busy(DBusMessage *msg)
> {
> return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
> @@ -79,12 +89,30 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg)
> "In Progress");
> }
>
> +DBusMessage *btd_error_in_progress_err(DBusMessage *msg, uint16_t err)
> +{
> + char str[16];
> +
> + sprintf(str, "BtdError:0x%04X", err);
> + return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", "%s",
> + str);

Was there a problem that you didn't use g_dbus_create_error to convert
the error? I mean instead of using %s use BtdError:0x%04X, actually it
might be enough to just have the code portion and skip BtdError as
that can be assumed implicitly the our error messages would contain
error codes.

> +}
> +
> DBusMessage *btd_error_not_available(DBusMessage *msg)
> {
> return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
> "Operation currently not available");
> }
>
> +DBusMessage *btd_error_not_available_err(DBusMessage *msg, uint16_t err)
> +{
> + char str[16];
> +
> + sprintf(str, "BtdError:0x%04X", err);
> + return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable", "%s",
> + str);
> +}
> +
> DBusMessage *btd_error_does_not_exist(DBusMessage *msg)
> {
> return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
> @@ -121,8 +149,104 @@ DBusMessage *btd_error_not_ready(DBusMessage *msg)
> "Resource Not Ready");
> }
>
> +DBusMessage *btd_error_not_ready_err(DBusMessage *msg, uint16_t err)
> +{
> + char str[16];
> +
> + sprintf(str, "BtdError:0x%04X", err);
> + return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady", "%s", str);
> +}
> +
> DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
> {
> return g_dbus_create_error(msg, ERROR_INTERFACE
> ".Failed", "%s", str);
> }
> +
> +DBusMessage *btd_error_failed_err(DBusMessage *msg, uint16_t err)
> +{
> + char str[16];
> +
> + sprintf(str, "BtdError:0x%04X", err);
> + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", str);
> +}
> +
> +uint16_t btd_error_bredr_conn_from_errno(int errno_code)
> +{
> + switch (-errno_code) {
> + case EALREADY:
> + case EISCONN: // Fall through
> + return BTD_ERR_BREDR_CONN_ALREADY_CONNECTED;
> + case EHOSTDOWN:
> + return BTD_ERR_BREDR_CONN_PAGE_TIMEOUT;
> + case ENOPROTOOPT:
> + return BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE;
> + case EIO:
> + return BTD_ERR_BREDR_CONN_CREATE_SOCKET;
> + case EINVAL:
> + return BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS;
> + case EHOSTUNREACH:
> + return BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED;
> + case EOPNOTSUPP:
> + case EPROTONOSUPPORT: // Fall through
> + return BTD_ERR_BREDR_CONN_NOT_SUPPORTED;
> + case EBADFD:
> + return BTD_ERR_BREDR_CONN_BAD_SOCKET;
> + case ENOMEM:
> + return BTD_ERR_BREDR_CONN_MEMORY_ALLOC;
> + case EBUSY:
> + return BTD_ERR_BREDR_CONN_BUSY;
> + case EMLINK:
> + return BTD_ERR_BREDR_CONN_SYNC_CONNECT_LIMIT;
> + case ETIMEDOUT:
> + return BTD_ERR_BREDR_CONN_TIMEOUT;
> + case ECONNREFUSED:
> + return BTD_ERR_BREDR_CONN_REFUSED;
> + case ECONNRESET:
> + return BTD_ERR_BREDR_CONN_TERM_BY_REMOTE;
> + case ECONNABORTED:
> + return BTD_ERR_BREDR_CONN_TERM_BY_LOCAL;
> + case EPROTO:
> + return BTD_ERR_BREDR_CONN_PROTO_ERROR;
> + default:
> + return BTD_ERR_BREDR_CONN_UNKNOWN;
> + }
> +}
> +
> +uint16_t btd_error_le_conn_from_errno(int errno_code)
> +{
> + switch (-errno_code) {
> + case EINVAL:
> + return BTD_ERR_LE_CONN_INVALID_ARGUMENTS;
> + case EHOSTUNREACH:
> + return BTD_ERR_LE_CONN_ADAPTER_NOT_POWERED;
> + case EOPNOTSUPP:
> + case EPROTONOSUPPORT: // Fall through
> + return BTD_ERR_LE_CONN_NOT_SUPPORTED;
> + case EALREADY:
> + case EISCONN: // Fall through
> + return BTD_ERR_LE_CONN_ALREADY_CONNECTED;
> + case EBADFD:
> + return BTD_ERR_LE_CONN_BAD_SOCKET;
> + case ENOMEM:
> + return BTD_ERR_LE_CONN_MEMORY_ALLOC;
> + case EBUSY:
> + return BTD_ERR_LE_CONN_BUSY;
> + case ECONNREFUSED:
> + return BTD_ERR_LE_CONN_REFUSED;
> + case EIO:
> + return BTD_ERR_LE_CONN_CREATE_SOCKET;
> + case ETIMEDOUT:
> + return BTD_ERR_LE_CONN_TIMEOUT;
> + case EMLINK:
> + return BTD_ERR_LE_CONN_SYNC_CONNECT_LIMIT;
> + case ECONNRESET:
> + return BTD_ERR_LE_CONN_TERM_BY_REMOTE;
> + case ECONNABORTED:
> + return BTD_ERR_LE_CONN_TERM_BY_LOCAL;
> + case EPROTO:
> + return BTD_ERR_LE_CONN_PROTO_ERROR;
> + default:
> + return BTD_ERR_LE_CONN_UNKNOWN;
> + }
> +}
> diff --git a/src/error.h b/src/error.h
> index 7c8cad066..f258cc4e7 100644
> --- a/src/error.h
> +++ b/src/error.h
> @@ -24,22 +24,193 @@
> */
>
> #include <dbus/dbus.h>
> +#include <stdint.h>
>
> #define ERROR_INTERFACE "org.bluez.Error"
>
> +/* BR/EDR connection failure reasons
> + * BT_ERR_* should be used as one of the parameters to btd_error_*_err().
> + */
> +
> +/* Either the profile is already connected or ACL connection is in
> + * place.
> + * errno: EALREADY, EISCONN
> + */
> +#define BTD_ERR_BREDR_CONN_ALREADY_CONNECTED 0x0001
> +/* Failed due to page timeout.
> + * errno: EHOSTDOWN
> + */
> +#define BTD_ERR_BREDR_CONN_PAGE_TIMEOUT 0x0002
> +/* Failed to find connectable services or the target service.
> + * errno: ENOPROTOOPT
> + */
> +#define BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE 0x0003
> +/* Failed to complete the SDP search.
> + * errno: none
> + */
> +#define BTD_ERR_BREDR_CONN_SDP_SEARCH 0x0004
> +/* Failed to create or connect to BT IO socket. This can also indicate
> + * hardware failure in the controller.
> + * errno: EIO
> + */
> +#define BTD_ERR_BREDR_CONN_CREATE_SOCKET 0x0005
> +/* Failed due to invalid arguments.
> + * errno: EINVAL
> + */
> +#define BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS 0x0006
> +/* Failed due to adapter not powered.
> + * errno: EHOSTUNREACH
> + */
> +#define BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED 0x0007
> +/* Failed due to unsupported state transition of L2CAP channel or other
> + * features either by the local host or the remote.
> + * errno: EOPNOTSUPP, EPROTONOSUPPORT
> + */
> +#define BTD_ERR_BREDR_CONN_NOT_SUPPORTED 0x0008
> +/* Failed due to the socket is in bad state.
> + * errno: EBADFD
> + */
> +#define BTD_ERR_BREDR_CONN_BAD_SOCKET 0x0009
> +/* Failed to allocate memory in either host stack or controller.
> + * errno: ENOMEM
> + */
> +#define BTD_ERR_BREDR_CONN_MEMORY_ALLOC 0x000A
> +/* Failed due to other ongoing operations, such as pairing, busy L2CAP
> + * channel or the operation disallowed by the controller.
> + * errno: EBUSY
> + */
> +#define BTD_ERR_BREDR_CONN_BUSY 0x000B
> +/* Failed due to reaching the synchronous connection limit to a device.
> + * errno: EMLINK
> + */
> +#define BTD_ERR_BREDR_CONN_SYNC_CONNECT_LIMIT 0x000C
> +/* Failed due to connection timeout
> + * errno: ETIMEDOUT
> + */
> +#define BTD_ERR_BREDR_CONN_TIMEOUT 0x000D
> +/* Refused by the remote device due to limited resource, security reason
> + * or unacceptable address type.
> + * errno: ECONNREFUSED
> + */
> +#define BTD_ERR_BREDR_CONN_REFUSED 0x000E
> +/* Terminated by the remote device due to limited resource or power
> + * off.
> + * errno: ECONNRESET
> + */
> +#define BTD_ERR_BREDR_CONN_TERM_BY_REMOTE 0x000F
> +/* Terminated by the local host.
> + * errno: ECONNABORTED
> + */
> +#define BTD_ERR_BREDR_CONN_TERM_BY_LOCAL 0x0010
> +/* Failed due to LMP protocol error.
> + * errno: EPROTO
> + */
> +#define BTD_ERR_BREDR_CONN_PROTO_ERROR 0x0011
> +/* Failed due to cancellation caused by adapter drop, unexpected device drop,
> + * or incoming disconnection request before connection request is completed.
> + * errno: none
> + */
> +#define BTD_ERR_BREDR_CONN_CANCELED 0x0012
> +/* Failed due to unknown reason.
> + * errno: ENOSYS
> + */
> +#define BTD_ERR_BREDR_CONN_UNKNOWN 0x0013
> +
> +/* LE connection failure reasons
> + * BT_ERR_* should be used as one of the parameters to btd_error_*_err().
> + */
> +
> +/* Failed due to invalid arguments.
> + * errno: EINVAL
> + */
> +#define BTD_ERR_LE_CONN_INVALID_ARGUMENTS 0x0101
> +/* Failed due to adapter not powered.
> + * errno: EHOSTUNREACH
> + */
> +#define BTD_ERR_LE_CONN_ADAPTER_NOT_POWERED 0x0102
> +/* Failed due to unsupported state transition of L2CAP channel or other
> + * features (e.g. LE features) either by the local host or the remote.
> + * errno: EOPNOTSUPP, EPROTONOSUPPORT
> + */
> +#define BTD_ERR_LE_CONN_NOT_SUPPORTED 0x0103
> +/* Either the BT IO is already connected or LE link connection in place.
> + * errno: EALREADY, EISCONN
> + */
> +#define BTD_ERR_LE_CONN_ALREADY_CONNECTED 0x0104
> +/* Failed due to the socket is in bad state.
> + * errno: EBADFD
> + */
> +#define BTD_ERR_LE_CONN_BAD_SOCKET 0x0105
> +/* Failed to allocate memory in either host stack or controller.
> + * errno: ENOMEM
> + */
> +#define BTD_ERR_LE_CONN_MEMORY_ALLOC 0x0106
> +/* Failed due to other ongoing operations, such as pairing, connecting, busy
> + * L2CAP channel or the operation disallowed by the controller.
> + * errno: EBUSY
> + */
> +#define BTD_ERR_LE_CONN_BUSY 0x0107
> +/* Failed due to that LE is not enabled or the attempt is refused by the remote
> + * device due to limited resource, security reason or unacceptable address type.
> + * errno: ECONNREFUSED
> + */
> +#define BTD_ERR_LE_CONN_REFUSED 0x0108
> +/* Failed to create or connect to BT IO socket. This can also indicate
> + * hardware failure in the controller.
> + * errno: EIO
> + */
> +#define BTD_ERR_LE_CONN_CREATE_SOCKET 0x0109
> +/* Failed due to connection timeout
> + * errno: ETIMEDOUT
> + */
> +#define BTD_ERR_LE_CONN_TIMEOUT 0x010A
> +/* Failed due to reaching the synchronous connection limit to a device.
> + * errno: EMLINK
> + */
> +#define BTD_ERR_LE_CONN_SYNC_CONNECT_LIMIT 0x010B
> +/* Terminated by the remote device due to limited resource or power
> + * off.
> + * errno: ECONNRESET
> + */
> +#define BTD_ERR_LE_CONN_TERM_BY_REMOTE 0x010C
> +/* Terminated by the local host.
> + * errno: ECONNABORTED
> + */
> +#define BTD_ERR_LE_CONN_TERM_BY_LOCAL 0x010D
> +/* Failed due to LL protocol error.
> + * errno: EPROTO
> + */
> +#define BTD_ERR_LE_CONN_PROTO_ERROR 0x010E
> +/* Failed to complete the GATT browsing.
> + * errno: none
> + */
> +#define BTD_ERR_LE_CONN_GATT_BROWSE 0x010F
> +/* Failed due to unknown reason.
> + * errno: ENOSYS
> + */
> +#define BTD_ERR_LE_CONN_UNKNOWN 0x0110
> +
> DBusMessage *btd_error_invalid_args(DBusMessage *msg);
> DBusMessage *btd_error_invalid_args_str(DBusMessage *msg, const char *str);
> +DBusMessage *btd_error_invalid_args_err(DBusMessage *msg, uint16_t err);
> DBusMessage *btd_error_busy(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_already_connected(DBusMessage *msg);
> DBusMessage *btd_error_not_available(DBusMessage *msg);
> +DBusMessage *btd_error_not_available_err(DBusMessage *msg, uint16_t err);
> DBusMessage *btd_error_in_progress(DBusMessage *msg);
> +DBusMessage *btd_error_in_progress_err(DBusMessage *msg, uint16_t err);
> DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
> DBusMessage *btd_error_not_authorized(DBusMessage *msg);
> DBusMessage *btd_error_not_permitted(DBusMessage *msg, const char *str);
> DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
> DBusMessage *btd_error_agent_not_available(DBusMessage *msg);
> DBusMessage *btd_error_not_ready(DBusMessage *msg);
> +DBusMessage *btd_error_not_ready_err(DBusMessage *msg, uint16_t err);
> DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
> +DBusMessage *btd_error_failed_err(DBusMessage *msg, uint16_t err);
> +
> +uint16_t btd_error_bredr_conn_from_errno(int errno_code);
> +uint16_t btd_error_le_conn_from_errno(int errno_code);
> --
> 2.32.0.288.g62a8d224e6-goog
>


--
Luiz Augusto von Dentz

2021-06-26 02:00:05

by Miao-chen Chou

[permalink] [raw]
Subject: Re: [BlueZ PATCH v1 1/3] error: BR/EDR and LE connection failure reasons

Hi Luiz,

On Fri, Jun 18, 2021 at 11:18 AM Luiz Augusto von Dentz
<[email protected]> wrote:
>
> Hi Miao,
>
> On Thu, Jun 17, 2021 at 8:08 PM Miao-chen Chou <[email protected]> wrote:
> >
> > The source of Connect() failures can be divided into the following
> > three.
> > - bluetoothd's device interface state transition and profile state
> > transition
> > - Kernel's L2CAP layer state transition
> > - Potential HCI error codes returned by the remote device
> >
> > Reviewed-by: Alain Michaud <[email protected]>
> > Reviewed-by: Howard Chung <[email protected]>
> > ---
> >
> > src/error.c | 124 +++++++++++++++++++++++++++++++++++++
> > src/error.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 295 insertions(+)
> >
> > diff --git a/src/error.c b/src/error.c
> > index 89517075e..b72e3d764 100644
> > --- a/src/error.c
> > +++ b/src/error.c
> > @@ -27,6 +27,7 @@
> > #include <config.h>
> > #endif
> >
> > +#include <stdio.h>
> > #include "gdbus/gdbus.h"
> >
> > #include "error.h"
> > @@ -43,6 +44,15 @@ DBusMessage *btd_error_invalid_args_str(DBusMessage *msg, const char *str)
> > "%s", str);
> > }
> >
> > +DBusMessage *btd_error_invalid_args_err(DBusMessage *msg, uint16_t err)
> > +{
> > + char str[16];
> > +
> > + sprintf(str, "BtdError:0x%04X", err);
> > + return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
> > + "%s", str);
> > +}
> > +
> > DBusMessage *btd_error_busy(DBusMessage *msg)
> > {
> > return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
> > @@ -79,12 +89,30 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg)
> > "In Progress");
> > }
> >
> > +DBusMessage *btd_error_in_progress_err(DBusMessage *msg, uint16_t err)
> > +{
> > + char str[16];
> > +
> > + sprintf(str, "BtdError:0x%04X", err);
> > + return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", "%s",
> > + str);
>
> Was there a problem that you didn't use g_dbus_create_error to convert
> the error? I mean instead of using %s use BtdError:0x%04X, actually it
> might be enough to just have the code portion and skip BtdError as
> that can be assumed implicitly the our error messages would contain
> error codes.
I thought about dropping BtdError from the error message, but I ended
up with BtdError to make the meaning more explicit. I am happy to drop
it if the implicity is fine.
>
> > +}
> > +
> > DBusMessage *btd_error_not_available(DBusMessage *msg)
> > {
> > return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable",
> > "Operation currently not available");
> > }
> >
> > +DBusMessage *btd_error_not_available_err(DBusMessage *msg, uint16_t err)
> > +{
> > + char str[16];
> > +
> > + sprintf(str, "BtdError:0x%04X", err);
> > + return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAvailable", "%s",
> > + str);
> > +}
> > +
> > DBusMessage *btd_error_does_not_exist(DBusMessage *msg)
> > {
> > return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
> > @@ -121,8 +149,104 @@ DBusMessage *btd_error_not_ready(DBusMessage *msg)
> > "Resource Not Ready");
> > }
> >
> > +DBusMessage *btd_error_not_ready_err(DBusMessage *msg, uint16_t err)
> > +{
> > + char str[16];
> > +
> > + sprintf(str, "BtdError:0x%04X", err);
> > + return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady", "%s", str);
> > +}
> > +
> > DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
> > {
> > return g_dbus_create_error(msg, ERROR_INTERFACE
> > ".Failed", "%s", str);
> > }
> > +
> > +DBusMessage *btd_error_failed_err(DBusMessage *msg, uint16_t err)
> > +{
> > + char str[16];
> > +
> > + sprintf(str, "BtdError:0x%04X", err);
> > + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", str);
> > +}
> > +
> > +uint16_t btd_error_bredr_conn_from_errno(int errno_code)
> > +{
> > + switch (-errno_code) {
> > + case EALREADY:
> > + case EISCONN: // Fall through
> > + return BTD_ERR_BREDR_CONN_ALREADY_CONNECTED;
> > + case EHOSTDOWN:
> > + return BTD_ERR_BREDR_CONN_PAGE_TIMEOUT;
> > + case ENOPROTOOPT:
> > + return BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE;
> > + case EIO:
> > + return BTD_ERR_BREDR_CONN_CREATE_SOCKET;
> > + case EINVAL:
> > + return BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS;
> > + case EHOSTUNREACH:
> > + return BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED;
> > + case EOPNOTSUPP:
> > + case EPROTONOSUPPORT: // Fall through
> > + return BTD_ERR_BREDR_CONN_NOT_SUPPORTED;
> > + case EBADFD:
> > + return BTD_ERR_BREDR_CONN_BAD_SOCKET;
> > + case ENOMEM:
> > + return BTD_ERR_BREDR_CONN_MEMORY_ALLOC;
> > + case EBUSY:
> > + return BTD_ERR_BREDR_CONN_BUSY;
> > + case EMLINK:
> > + return BTD_ERR_BREDR_CONN_SYNC_CONNECT_LIMIT;
> > + case ETIMEDOUT:
> > + return BTD_ERR_BREDR_CONN_TIMEOUT;
> > + case ECONNREFUSED:
> > + return BTD_ERR_BREDR_CONN_REFUSED;
> > + case ECONNRESET:
> > + return BTD_ERR_BREDR_CONN_TERM_BY_REMOTE;
> > + case ECONNABORTED:
> > + return BTD_ERR_BREDR_CONN_TERM_BY_LOCAL;
> > + case EPROTO:
> > + return BTD_ERR_BREDR_CONN_PROTO_ERROR;
> > + default:
> > + return BTD_ERR_BREDR_CONN_UNKNOWN;
> > + }
> > +}
> > +
> > +uint16_t btd_error_le_conn_from_errno(int errno_code)
> > +{
> > + switch (-errno_code) {
> > + case EINVAL:
> > + return BTD_ERR_LE_CONN_INVALID_ARGUMENTS;
> > + case EHOSTUNREACH:
> > + return BTD_ERR_LE_CONN_ADAPTER_NOT_POWERED;
> > + case EOPNOTSUPP:
> > + case EPROTONOSUPPORT: // Fall through
> > + return BTD_ERR_LE_CONN_NOT_SUPPORTED;
> > + case EALREADY:
> > + case EISCONN: // Fall through
> > + return BTD_ERR_LE_CONN_ALREADY_CONNECTED;
> > + case EBADFD:
> > + return BTD_ERR_LE_CONN_BAD_SOCKET;
> > + case ENOMEM:
> > + return BTD_ERR_LE_CONN_MEMORY_ALLOC;
> > + case EBUSY:
> > + return BTD_ERR_LE_CONN_BUSY;
> > + case ECONNREFUSED:
> > + return BTD_ERR_LE_CONN_REFUSED;
> > + case EIO:
> > + return BTD_ERR_LE_CONN_CREATE_SOCKET;
> > + case ETIMEDOUT:
> > + return BTD_ERR_LE_CONN_TIMEOUT;
> > + case EMLINK:
> > + return BTD_ERR_LE_CONN_SYNC_CONNECT_LIMIT;
> > + case ECONNRESET:
> > + return BTD_ERR_LE_CONN_TERM_BY_REMOTE;
> > + case ECONNABORTED:
> > + return BTD_ERR_LE_CONN_TERM_BY_LOCAL;
> > + case EPROTO:
> > + return BTD_ERR_LE_CONN_PROTO_ERROR;
> > + default:
> > + return BTD_ERR_LE_CONN_UNKNOWN;
> > + }
> > +}
> > diff --git a/src/error.h b/src/error.h
> > index 7c8cad066..f258cc4e7 100644
> > --- a/src/error.h
> > +++ b/src/error.h
> > @@ -24,22 +24,193 @@
> > */
> >
> > #include <dbus/dbus.h>
> > +#include <stdint.h>
> >
> > #define ERROR_INTERFACE "org.bluez.Error"
> >
> > +/* BR/EDR connection failure reasons
> > + * BT_ERR_* should be used as one of the parameters to btd_error_*_err().
> > + */
> > +
> > +/* Either the profile is already connected or ACL connection is in
> > + * place.
> > + * errno: EALREADY, EISCONN
> > + */
> > +#define BTD_ERR_BREDR_CONN_ALREADY_CONNECTED 0x0001
> > +/* Failed due to page timeout.
> > + * errno: EHOSTDOWN
> > + */
> > +#define BTD_ERR_BREDR_CONN_PAGE_TIMEOUT 0x0002
> > +/* Failed to find connectable services or the target service.
> > + * errno: ENOPROTOOPT
> > + */
> > +#define BTD_ERR_BREDR_CONN_PROFILE_UNAVAILABLE 0x0003
> > +/* Failed to complete the SDP search.
> > + * errno: none
> > + */
> > +#define BTD_ERR_BREDR_CONN_SDP_SEARCH 0x0004
> > +/* Failed to create or connect to BT IO socket. This can also indicate
> > + * hardware failure in the controller.
> > + * errno: EIO
> > + */
> > +#define BTD_ERR_BREDR_CONN_CREATE_SOCKET 0x0005
> > +/* Failed due to invalid arguments.
> > + * errno: EINVAL
> > + */
> > +#define BTD_ERR_BREDR_CONN_INVALID_ARGUMENTS 0x0006
> > +/* Failed due to adapter not powered.
> > + * errno: EHOSTUNREACH
> > + */
> > +#define BTD_ERR_BREDR_CONN_ADAPTER_NOT_POWERED 0x0007
> > +/* Failed due to unsupported state transition of L2CAP channel or other
> > + * features either by the local host or the remote.
> > + * errno: EOPNOTSUPP, EPROTONOSUPPORT
> > + */
> > +#define BTD_ERR_BREDR_CONN_NOT_SUPPORTED 0x0008
> > +/* Failed due to the socket is in bad state.
> > + * errno: EBADFD
> > + */
> > +#define BTD_ERR_BREDR_CONN_BAD_SOCKET 0x0009
> > +/* Failed to allocate memory in either host stack or controller.
> > + * errno: ENOMEM
> > + */
> > +#define BTD_ERR_BREDR_CONN_MEMORY_ALLOC 0x000A
> > +/* Failed due to other ongoing operations, such as pairing, busy L2CAP
> > + * channel or the operation disallowed by the controller.
> > + * errno: EBUSY
> > + */
> > +#define BTD_ERR_BREDR_CONN_BUSY 0x000B
> > +/* Failed due to reaching the synchronous connection limit to a device.
> > + * errno: EMLINK
> > + */
> > +#define BTD_ERR_BREDR_CONN_SYNC_CONNECT_LIMIT 0x000C
> > +/* Failed due to connection timeout
> > + * errno: ETIMEDOUT
> > + */
> > +#define BTD_ERR_BREDR_CONN_TIMEOUT 0x000D
> > +/* Refused by the remote device due to limited resource, security reason
> > + * or unacceptable address type.
> > + * errno: ECONNREFUSED
> > + */
> > +#define BTD_ERR_BREDR_CONN_REFUSED 0x000E
> > +/* Terminated by the remote device due to limited resource or power
> > + * off.
> > + * errno: ECONNRESET
> > + */
> > +#define BTD_ERR_BREDR_CONN_TERM_BY_REMOTE 0x000F
> > +/* Terminated by the local host.
> > + * errno: ECONNABORTED
> > + */
> > +#define BTD_ERR_BREDR_CONN_TERM_BY_LOCAL 0x0010
> > +/* Failed due to LMP protocol error.
> > + * errno: EPROTO
> > + */
> > +#define BTD_ERR_BREDR_CONN_PROTO_ERROR 0x0011
> > +/* Failed due to cancellation caused by adapter drop, unexpected device drop,
> > + * or incoming disconnection request before connection request is completed.
> > + * errno: none
> > + */
> > +#define BTD_ERR_BREDR_CONN_CANCELED 0x0012
> > +/* Failed due to unknown reason.
> > + * errno: ENOSYS
> > + */
> > +#define BTD_ERR_BREDR_CONN_UNKNOWN 0x0013
> > +
> > +/* LE connection failure reasons
> > + * BT_ERR_* should be used as one of the parameters to btd_error_*_err().
> > + */
> > +
> > +/* Failed due to invalid arguments.
> > + * errno: EINVAL
> > + */
> > +#define BTD_ERR_LE_CONN_INVALID_ARGUMENTS 0x0101
> > +/* Failed due to adapter not powered.
> > + * errno: EHOSTUNREACH
> > + */
> > +#define BTD_ERR_LE_CONN_ADAPTER_NOT_POWERED 0x0102
> > +/* Failed due to unsupported state transition of L2CAP channel or other
> > + * features (e.g. LE features) either by the local host or the remote.
> > + * errno: EOPNOTSUPP, EPROTONOSUPPORT
> > + */
> > +#define BTD_ERR_LE_CONN_NOT_SUPPORTED 0x0103
> > +/* Either the BT IO is already connected or LE link connection in place.
> > + * errno: EALREADY, EISCONN
> > + */
> > +#define BTD_ERR_LE_CONN_ALREADY_CONNECTED 0x0104
> > +/* Failed due to the socket is in bad state.
> > + * errno: EBADFD
> > + */
> > +#define BTD_ERR_LE_CONN_BAD_SOCKET 0x0105
> > +/* Failed to allocate memory in either host stack or controller.
> > + * errno: ENOMEM
> > + */
> > +#define BTD_ERR_LE_CONN_MEMORY_ALLOC 0x0106
> > +/* Failed due to other ongoing operations, such as pairing, connecting, busy
> > + * L2CAP channel or the operation disallowed by the controller.
> > + * errno: EBUSY
> > + */
> > +#define BTD_ERR_LE_CONN_BUSY 0x0107
> > +/* Failed due to that LE is not enabled or the attempt is refused by the remote
> > + * device due to limited resource, security reason or unacceptable address type.
> > + * errno: ECONNREFUSED
> > + */
> > +#define BTD_ERR_LE_CONN_REFUSED 0x0108
> > +/* Failed to create or connect to BT IO socket. This can also indicate
> > + * hardware failure in the controller.
> > + * errno: EIO
> > + */
> > +#define BTD_ERR_LE_CONN_CREATE_SOCKET 0x0109
> > +/* Failed due to connection timeout
> > + * errno: ETIMEDOUT
> > + */
> > +#define BTD_ERR_LE_CONN_TIMEOUT 0x010A
> > +/* Failed due to reaching the synchronous connection limit to a device.
> > + * errno: EMLINK
> > + */
> > +#define BTD_ERR_LE_CONN_SYNC_CONNECT_LIMIT 0x010B
> > +/* Terminated by the remote device due to limited resource or power
> > + * off.
> > + * errno: ECONNRESET
> > + */
> > +#define BTD_ERR_LE_CONN_TERM_BY_REMOTE 0x010C
> > +/* Terminated by the local host.
> > + * errno: ECONNABORTED
> > + */
> > +#define BTD_ERR_LE_CONN_TERM_BY_LOCAL 0x010D
> > +/* Failed due to LL protocol error.
> > + * errno: EPROTO
> > + */
> > +#define BTD_ERR_LE_CONN_PROTO_ERROR 0x010E
> > +/* Failed to complete the GATT browsing.
> > + * errno: none
> > + */
> > +#define BTD_ERR_LE_CONN_GATT_BROWSE 0x010F
> > +/* Failed due to unknown reason.
> > + * errno: ENOSYS
> > + */
> > +#define BTD_ERR_LE_CONN_UNKNOWN 0x0110
> > +
> > DBusMessage *btd_error_invalid_args(DBusMessage *msg);
> > DBusMessage *btd_error_invalid_args_str(DBusMessage *msg, const char *str);
> > +DBusMessage *btd_error_invalid_args_err(DBusMessage *msg, uint16_t err);
> > DBusMessage *btd_error_busy(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_already_connected(DBusMessage *msg);
> > DBusMessage *btd_error_not_available(DBusMessage *msg);
> > +DBusMessage *btd_error_not_available_err(DBusMessage *msg, uint16_t err);
> > DBusMessage *btd_error_in_progress(DBusMessage *msg);
> > +DBusMessage *btd_error_in_progress_err(DBusMessage *msg, uint16_t err);
> > DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
> > DBusMessage *btd_error_not_authorized(DBusMessage *msg);
> > DBusMessage *btd_error_not_permitted(DBusMessage *msg, const char *str);
> > DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
> > DBusMessage *btd_error_agent_not_available(DBusMessage *msg);
> > DBusMessage *btd_error_not_ready(DBusMessage *msg);
> > +DBusMessage *btd_error_not_ready_err(DBusMessage *msg, uint16_t err);
> > DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
> > +DBusMessage *btd_error_failed_err(DBusMessage *msg, uint16_t err);
> > +
> > +uint16_t btd_error_bredr_conn_from_errno(int errno_code);
> > +uint16_t btd_error_le_conn_from_errno(int errno_code);
> > --
> > 2.32.0.288.g62a8d224e6-goog
> >
>
>
> --
> Luiz Augusto von Dentz
Thanks,
Miao