1 /** @file
2  *  @brief Internal APIs for Bluetooth Hearing Access Profile.
3  */
4 
5 /*
6  * Copyright (c) 2022 Codecoup
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 /* Control Point opcodes */
12 #define BT_HAS_OP_READ_PRESET_REQ        0x01
13 #define BT_HAS_OP_READ_PRESET_RSP        0x02
14 #define BT_HAS_OP_PRESET_CHANGED         0x03
15 #define BT_HAS_OP_WRITE_PRESET_NAME      0x04
16 #define BT_HAS_OP_SET_ACTIVE_PRESET      0x05
17 #define BT_HAS_OP_SET_NEXT_PRESET        0x06
18 #define BT_HAS_OP_SET_PREV_PRESET        0x07
19 #define BT_HAS_OP_SET_ACTIVE_PRESET_SYNC 0x08
20 #define BT_HAS_OP_SET_NEXT_PRESET_SYNC   0x09
21 #define BT_HAS_OP_SET_PREV_PRESET_SYNC   0x0a
22 
23 /* Application error codes */
24 #define BT_HAS_ERR_INVALID_OPCODE         0x80
25 #define BT_HAS_ERR_WRITE_NAME_NOT_ALLOWED 0x81
26 #define BT_HAS_ERR_PRESET_SYNC_NOT_SUPP   0x82
27 #define BT_HAS_ERR_OPERATION_NOT_POSSIBLE 0x83
28 #define BT_HAS_ERR_INVALID_PARAM_LEN      0x84
29 
30 /* Hearing Aid Feature bits */
31 #define BT_HAS_FEAT_HEARING_AID_TYPE_LSB  BIT(0)
32 #define BT_HAS_FEAT_HEARING_AID_TYPE_MSB  BIT(1)
33 #define BT_HAS_FEAT_PRESET_SYNC_SUPP      BIT(2)
34 #define BT_HAS_FEAT_INDEPENDENT_PRESETS   BIT(3)
35 #define BT_HAS_FEAT_DYNAMIC_PRESETS       BIT(4)
36 #define BT_HAS_FEAT_WRITABLE_PRESETS_SUPP BIT(5)
37 
38 #define BT_HAS_FEAT_HEARING_AID_TYPE_MASK (BT_HAS_FEAT_HEARING_AID_TYPE_LSB | \
39 					   BT_HAS_FEAT_HEARING_AID_TYPE_MSB)
40 
41 /* Preset Changed Change ID values */
42 #define BT_HAS_CHANGE_ID_GENERIC_UPDATE     0x00
43 #define BT_HAS_CHANGE_ID_PRESET_DELETED     0x01
44 #define BT_HAS_CHANGE_ID_PRESET_AVAILABLE   0x02
45 #define BT_HAS_CHANGE_ID_PRESET_UNAVAILABLE 0x03
46 
47 #define BT_HAS_IS_LAST 0x01
48 
49 struct bt_has {
50 	/** Hearing Aid Features value */
51 	uint8_t features;
52 
53 	/** Active preset index value */
54 	uint8_t active_index;
55 
56 	/* Whether the service has been registered or not */
57 	bool registered;
58 };
59 
60 struct bt_has_cp_hdr {
61 	uint8_t opcode;
62 	uint8_t data[0];
63 } __packed;
64 
65 struct bt_has_cp_read_presets_req {
66 	uint8_t start_index;
67 	uint8_t num_presets;
68 } __packed;
69 
70 struct bt_has_cp_read_preset_rsp {
71 	uint8_t is_last;
72 	uint8_t index;
73 	uint8_t properties;
74 	uint8_t name[0];
75 } __packed;
76 
77 struct bt_has_cp_preset_changed {
78 	uint8_t change_id;
79 	uint8_t is_last;
80 } __packed;
81 
82 struct bt_has_cp_generic_update {
83 	uint8_t prev_index;
84 	uint8_t index;
85 	uint8_t properties;
86 	uint8_t name[0];
87 } __packed;
88 
89 struct bt_has_cp_write_preset_name {
90 	uint8_t index;
91 	uint8_t name[0];
92 } __packed;
93 
94 struct bt_has_cp_set_active_preset {
95 	uint8_t index;
96 } __packed;
97 
bt_has_op_str(uint8_t op)98 static inline const char *bt_has_op_str(uint8_t op)
99 {
100 	switch (op) {
101 	case BT_HAS_OP_READ_PRESET_REQ:
102 		return "Read preset request";
103 	case BT_HAS_OP_READ_PRESET_RSP:
104 		return "Read preset response";
105 	case BT_HAS_OP_PRESET_CHANGED:
106 		return "Preset changed";
107 	case BT_HAS_OP_WRITE_PRESET_NAME:
108 		return "Write preset name";
109 	case BT_HAS_OP_SET_ACTIVE_PRESET:
110 		return "Set active preset";
111 	case BT_HAS_OP_SET_NEXT_PRESET:
112 		return "Set next preset";
113 	case BT_HAS_OP_SET_PREV_PRESET:
114 		return "Set previous preset";
115 	case BT_HAS_OP_SET_ACTIVE_PRESET_SYNC:
116 		return "Set active preset (sync)";
117 	case BT_HAS_OP_SET_NEXT_PRESET_SYNC:
118 		return "Set next preset (sync)";
119 	case BT_HAS_OP_SET_PREV_PRESET_SYNC:
120 		return "Set previous preset (sync)";
121 	default:
122 		return "Unknown";
123 	}
124 }
125 
bt_has_change_id_str(uint8_t change_id)126 static inline const char *bt_has_change_id_str(uint8_t change_id)
127 {
128 	switch (change_id) {
129 	case BT_HAS_CHANGE_ID_GENERIC_UPDATE:
130 		return "Generic update";
131 	case BT_HAS_CHANGE_ID_PRESET_DELETED:
132 		return "Preset deleted";
133 	case BT_HAS_CHANGE_ID_PRESET_AVAILABLE:
134 		return "Preset available";
135 	case BT_HAS_CHANGE_ID_PRESET_UNAVAILABLE:
136 		return "Preset unavailable";
137 	default:
138 		return "Unknown changeId";
139 	}
140 }
141