Skip to content

Commit 341ecf5

Browse files
committed
UART divides long text into 20B parts
UART now checks the RX characteristic properties and: 1) it will use long write if WRITE REQUEST is set, 2) it will divide the text into up to 20-bytes packets Also the app background has been fixed.
1 parent 54507a1 commit 341ecf5

35 files changed

+316
-75
lines changed

app/app.iml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
1313
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
1414
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
15-
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
1615
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
1716
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
18-
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
17+
<afterSyncTasks>
18+
<task>generateDebugAndroidTestSources</task>
19+
<task>generateDebugSources</task>
20+
</afterSyncTasks>
1921
<option name="ALLOW_USER_CONFIGURATION" value="false" />
2022
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
2123
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
@@ -24,7 +26,7 @@
2426
</configuration>
2527
</facet>
2628
</component>
27-
<component name="NewModuleRootManager" inherit-compiler-output="false">
29+
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
2830
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
2931
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
3032
<exclude-output />
@@ -34,13 +36,13 @@
3436
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
3537
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
3638
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
37-
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
39+
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
3840
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
3941
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
4042
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
4143
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
4244
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
43-
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
45+
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
4446
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
4547
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
4648
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@@ -70,7 +72,7 @@
7072
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
7173
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
7274
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.2.1/jars" />
73-
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/22.2.0/jars" />
75+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/22.2.1/jars" />
7476
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
7577
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
7678
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
@@ -89,7 +91,7 @@
8991
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
9092
<orderEntry type="sourceFolder" forTests="false" />
9193
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
92-
<orderEntry type="library" exported="" name="design-22.2.0" level="project" />
94+
<orderEntry type="library" exported="" name="design-22.2.1" level="project" />
9395
<orderEntry type="library" exported="" name="nrf-logger-v2.0" level="project" />
9496
<orderEntry type="library" exported="" name="support-v4-22.2.1" level="project" />
9597
<orderEntry type="library" exported="" name="achartengine-1.1.0" level="project" />

