mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-09-20 05:17:11 -04:00
Modify code to support minor API versions
This commit is contained in:
1 parent
6ea1d9ec73
commit
3c917da56a
4 files changed
+47
-18
No files matched your search
@@ -148,10 +148,10 @@ class BluetoothServerService : Service() {
|
||||
val firstLine = reader.readLine()?.trim() ?: return
|
||||
|
||||
if (firstLine == WearBluetoothProtocol.BT_CMD_VERSIONS) {
|
||||
val versions = JSONArray().put(WearBluetoothProtocol.PROTOCOL_VERSION).toString()
|
||||
val versions = JSONArray().put("${WearBluetoothProtocol.PROTOCOL_VERSION}.${WearBluetoothProtocol.PROTOCOL_MINOR_VERSION}").toString()
|
||||
writer.println(versions)
|
||||
writer.flush()
|
||||
Log.d(TAG, "Sent supported versions to $deviceName")
|
||||
Log.d(TAG, "Sent supported versions to $deviceName: $versions")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+27
-11
@@ -14,7 +14,14 @@ The Bluetooth server is currently only used by the Catima WearOS companion app.
|
||||
|
||||
## API versions
|
||||
|
||||
There is currently only a single API version. Version 1.
|
||||
For each API version, we have a major and a minor version. The rules for versioning are as follows:
|
||||
1. A new minor version may add fields or endpoints, but must never modify or remove existing fields or endpoints.
|
||||
2. A new minor version must not change any authentication systems compared to the previous minor version.
|
||||
3. A device cannot request Catima to use a specific minor version, it will always return data as per the most recently supported minor version.
|
||||
|
||||
The main driver of compatibility is the major version.
|
||||
|
||||
Due to this system, a device only supporting API version 1.0 can talk to Catima supporting API version 1.1 with no issues, as long as it ignores fields it doesn't know. On the other side, a device wanting to use API version 1.1 with Catima on API version 1.0 has to accept certain fields may not be available. Which minor version introduces which additional fields and endpoints is documented in this file.
|
||||
|
||||
### Unversioned
|
||||
|
||||
@@ -22,11 +29,20 @@ There is currently only a single API version. Version 1.
|
||||
|
||||
Return type: JSON.
|
||||
|
||||
Value:
|
||||
Returns all supported major versions and the most recent supported minor version.
|
||||
|
||||
Example request:
|
||||
```
|
||||
[1]
|
||||
/VERSIONS
|
||||
```
|
||||
|
||||
Example return value:
|
||||
```
|
||||
["1.0"]
|
||||
```
|
||||
|
||||
In this example case, the phone supports only API version 1. Of API version 1, the most recent minor version supported is 0.
|
||||
|
||||
### V1
|
||||
|
||||
All V1 endpoints are authenticated and must be communicated with by sending 2 lines over an RfConn socket. First the full command, then a device-specific token (recommended: a base64-encoded version of a 32 characters long SecureRandom-generated string).
|
||||
@@ -47,14 +63,14 @@ Request a single page of cards with page and total page details. The page ID is
|
||||
|
||||
Each card contains the following fields:
|
||||
|
||||
| Column | Type | Description |
|
||||
|-------------------|-------------------|----------------------------|
|
||||
| `id` | `int` | Unique card ID |
|
||||
| `store` | `String` | Card name |
|
||||
| `cardId` | `String` | Card ID. |
|
||||
| `barcodeId` | `Nullable String` | Barcode value. If empty, it's the same as the card ID. |
|
||||
| `barcodeType` | `Nullable String` | The barcode type name, matching [com.google.zxing.BarcodeFormat](https://zxing.github.io/zxing/apidocs/com/google/zxing/BarcodeFormat.html). When null, there is no barcode for this card. |
|
||||
| `headerColor` | `int` | Header color, matching [Android color int](https://developer.android.com/reference/android/graphics/Color). |
|
||||
| Column | Type | Description | Introduced in minor version |
|
||||
|-------------------|-------------------|----------------------------| --------------------------- |
|
||||
| `id` | `int` | Unique card ID | 0 |
|
||||
| `store` | `String` | Card name | 0 |
|
||||
| `cardId` | `String` | Card ID. | 0 |
|
||||
| `barcodeId` | `Nullable String` | Barcode value. If empty, it's the same as the card ID. | 0 |
|
||||
| `barcodeType` | `Nullable String` | The barcode type name, matching [com.google.zxing.BarcodeFormat](https://zxing.github.io/zxing/apidocs/com/google/zxing/BarcodeFormat.html). When null, there is no barcode for this card. | 0 |
|
||||
| `headerColor` | `int` | Header color, matching [Android color int](https://developer.android.com/reference/android/graphics/Color). | 0 |
|
||||
|
||||
Example request:
|
||||
```
|
||||
|
||||
@@ -6,6 +6,7 @@ object WearBluetoothProtocol {
|
||||
val BT_SERVICE_UUID: UUID = UUID.fromString("e5b4f020-3a7e-4b6d-9f2c-1a8c5d3e7f90")
|
||||
const val BT_SERVICE_NAME = "CatimaWear"
|
||||
const val PROTOCOL_VERSION = 1
|
||||
const val PROTOCOL_MINOR_VERSION = 0
|
||||
const val BT_CMD_VERSIONS = "/VERSIONS"
|
||||
const val BT_CMD_TOKEN_PREFIX = "TOKEN:"
|
||||
const val BT_CMD_VERSION_PREFIX = "/V$PROTOCOL_VERSION/"
|
||||
|
||||
@@ -97,13 +97,25 @@ object BluetoothCardClient {
|
||||
socket.connect()
|
||||
val supportedVersions = requestSupportedVersions(socket)
|
||||
?: return null to SyncStatus.PHONE_NOT_REACHABLE
|
||||
if (WearBluetoothProtocol.PROTOCOL_VERSION !in supportedVersions) {
|
||||
Log.w(TAG, "Phone does not support API version ${WearBluetoothProtocol.PROTOCOL_VERSION}")
|
||||
var majorVersionIsSupported = false
|
||||
var mostRecentMinorVersion = -1
|
||||
run breaking@{
|
||||
supportedVersions.forEach {
|
||||
val supportedVersionParts = it.split('.')
|
||||
if (supportedVersionParts[0] == WearBluetoothProtocol.PROTOCOL_VERSION.toString()) {
|
||||
majorVersionIsSupported = true
|
||||
mostRecentMinorVersion = supportedVersionParts[1].toInt()
|
||||
return@breaking
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!majorVersionIsSupported) {
|
||||
Log.w(TAG, "Phone does not support major API version ${WearBluetoothProtocol.PROTOCOL_VERSION}")
|
||||
return null to SyncStatus.VERSION_INCOMPATIBLE
|
||||
}
|
||||
socket.close()
|
||||
socket = null
|
||||
Log.d(TAG, "Connected to $deviceName with API version ${WearBluetoothProtocol.PROTOCOL_VERSION}")
|
||||
Log.d(TAG, "Connected to $deviceName with major API version ${WearBluetoothProtocol.PROTOCOL_VERSION}, phone supports up to minor API version ${mostRecentMinorVersion}, we can use up to ${WearBluetoothProtocol.PROTOCOL_MINOR_VERSION}")
|
||||
|
||||
socket = device.createRfcommSocketToServiceRecord(WearBluetoothProtocol.BT_SERVICE_UUID)
|
||||
socket.connect()
|
||||
@@ -173,7 +185,7 @@ object BluetoothCardClient {
|
||||
writer.println("${WearBluetoothProtocol.BT_CMD_TOKEN_PREFIX}$token")
|
||||
}
|
||||
|
||||
private fun requestSupportedVersions(socket: BluetoothSocket): Set<Int>? {
|
||||
private fun requestSupportedVersions(socket: BluetoothSocket): Set<String>? {
|
||||
val writer = PrintWriter(OutputStreamWriter(socket.outputStream, "UTF-8"), false)
|
||||
val reader = BufferedReader(InputStreamReader(socket.inputStream, "UTF-8"))
|
||||
writer.print("${WearBluetoothProtocol.BT_CMD_VERSIONS}\n")
|
||||
@@ -183,7 +195,7 @@ object BluetoothCardClient {
|
||||
val versions = JSONArray(response)
|
||||
buildSet {
|
||||
for (index in 0 until versions.length()) {
|
||||
add(versions.getInt(index))
|
||||
add(versions.getString(index))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
||||
Reference in new issue
Block a user