39
39
import java .util .Queue ;
40
40
import java .util .UUID ;
41
41
42
+ import no .nordicsemi .android .error .GattError ;
42
43
import no .nordicsemi .android .log .Logger ;
43
44
import no .nordicsemi .android .nrftoolbox .profile .BleManager ;
44
45
import no .nordicsemi .android .nrftoolbox .parser .AlertLevelParser ;
@@ -102,7 +103,7 @@ private void addLinklossService() {
102
103
* This method must be called in UI thread. It works fine on Nexus devices but if called from other thread (f.e. from onServiceAdded in gatt server callback) it hangs the app.
103
104
*/
104
105
final BluetoothGattCharacteristic linklossAlertLevel = new BluetoothGattCharacteristic (ALERT_LEVEL_CHARACTERISTIC_UUID , BluetoothGattCharacteristic .PROPERTY_WRITE
105
- | BluetoothGattCharacteristic .PROPERTY_READ , BluetoothGattCharacteristic .PERMISSION_WRITE );
106
+ | BluetoothGattCharacteristic .PROPERTY_READ , BluetoothGattCharacteristic .PERMISSION_WRITE | BluetoothGattCharacteristic . PERMISSION_READ );
106
107
linklossAlertLevel .setValue (HIGH_ALERT );
107
108
final BluetoothGattService linklossService = new BluetoothGattService (LINKLOSS_SERVICE_UUID , BluetoothGattService .SERVICE_TYPE_PRIMARY );
108
109
linklossService .addCharacteristic (linklossAlertLevel );
@@ -122,7 +123,7 @@ public void run() {
122
123
if (IMMEDIATE_ALERT_SERVICE_UUID .equals (service .getUuid ()))
123
124
addLinklossService ();
124
125
else {
125
- Logger .i (mLogSession , "[Proximity Server] Gatt server started" );
126
+ Logger .i (mLogSession , "[Server] Gatt server started" );
126
127
ProximityManager .super .connect (mDeviceToConnect );
127
128
mDeviceToConnect = null ;
128
129
}
@@ -132,32 +133,56 @@ public void run() {
132
133
133
134
@ Override
134
135
public void onConnectionStateChange (final BluetoothDevice device , final int status , final int newState ) {
135
- if (status == BluetoothGatt .GATT_SUCCESS && newState == BluetoothGatt .STATE_CONNECTED ) {
136
- Logger .i (mLogSession , "[Server] Device with address " + device .getAddress () + " connected" );
137
- } else {
138
- if (newState == BluetoothGatt .STATE_DISCONNECTED ) {
139
- Logger .i (mLogSession , "[Server] Device disconnected" );
136
+ Logger .d (mLogSession , "[Server callback] Connection state changed with status: " + status + " and new state: " + stateToString (newState ) + " (" + newState + ")" );
137
+ if (status == BluetoothGatt .GATT_SUCCESS ) {
138
+ if (newState == BluetoothGatt .STATE_CONNECTED ) {
139
+ Logger .i (mLogSession , "[Server] Device with address " + device .getAddress () + " connected" );
140
140
} else {
141
- Logger .e (mLogSession , "[Server] Connection state changed with error " + status );
141
+ Logger .i (mLogSession , "[Server] Device disconnected" );
142
142
}
143
+ } else {
144
+ Logger .e (mLogSession , "[Server] Error " + status + " (0x" + Integer .toHexString (status ) + "): " + GattError .parseConnectionError (status ));
143
145
}
144
146
}
145
147
146
148
@ Override
147
149
public void onCharacteristicReadRequest (final BluetoothDevice device , final int requestId , final int offset , final BluetoothGattCharacteristic characteristic ) {
148
- Logger .i (mLogSession , "[Server] Read request for characteristic " + characteristic .getUuid () + " (requestId = " + requestId + ", offset = " + offset + ")" );
149
- Logger .v (mLogSession , "[Server] Sending response: SUCCESS" );
150
- Logger .d (mLogSession , "[Server] sendResponse(GATT_SUCCESS, " + ParserUtils .parse (characteristic .getValue ()) + ")" );
151
- mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_SUCCESS , offset , characteristic .getValue ());
150
+ Logger .d (mLogSession , "[Server callback] Read request for characteristic " + characteristic .getUuid () + " (requestId=" + requestId + ", offset=" + offset + ")" );
151
+ Logger .i (mLogSession , "[Server] READ request for characteristic " + characteristic .getUuid () + " received" );
152
+
153
+ byte [] value = characteristic .getValue ();
154
+ if (value != null && offset > 0 ) {
155
+ byte [] offsetValue = new byte [value .length - offset ];
156
+ System .arraycopy (value , offset , offsetValue , 0 , offsetValue .length );
157
+ value = offsetValue ;
158
+ }
159
+ if (value != null )
160
+ Logger .d (mLogSession , "server.sendResponse(GATT_SUCCESS, value=" + ParserUtils .parse (value ) + ")" );
161
+ else
162
+ Logger .d (mLogSession , "server.sendResponse(GATT_SUCCESS, value=null)" );
163
+ mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_SUCCESS , offset , value );
164
+ Logger .v (mLogSession , "[Server] Response sent" );
152
165
}
153
166
154
167
@ Override
155
168
public void onCharacteristicWriteRequest (final BluetoothDevice device , final int requestId , final BluetoothGattCharacteristic characteristic , final boolean preparedWrite ,
156
169
final boolean responseNeeded , final int offset , final byte [] value ) {
157
- Logger .i (mLogSession , "[Server] Write request to characteristic " + characteristic .getUuid () + " (requestId = " + requestId + ", value = " + ParserUtils .parse (value ) + ", offset = " + offset + ")" );
158
- characteristic .setValue (value );
170
+ Logger .d (mLogSession , "[Server callback] Write request to characteristic " + characteristic .getUuid ()
171
+ + " (requestId=" + requestId + ", prepareWrite=" + preparedWrite + ", responseNeeded=" + responseNeeded + ", offset=" + offset + ", value=" + ParserUtils .parse (value ) + ")" );
172
+ final String writeType = !responseNeeded ? "WRITE NO RESPONSE" : "WRITE COMMAND" ;
173
+ Logger .i (mLogSession , "[Server] " + writeType + " request for characteristic " + characteristic .getUuid () + " received, value: " + ParserUtils .parse (value ));
159
174
160
- if (value != null && value .length == 1 ) { // small validation
175
+ if (offset == 0 ) {
176
+ characteristic .setValue (value );
177
+ } else {
178
+ final byte [] currentValue = characteristic .getValue ();
179
+ final byte [] newValue = new byte [currentValue .length + value .length ];
180
+ System .arraycopy (currentValue , 0 , newValue , 0 , currentValue .length );
181
+ System .arraycopy (value , 0 , newValue , offset , value .length );
182
+ characteristic .setValue (newValue );
183
+ }
184
+
185
+ if (!preparedWrite && value != null && value .length == 1 ) { // small validation
161
186
if (value [0 ] != NO_ALERT [0 ]) {
162
187
Logger .a (mLogSession , "[Server] Immediate alarm request received: " + AlertLevelParser .parse (characteristic ));
163
188
mCallbacks .onAlarmTriggered ();
@@ -166,39 +191,44 @@ public void onCharacteristicWriteRequest(final BluetoothDevice device, final int
166
191
mCallbacks .onAlarmStopped ();
167
192
}
168
193
}
169
- if (responseNeeded ) {
170
- Logger .v (mLogSession , "[Server] Sending response: SUCCESS" );
171
- Logger .d (mLogSession , "[Server] sendResponse(GATT_SUCCESS)" );
172
- mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_SUCCESS , offset , null );
173
- }
194
+
195
+ Logger .d (mLogSession , "server.sendResponse(GATT_SUCCESS, offset=" + offset + ", value=" + ParserUtils .parse (value ) + ")" );
196
+ mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_SUCCESS , offset , null );
197
+ Logger .v (mLogSession , "[Server] Response sent" );
174
198
}
175
199
176
200
@ Override
177
201
public void onDescriptorReadRequest (final BluetoothDevice device , final int requestId , final int offset , final BluetoothGattDescriptor descriptor ) {
178
- Logger .i (mLogSession , "[Server] Write request to descriptor " + descriptor .getUuid () + " (requestId = " + requestId + ", offset = " + offset + ")" );
202
+ Logger .d (mLogSession , "[Server callback] Write request to descriptor " + descriptor .getUuid () + " (requestId=" + requestId + ", offset=" + offset + ")" );
203
+ Logger .i (mLogSession , "[Server] READ request for descriptor " + descriptor .getUuid () + " received" );
179
204
// This method is not supported
180
- Logger .v (mLogSession , "[Server] Sending response: REQUEST_NOT_SUPPORTED " );
181
- Logger .d (mLogSession , "[Server] sendResponse(GATT_REQUEST_NOT_SUPPORTED)" );
205
+ Logger .w (mLogSession , "[Server] Operation not supported " );
206
+ Logger .d (mLogSession , "[Server] server. sendResponse(GATT_REQUEST_NOT_SUPPORTED)" );
182
207
mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_REQUEST_NOT_SUPPORTED , offset , null );
208
+ Logger .v (mLogSession , "[Server] Response sent" );
183
209
}
184
210
185
211
@ Override
186
212
public void onDescriptorWriteRequest (final BluetoothDevice device , final int requestId , final BluetoothGattDescriptor descriptor , final boolean preparedWrite ,
187
213
final boolean responseNeeded , final int offset , final byte [] value ) {
188
- Logger .i (mLogSession , "[Server] Write request to descriptor " + descriptor .getUuid () + " (requestId = " + requestId + ", value = " + ParserUtils .parse (value ) + ", offset = " + offset + ")" );
214
+ Logger .d (mLogSession , "[Server callback] Write request to descriptor " + descriptor .getUuid ()
215
+ + " (requestId=" + requestId + ", prepareWrite=" + preparedWrite + ", responseNeeded=" + responseNeeded + ", offset=" + offset + ", value=" + ParserUtils .parse (value ) + ")" );
216
+ Logger .i (mLogSession , "[Server] READ request for descriptor " + descriptor .getUuid () + " received" );
189
217
// This method is not supported
190
- Logger .v (mLogSession , "[Server] Sending response: REQUEST_NOT_SUPPORTED " );
191
- Logger .d (mLogSession , "[Server] sendResponse(GATT_REQUEST_NOT_SUPPORTED)" );
218
+ Logger .w (mLogSession , "[Server] Operation not supported " );
219
+ Logger .d (mLogSession , "[Server] server. sendResponse(GATT_REQUEST_NOT_SUPPORTED)" );
192
220
mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_REQUEST_NOT_SUPPORTED , offset , null );
221
+ Logger .v (mLogSession , "[Server] Response sent" );
193
222
}
194
223
195
224
@ Override
196
225
public void onExecuteWrite (final BluetoothDevice device , final int requestId , final boolean execute ) {
197
- Logger .i (mLogSession , "[Server] Execute write request (requestId = " + requestId + ")" );
226
+ Logger .d (mLogSession , "[Server callback ] Execute write request (requestId= " + requestId + ", execute=" + execute + ")" );
198
227
// This method is not supported
199
- Logger .v (mLogSession , "[Server] Sending response: REQUEST_NOT_SUPPORTED " );
200
- Logger .d (mLogSession , "[Server] sendResponse(GATT_REQUEST_NOT_SUPPORTED)" );
228
+ Logger .w (mLogSession , "[Server] Operation not supported " );
229
+ Logger .d (mLogSession , "[Server] server. sendResponse(GATT_REQUEST_NOT_SUPPORTED)" );
201
230
mBluetoothGattServer .sendResponse (device , requestId , BluetoothGatt .GATT_REQUEST_NOT_SUPPORTED , 0 , null );
231
+ Logger .v (mLogSession , "[Server] Response sent" );
202
232
}
203
233
};
204
234
0 commit comments