app/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
applicationId "no.nordicsemi.android.nrftoolbox"
88
minSdkVersion 18
99
targetSdkVersion 22
10-
versionCode 35
11-
versionName "1.14.2"
10+
versionCode 36
11+
versionName "1.14.3"
1212
}
1313
buildTypes {
1414
release {
@@ -21,7 +21,7 @@ android {
2121
dependencies {
2222
compile fileTree(dir: 'libs', include: ['*.jar'])
2323
compile 'com.android.support:appcompat-v7:22.2.1'
24-
compile 'com.android.support:design:22.2.0'
24+
compile 'com.android.support:design:22.2.1'
2525
compile project(':dfu')
2626
compile files('libs/achartengine-1.1.0.jar')
2727
compile files('libs/nrf-logger-v2.0.jar')

app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ protected final boolean enableNotifications(final BluetoothGattCharacteristic ch
340340
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0)
341341
return false;
342342

343+
Logger.d(mLogSession, "gatt.setCharacteristicNotification(" + characteristic.getUuid() + ", true)");
343344
gatt.setCharacteristicNotification(characteristic, true);
344345
final BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);
345346
if (descriptor != null) {
@@ -366,6 +367,7 @@ protected final boolean enableIndications(final BluetoothGattCharacteristic char
366367
if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE) == 0)
367368
return false;
368369

370+
Logger.d(mLogSession, "gatt.setCharacteristicNotification(" + characteristic.getUuid() + ", true)");
369371
gatt.setCharacteristicNotification(characteristic, true);
370372
final BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);
371373
if (descriptor != null) {
@@ -414,7 +416,7 @@ protected final boolean writeCharacteristic(final BluetoothGattCharacteristic ch
414416
if ((properties & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) == 0)
415417
return false;
416418

417-
Logger.v(mLogSession, "Writing characteristic " + characteristic.getUuid());
419+
Logger.v(mLogSession, "Writing characteristic " + characteristic.getUuid() + " (" + getWriteType(characteristic.getWriteType()) + ")");
418420
Logger.d(mLogSession, "gatt.writeCharacteristic(" + characteristic.getUuid() + ")");
419421
return gatt.writeCharacteristic(characteristic);
420422
}
@@ -921,4 +923,17 @@ private String bondStateToString(final int state) {
921923
return "UNKNOWN";
922924
}
923925
}
926+
927+
private String getWriteType(final int type) {
928+
switch (type) {
929+
case BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT:
930+
return "WRITE REQUEST";
931+
case BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE:
932+
return "WRITE COMMAND";
933+
case BluetoothGattCharacteristic.WRITE_TYPE_SIGNED:
934+
return "WRITE SIGNED";
935+
default:
936+
return "UNKNOWN: " + type;
937+
}
938+
}
924939
}

app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTManager.java

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import android.bluetooth.BluetoothGattCharacteristic;
2727
import android.bluetooth.BluetoothGattService;
2828
import android.content.Context;
29+
import android.text.TextUtils;
2930

31+
import java.io.UnsupportedEncodingException;
3032
import java.util.LinkedList;
3133
import java.util.Queue;
3234
import java.util.UUID;
@@ -36,12 +38,16 @@
3638
public class UARTManager extends BleManager<UARTManagerCallbacks> {
3739
/** Nordic UART Service UUID */
3840
private final static UUID UART_SERVICE_UUID = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
39-
/** TX characteristic UUID */
40-
private final static UUID UART_TX_CHARACTERISTIC_UUID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
4141
/** RX characteristic UUID */
42-
private final static UUID UART_RX_CHARACTERISTIC_UUID = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
42+
private final static UUID UART_RX_CHARACTERISTIC_UUID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
43+
/** TX characteristic UUID */
44+
private final static UUID UART_TX_CHARACTERISTIC_UUID = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
45+
/** The maximum packet size is 20 bytes. */
46+
private static final int MAX_PACKET_SIZE = 20;
4347

44-
private BluetoothGattCharacteristic mTXCharacteristic, mRXCharacteristic;
48+
private BluetoothGattCharacteristic mRXCharacteristic, mTXCharacteristic;
49+
private byte[] mOutgoingBuffer;
50+
private int mBufferOffset;
4551

4652
public UARTManager(final Context context) {
4753
super(context);
@@ -60,30 +66,59 @@ protected BleManagerGattCallback getGattCallback() {
6066
@Override
6167
protected Queue<Request> initGatt(final BluetoothGatt gatt) {
6268
final LinkedList<Request> requests = new LinkedList<>();
63-
requests.push(Request.newEnableNotificationsRequest(mRXCharacteristic));
69+
requests.push(Request.newEnableNotificationsRequest(mTXCharacteristic));
6470
return requests;
6571
}
6672

6773
@Override
6874
public boolean isRequiredServiceSupported(final BluetoothGatt gatt) {
6975
final BluetoothGattService service = gatt.getService(UART_SERVICE_UUID);
7076
if (service != null) {
71-
mTXCharacteristic = service.getCharacteristic(UART_TX_CHARACTERISTIC_UUID);
7277
mRXCharacteristic = service.getCharacteristic(UART_RX_CHARACTERISTIC_UUID);
78+
mTXCharacteristic = service.getCharacteristic(UART_TX_CHARACTERISTIC_UUID);
79+
}
80+
81+
boolean writeRequest = false;
82+
boolean writeCommand = false;
83+
if (mRXCharacteristic != null) {
84+
final int rxProperties = mRXCharacteristic.getProperties();
85+
writeRequest = (rxProperties & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0;
86+
writeCommand = (rxProperties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0;
87+
88+
// Set the WRITE REQUEST type when the characteristic supports it. This will allow to send long write (also if the characteristic support it).
89+
// In case there is no WRITE REQUEST property, this manager will divide texts longer then 20 bytes into up to 20 bytes chunks.
90+
if (writeRequest)
91+
mRXCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
7392
}
74-
return mTXCharacteristic != null && mRXCharacteristic != null;
93+
94+
return mRXCharacteristic != null && mTXCharacteristic != null && (writeRequest || writeCommand);
7595
}
7696

7797
@Override
7898
protected void onDeviceDisconnected() {
79-
mTXCharacteristic = null;
8099
mRXCharacteristic = null;
100+
mTXCharacteristic = null;
81101
}
82102

83103
@Override
84104
public void onCharacteristicWrite(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
85-
final String data = characteristic.getStringValue(0);
86-
mCallbacks.onDataSent(data);
105+
// When the whole buffer has been sent
106+
final byte[] buffer = mOutgoingBuffer;
107+
if (mBufferOffset == buffer.length) {
108+
try {
109+
mCallbacks.onDataSent(new String(buffer, "UTF-8"));
110+
} catch (final UnsupportedEncodingException e) {
111+
// do nothing
112+
}
113+
mOutgoingBuffer = null;
114+
} else { // Otherwise...
115+
final int length = Math.min(buffer.length - mBufferOffset, MAX_PACKET_SIZE);
116+
final byte[] data = new byte[length]; // We send at most 20 bytes
117+
System.arraycopy(buffer, mBufferOffset, data, 0, length);
118+
mBufferOffset += length;
119+
mRXCharacteristic.setValue(data);
120+
writeCharacteristic(mRXCharacteristic);
121+
}
87122
}
88123

89124
@Override
@@ -100,13 +135,30 @@ protected boolean shouldAutoConnect() {
100135
}
101136

102137
/**
103-
* Sends the given text to TH characteristic.
138+
* Sends the given text to RX characteristic.
104139
* @param text the text to be sent
105140
*/
106141
public void send(final String text) {
107-
if (mTXCharacteristic != null) {
108-
mTXCharacteristic.setValue(text);
109-
writeCharacteristic(mTXCharacteristic);
142+
// An outgoing buffer may not be null if there is already another packet being sent. We do nothing in this case.
143+
if (!TextUtils.isEmpty(text) && mOutgoingBuffer == null) {
144+
final byte[] buffer = mOutgoingBuffer = text.getBytes();
145+
mBufferOffset = 0;
146+
147+
// Depending on whether the characteristic has the WRITE REQUEST property or not, we will either send it as it is (hoping the long write is implemented),
148+
// or divide it into up to 20 bytes chunks and send them one by one.
149+
final boolean writeRequest = (mRXCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0;
150+
151+
if (!writeRequest) { // no WRITE REQUEST property
152+
final int length = Math.min(buffer.length, MAX_PACKET_SIZE);
153+
final byte[] data = new byte[length]; // We send at most 20 bytes
154+
System.arraycopy(buffer, 0, data, 0, length);
155+
mBufferOffset += length;
156+
mRXCharacteristic.setValue(data);
157+
} else { // there is WRITE REQUEST property
158+
mRXCharacteristic.setValue(buffer);
159+
mBufferOffset = buffer.length;
160+
}
161+
writeCharacteristic(mRXCharacteristic);
110162
}
111163
}
112164
}

app/src/main/res/drawable/background.xml

Lines changed: 0 additions & 34 deletions
This file was deleted.

app/src/main/res/layout-land/activity_feature_bpm.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,13 @@
293293
android:onClick="onConnectClicked"
294294
android:text="@string/action_connect" />
295295

296+
<ImageView
297+
android:layout_width="wrap_content"
298+
android:layout_height="wrap_content"
299+
android:src="@drawable/background_title"
300+
android:layout_alignParentBottom="true"
301+
android:layout_centerHorizontal="true"
302+
android:layout_marginBottom="6dp"/>
303+
296304
</no.nordicsemi.android.nrftoolbox.widget.ForegroundRelativeLayout>
297305
</LinearLayout>

app/src/main/res/layout-land/activity_feature_csc.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,5 +290,13 @@
290290
android:onClick="onConnectClicked"
291291
android:text="@string/action_connect" />
292292

293+
<ImageView
294+
android:layout_width="wrap_content"
295+
android:layout_height="wrap_content"
296+
android:src="@drawable/background_title"
297+
android:layout_alignParentBottom="true"
298+
android:layout_centerHorizontal="true"
299+
android:layout_marginBottom="6dp"/>
300+
293301
</no.nordicsemi.android.nrftoolbox.widget.ForegroundRelativeLayout>
294302
</LinearLayout>

app/src/main/res/layout-land/activity_feature_dfu.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,5 +260,13 @@
260260
android:onClick="onConnectClicked"
261261
android:text="@string/action_select" />
262262

263+
<ImageView
264+
android:layout_width="wrap_content"
265+
android:layout_height="wrap_content"
266+
android:src="@drawable/background_title"
267+
android:layout_alignParentBottom="true"
268+
android:layout_centerHorizontal="true"
269+
android:layout_marginBottom="6dp"/>
270+
263271
</no.nordicsemi.android.nrftoolbox.widget.ForegroundRelativeLayout>
264272
</LinearLayout>

app/src/main/res/layout-land/activity_feature_gls.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,5 +214,13 @@
214214
android:onClick="onConnectClicked"
215215
android:text="@string/action_connect" />
216216

217+
<ImageView
218+
android:layout_width="wrap_content"
219+
android:layout_height="wrap_content"
220+
android:src="@drawable/background_title"
221+
android:layout_alignParentBottom="true"
222+
android:layout_centerHorizontal="true"
223+
android:layout_marginBottom="6dp"/>
224+
217225
</no.nordicsemi.android.nrftoolbox.widget.ForegroundRelativeLayout>
218226
</LinearLayout>

app/src/main/res/layout-land/activity_feature_hrs.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,13 @@
148148
android:onClick="onConnectClicked"
149149
android:text="@string/action_connect" />
150150

151+
<ImageView
152+
android:layout_width="wrap_content"
153+
android:layout_height="wrap_content"
154+
android:src="@drawable/background_title"
155+
android:layout_alignParentBottom="true"
156+
android:layout_centerHorizontal="true"
157+
android:layout_marginBottom="6dp"/>
158+
151159
</no.nordicsemi.android.nrftoolbox.widget.ForegroundRelativeLayout>
152160
</LinearLayout>

0 commit comments

Comments
 (0)