Skip to content

Commit 3b1ff4f

Browse files
authored
feat: add attribute protocol errors (#421)
* feat: add attribute protocol errors This will allow to return protocol level errors * code review
1 parent 5c19f86 commit 3b1ff4f

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

errors.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package bluetooth
2+
3+
import (
4+
"encoding/hex"
5+
"strings"
6+
)
7+
8+
// AttributeProtocolError represents an ATT error code as defined in the
9+
// Bluetooth Core Specification, Section 3.4.1.1 (ATT_ERROR_RSP), Table 3.4.
10+
type AttributeProtocolError uint8
11+
12+
// attErrorDetails holds the name and description for an ATT error code.
13+
type attErrorDetails struct {
14+
// name is a short identifier for the error.
15+
name string
16+
// description is the human-readable description from the spec.
17+
description string
18+
}
19+
20+
// ATT error codes from the Bluetooth Core Specification, Table 3.4.
21+
const (
22+
ErrAttInvalidHandle AttributeProtocolError = 0x01 // The attribute handle given was not valid on this server.
23+
ErrAttReadNotPermitted AttributeProtocolError = 0x02 // The attribute cannot be read.
24+
ErrAttWriteNotPermitted AttributeProtocolError = 0x03 // The attribute cannot be written.
25+
ErrAttInvalidPDU AttributeProtocolError = 0x04 // The attribute PDU was invalid.
26+
ErrAttInsufficientAuthentication AttributeProtocolError = 0x05 // The attribute requires authentication before it can be read or written.
27+
ErrAttRequestNotSupported AttributeProtocolError = 0x06 // ATT Server does not support the request received from the client.
28+
ErrAttInvalidOffset AttributeProtocolError = 0x07 // Offset specified was past the end of the attribute.
29+
ErrAttInsufficientAuthorization AttributeProtocolError = 0x08 // The attribute requires authorization before it can be read or written.
30+
ErrAttPrepareQueueFull AttributeProtocolError = 0x09 // Too many prepare writes have been queued.
31+
ErrAttNotFound AttributeProtocolError = 0x0A // No attribute found within the given attribute handle range.
32+
ErrAttNotLong AttributeProtocolError = 0x0B // The attribute cannot be read using the ATT_READ_BLOB_REQ PDU.
33+
ErrAttInsufficientEncKeySize AttributeProtocolError = 0x0C // The Encryption Key Size used for encrypting this link is too short.
34+
ErrAttInvalidLength AttributeProtocolError = 0x0D // The attribute value length is invalid for the operation.
35+
ErrAttUnlikelyError AttributeProtocolError = 0x0E // The attribute request has encountered an error that was unlikely, and therefore could not be completed as requested.
36+
ErrAttInsufficientEncryption AttributeProtocolError = 0x0F // The attribute requires encryption before it can be read or written.
37+
ErrAttUnsupportedGroupType AttributeProtocolError = 0x10 // The attribute type is not a supported grouping attribute as defined by a higher layer specification.
38+
ErrAttInsufficientResources AttributeProtocolError = 0x11 // Insufficient Resources to complete the request.
39+
ErrAttOutOfSync AttributeProtocolError = 0x12 // The server requests the client to rediscover the database.
40+
ErrAttValueNotAllowed AttributeProtocolError = 0x13 // The attribute parameter value was not allowed.
41+
)
42+
43+
var attErrors = map[AttributeProtocolError]attErrorDetails{
44+
ErrAttInvalidHandle: {"Invalid Handle", "The attribute handle given was not valid on this server."},
45+
ErrAttReadNotPermitted: {"Read Not Permitted", "The attribute cannot be read."},
46+
ErrAttWriteNotPermitted: {"Write Not Permitted", "The attribute cannot be written."},
47+
ErrAttInvalidPDU: {"Invalid PDU", "The attribute PDU was invalid."},
48+
ErrAttInsufficientAuthentication: {"Insufficient Authentication", "The attribute requires authentication before it can be read or written."},
49+
ErrAttRequestNotSupported: {"Request Not Supported", "ATT Server does not support the request received from the client."},
50+
ErrAttInvalidOffset: {"Invalid Offset", "Offset specified was past the end of the attribute."},
51+
ErrAttInsufficientAuthorization: {"Insufficient Authorization", "The attribute requires authorization before it can be read or written."},
52+
ErrAttPrepareQueueFull: {"Prepare Queue Full", "Too many prepare writes have been queued."},
53+
ErrAttNotFound: {"Attribute Not Found", "No attribute found within the given attribute handle range."},
54+
ErrAttNotLong: {"Attribute Not Long", "The attribute cannot be read using the ATT_READ_BLOB_REQ PDU."},
55+
ErrAttInsufficientEncKeySize: {"Encryption Key Size Too Short", "The Encryption Key Size used for encrypting this link is too short."},
56+
ErrAttInvalidLength: {"Invalid Attribute Value Length", "The attribute value length is invalid for the operation."},
57+
ErrAttUnlikelyError: {"Unlikely Error", "The attribute request has encountered an error that was unlikely, and therefore could not be completed as requested."},
58+
ErrAttInsufficientEncryption: {"Insufficient Encryption", "The attribute requires encryption before it can be read or written."},
59+
ErrAttUnsupportedGroupType: {"Unsupported Group Type", "The attribute type is not a supported grouping attribute as defined by a higher layer specification."},
60+
ErrAttInsufficientResources: {"Insufficient Resources", "Insufficient Resources to complete the request."},
61+
ErrAttOutOfSync: {"Database Out Of Sync", "The server requests the client to rediscover the database."},
62+
ErrAttValueNotAllowed: {"Value Not Allowed", "The attribute parameter value was not allowed."},
63+
}
64+
65+
// Code returns the raw ATT error code.
66+
func (e AttributeProtocolError) Code() uint8 {
67+
return uint8(e)
68+
}
69+
70+
func (e AttributeProtocolError) details() attErrorDetails {
71+
if d, ok := attErrors[e]; ok {
72+
return d
73+
}
74+
code := hex.EncodeToString([]byte{uint8(e)})
75+
if e >= 0x80 && e <= 0x9F {
76+
return attErrorDetails{"Application Error", "Application error code defined by a higher layer specification (0x" + code + ")."}
77+
}
78+
if e >= 0xE0 && e <= 0xFF {
79+
return attErrorDetails{"Common Profile and Service Error", "Common profile and service error code (0x" + code + ")."}
80+
}
81+
return attErrorDetails{"Reserved", "Reserved for future use (0x" + code + ")."}
82+
}
83+
84+
// Name returns a short human-readable name for this ATT error code.
85+
func (e AttributeProtocolError) Name() string {
86+
return e.details().name
87+
}
88+
89+
// Description returns the full description from the Bluetooth Core Specification.
90+
func (e AttributeProtocolError) Description() string {
91+
return e.details().description
92+
}
93+
94+
func (e AttributeProtocolError) Error() string {
95+
d := e.details()
96+
var b strings.Builder
97+
b.WriteString("ATT error 0x")
98+
b.WriteString(hex.EncodeToString([]byte{uint8(e)}))
99+
b.WriteString(" (")
100+
b.WriteString(d.name)
101+
b.WriteString("): ")
102+
b.WriteString(d.description)
103+
return b.String()
104+
}

0 commit comments

Comments
 (0)