@wisdomgarden/capacitor-plugin-beacon 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGE-LOG.md CHANGED
@@ -3,4 +3,11 @@
3
3
  ### Bug Fixes
4
4
  - Fix (Android): Resolved broadcast failure `ADVERTISE_FAILED_DATA_TOO_LARGE`.
5
5
  - Fix (Android/iOS): Resolved issue where stale/historical messages were received due to system caching.
6
- - Optimization: Standardized logToJsWithTag output format and logical sequence `[SEQ-XX]` .
6
+ - Optimization: Standardized logToJsWithTag output format and logical sequence `[SEQ-XX]` .
7
+
8
+ ## 0.0.3 (2025-12-23)
9
+
10
+ ### Optimize code
11
+ - Logic Optimization: Aligned cross-platform encoding and improved variable-length payload handling.
12
+ - Code Fixes: Resolved naming conflicts and indexing safety issues.
13
+ - Log Refinement: Simplified logs with concise method tags.
@@ -47,10 +47,9 @@ public class BeaconUtils {
47
47
  * @return 编码后的字符串
48
48
  */
49
49
  public static String encode(int num) {
50
- if (num == 0) return String.valueOf(CHARS.charAt(0));
50
+ if (num <= 0) return String.valueOf(CHARS.charAt(0));
51
51
  StringBuilder result = new StringBuilder();
52
- boolean isNegative = num < 0;
53
- int n = Math.abs(num);
52
+ int n = num;
54
53
 
55
54
  while (n > 0) {
56
55
  int remainder = n % RADIX;
@@ -58,7 +57,7 @@ public class BeaconUtils {
58
57
  n /= RADIX;
59
58
  }
60
59
 
61
- return isNegative ? "-" + result.toString() : result.toString();
60
+ return result.toString();
62
61
  }
63
62
 
64
63
  /**
@@ -87,8 +86,7 @@ public class BeaconUtils {
87
86
  * @return 如果是 nonce 字母返回 true,否则返回 false
88
87
  */
89
88
  public static boolean isNonceLetter(char c) {
90
- int code = (int) c;
91
- return code >= 84 && code <= 90;
89
+ return c >= 'T' && c <= 'Z';
92
90
  }
93
91
 
94
92
  /**
@@ -120,17 +118,16 @@ public class BeaconUtils {
120
118
  payload.put("rollcallId", 0);
121
119
  payload.put("nonce", "");
122
120
 
123
- if (message == null) {
121
+ if (message == null || message.isEmpty()) {
124
122
  return payload;
125
123
  }
126
124
 
127
125
  for (int i = 0; i < message.length(); i++) {
128
- char c = message.charAt(i);
129
- if (isNonceLetter(c)) {
126
+ if (isNonceLetter(message.charAt(i))) {
130
127
  String rollcallIdStr = message.substring(0, i);
131
128
  payload.put("rollcallId", decode(rollcallIdStr));
132
129
  payload.put("nonce", message.substring(i));
133
- break;
130
+ return payload;
134
131
  }
135
132
  }
136
133
 
@@ -171,25 +168,25 @@ public class BeaconUtils {
171
168
  */
172
169
  public static String extractMessageFromBytes(byte[] data) {
173
170
  if (data == null) {
174
- Log.w(TAG, "[extractMessageFromBytes] data is null");
171
+ Log.w(TAG, "[extractBytes] data is null");
175
172
  return null;
176
173
  }
177
174
 
178
175
  // Total length must be: length of WG_PREFIX_BYTES + length of message
179
176
  int expectedLength = WG_PREFIX_BYTES.length + MESSAGE_MAX_LENGTH;
180
177
 
181
- if (data.length != expectedLength) {
182
- Log.w(TAG, "[extractMessageFromBytes] Byte length mismatch. Expected: " + expectedLength + ", Got: " + data.length);
178
+ if (data.length < WG_PREFIX_BYTES.length || data.length > expectedLength) {
179
+ Log.w(TAG, "[extractBytes] Length out of bounds. Max: " + expectedLength + ", Got: " + data.length);
183
180
  return null;
184
181
  }
185
182
  for (int i = 0; i < WG_PREFIX_BYTES.length; i++) {
186
183
  if (data[i] != WG_PREFIX_BYTES[i]) {
187
- Log.v(TAG, "[extractMessageFromBytes] Prefix mismatch at byte " + i);
188
184
  return null;
189
185
  }
190
186
  }
191
- String extracted = new String(data, WG_PREFIX_BYTES.length, MESSAGE_MAX_LENGTH, StandardCharsets.US_ASCII);
192
- Log.i(TAG, "[extractMessageFromBytes] Successfully extracted message from bytes: " + extracted);
187
+ int payloadLength = data.length - WG_PREFIX_BYTES.length;
188
+ String extracted = new String(data, WG_PREFIX_BYTES.length, payloadLength, StandardCharsets.US_ASCII);
189
+ Log.i(TAG, "[extractBytes] Successfully extracted message from bytes: " + extracted);
193
190
  return extracted;
194
191
  }
195
192
 
@@ -199,21 +196,20 @@ public class BeaconUtils {
199
196
  * where the message is prefixed with "WG" and advertised as the device's name.
200
197
  */
201
198
  public static String extractMessageFromDeviceName(String message) {
202
- if (message == null) {
203
- Log.w(TAG, "[extractMessageFromDeviceName] message is null");
199
+ if (message == null || message.isEmpty()) {
200
+ Log.w(TAG, "[extractName] message is null");
204
201
  return null;
205
202
  }
206
203
  if (!message.startsWith(WG_PREFIX)) {
207
- Log.w(TAG, "[extractMessageFromDeviceName] message does not start with prefix.message is " + message);
208
204
  return null;
209
205
  }
210
- int fullLength = WG_PREFIX.length() + MESSAGE_MAX_LENGTH;
211
- if (message.length() != fullLength) {
212
- Log.w(TAG, "[extractMessageFromDeviceName] message length mismatch. Expected: " + fullLength + ", Got: " + message.length());
206
+ int expectedLength = WG_PREFIX.length() + MESSAGE_MAX_LENGTH;
207
+ if (message.length() > expectedLength) {
208
+ Log.w(TAG, "[extractName] Length out of bounds. Max: " + expectedLength + ", Got: " + message.length());
213
209
  return null;
214
210
  }
215
- String extracted= message.substring(WG_PREFIX.length());
216
- Log.i(TAG, "[extractMessageFromDeviceName] Successfully extracted message from device name: " + extracted);
211
+ String extracted = message.substring(WG_PREFIX.length());
212
+ Log.i(TAG, "[extractName] Successfully. " + extracted);
217
213
  return extracted;
218
214
  }
219
215
  }
@@ -1,7 +1,7 @@
1
1
  import Foundation
2
2
 
3
3
  public struct BeaconUtils {
4
- /**
4
+ /**
5
5
  * 16-bit Bluetooth Short UUID (0x5747)
6
6
  * Logic & Rationale:
7
7
  * 1. Represents the hex characters for 'WG' (W=0x57, G=0x47).
@@ -32,14 +32,13 @@ public struct BeaconUtils {
32
32
  public static let message_max_length = 11
33
33
 
34
34
  private static let chars =
35
- "2O9AuFNPDx4gtJwS3ye7l1Mq0dEB5HsaKInikRmLhjpG6b8fzQrCcvo"
35
+ "2O9AuFNPDx4gtJwS3ye7l1Mq0dEB5HsaKInikRmLhjpG6b8fzQrCcvo"
36
36
  private static let radix = chars.count
37
37
 
38
38
  public static func encode(_ num: Int) -> String {
39
- if num == 0 { return String(chars[chars.startIndex]) }
39
+ if num <= 0 { return String(chars[chars.startIndex]) }
40
40
  var result = ""
41
- let isNegative = num < 0
42
- var n = abs(num)
41
+ var n = num
43
42
 
44
43
  while n > 0 {
45
44
  let remainder = n % radix
@@ -48,7 +47,7 @@ public struct BeaconUtils {
48
47
  n /= radix
49
48
  }
50
49
 
51
- return isNegative ? "-" + result : result
50
+ return result
52
51
  }
53
52
 
54
53
  public static func decode(_ str: String) -> Int {
@@ -56,8 +55,8 @@ public struct BeaconUtils {
56
55
  for char in str {
57
56
  if let index = chars.firstIndex(of: char) {
58
57
  num =
59
- num * radix
60
- + chars.distance(from: chars.startIndex, to: index)
58
+ num * radix
59
+ + chars.distance(from: chars.startIndex, to: index)
61
60
  } else {
62
61
  return 0
63
62
  }
@@ -65,46 +64,29 @@ public struct BeaconUtils {
65
64
  return num
66
65
  }
67
66
 
67
+ // 检查字符是否为 nonce 字母,T-Z
68
+ func isNonceLetter(_ c: Character) -> Bool {
69
+ return c >= "T" && c <= "Z"
70
+ }
71
+
68
72
  public static func parseMessage(_ message: String?) -> [String: Any] {
69
73
  var payload: [String: Any] = [
70
74
  "rollcallId": 0,
71
75
  "nonce": "",
72
76
  ]
73
77
 
74
- guard let message = message else {
78
+ guard let message = message, !message.isEmpty else {
75
79
  return payload
76
80
  }
77
81
 
78
- if message.count < message_max_length {
79
- return payload
80
- }
81
-
82
- // 检查字符是否为 nonce 字母,T-Z
83
- func isNonceLetter(_ c: Character) -> Bool {
84
- let code = c.asciiValue ?? 0
85
- return code >= 84 && code <= 90
86
- }
87
-
88
82
  for (i, char) in message.enumerated() {
89
83
  if isNonceLetter(char) {
90
- let rollcallIdStr = String(
91
- message[
92
- ..<message.index(
93
- message.startIndex,
94
- offsetBy: i
95
- )
96
- ]
97
- )
84
+ let splitIndex = message.index(message.startIndex, offsetBy: i)
85
+
86
+ let rollcallIdStr = String(message[..<splitIndex])
98
87
  payload["rollcallId"] = decode(rollcallIdStr)
99
88
 
100
- let nonceStr = String(
101
- message[
102
- message.index(
103
- message.startIndex,
104
- offsetBy: i
105
- )...
106
- ]
107
- )
89
+ let nonceStr = String(message[splitIndex...])
108
90
  payload["nonce"] = nonceStr
109
91
  break
110
92
  }
@@ -117,17 +99,16 @@ public struct BeaconUtils {
117
99
  public static func buildMessage(rollcallId: Int, nonce: String) -> String {
118
100
  let rollcallIdStr = encode(rollcallId)
119
101
 
120
- guard !nonce.isEmpty, let firstChar = nonce.first else {
102
+ guard !nonce.isEmpty else {
121
103
  return rollcallIdStr + "Z"
122
104
  }
123
105
 
124
- let remainingChars = String(nonce.dropFirst())
125
-
126
106
  let message = rollcallIdStr + nonce
127
107
  return message.count > message_max_length
128
- ? String(message.prefix(message_max_length)) : message
108
+ ? String(message.prefix(message_max_length)) : message
129
109
  }
130
110
 
111
+
131
112
  /**
132
113
  * Prepends the protocol prefix "WG" to the message string.
133
114
  * This is used for iOS advertising, where the identifier is placed in the
@@ -144,27 +125,28 @@ public struct BeaconUtils {
144
125
  * length matches the protocol specification before returning the decoded string.
145
126
  */
146
127
  public static func extractMessageFromBytes(_ data: Data) -> String? {
147
- // 2 bytes(CompanyID) + 2 bytes(Magic) + 11 bytes(Msg) = 15
148
- let expectedVendorLength = 2 + WG_PREFIX_BYTES.count + message_max_length
149
- guard data.count == expectedVendorLength else {
150
- print("[extractMessageFromBytes] Extraction failed: Invalid byte length (\(data.count)). Expected \(expectedVendorLength).")
128
+ // Android Logic: CompanyID(2 bytes) + (Prefix)2 bytes + Msg(11 bytes) = 15
129
+ let minLength = 2 + WG_PREFIX_BYTES.count // 4 bytes
130
+ let maxLength = minLength + message_max_length // 15 bytes
131
+
132
+ guard data.count >= minLength && data.count <= maxLength else {
133
+ print("[extractBytes] Length out of bounds: \(data.count)")
151
134
  return nil
152
135
  }
153
136
 
154
137
  let bytes = [UInt8](data)
155
138
  // Check "WG" magic bytes at index 2 and 3 (after 0xFFFF Company ID)
156
139
  guard bytes[2] == WG_PREFIX_BYTES[0], bytes[3] == WG_PREFIX_BYTES[1] else {
157
- print("[extractMessageFromBytes] Extraction failed: Magic bytes prefix mismatch.")
158
140
  return nil
159
141
  }
160
142
 
161
143
  let messageData = data.subdata(in: 4..<data.count)
162
144
  if let extracted = String(data: messageData, encoding: .ascii) {
163
- print("[extractMessageFromBytes] Successfully extracted message from bytes: \(extracted)")
145
+ print("[extractBytes] Successfully: \(extracted)")
164
146
  return extracted
165
147
  }
166
148
 
167
- print("[extractMessageFromBytes] Extraction failed: Data is not valid ASCII.")
149
+ print("[extractBytes] ASCII error")
168
150
  return nil
169
151
  }
170
152
 
@@ -174,17 +156,15 @@ public struct BeaconUtils {
174
156
  * where the message is prefixed with "WG" and advertised as the device's name.
175
157
  */
176
158
  public static func extractMessageFromDeviceName(_ message: String) -> String? {
177
- guard deviceName.hasPrefix(WG_PREFIX) else {
178
- return nil
179
- }
159
+ guard message.hasPrefix(WG_PREFIX) else { return nil }
180
160
 
181
- let fullLength = WG_PREFIX.count + message_max_length
182
- if deviceName.count == fullLength {
183
- let extracted = String(deviceName.dropFirst(WG_PREFIX.count))
184
- print("[extractMessageFromDeviceName] Successfully extracted message from Device Name: \(extracted)")
161
+ let maxFullLength = WG_PREFIX.count + message_max_length
162
+ if message.count <= maxFullLength {
163
+ let extracted = String(message.dropFirst(WG_PREFIX.count))
164
+ print("[extractName] Successfully: \(extracted)")
185
165
  return extracted
186
166
  } else {
187
- print("[extractMessageFromDeviceName] Device Name prefix matched, but length was invalid: \(deviceName.count)")
167
+ print("[extractName] Too long: \(message.count)")
188
168
  return nil
189
169
  }
190
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wisdomgarden/capacitor-plugin-beacon",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Capacitor plugin for Bluetooth beacon broadcasting and monitoring",
5
5
  "main": "dist/plugin.js",
6
6
  "module": "dist/esm/index.js",