Skip to content

Commit 47a08d5

Browse files
committed
Implemented message splitter for ios ble server
1 parent 141872b commit 47a08d5

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

ios/BLEServer.swift

+39-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class BLEServer: NSObject, CBPeripheralManagerDelegate {
2424

2525
private var advertiseCompletion: ((Result<Any?, BLEError>) -> Void)?
2626

27+
private var outboundQueue: [Data] = []
28+
2729
func isReady() -> Bool {
2830
return true
2931
}
@@ -66,8 +68,17 @@ class BLEServer: NSObject, CBPeripheralManagerDelegate {
6668
return
6769
}
6870

69-
// TODO: implement message splitter
70-
peripheralManager.updateValue(Data(message.appending("\0").utf8), for: characteristic, onSubscribedCentrals: nil)
71+
let chunks = splitMessage(data: Data(message.utf8), maxChunkLength: 180)
72+
73+
for i in chunks.indices {
74+
let result = peripheralManager.updateValue(chunks[i], for: characteristic, onSubscribedCentrals: nil)
75+
if !result {
76+
log(tag: tag, message: "Cannot send the update chunk, the internal queue is full, adding to our own queue")
77+
outboundQueue.append(contentsOf: chunks.dropFirst(i))
78+
break
79+
}
80+
}
81+
7182
}
7283

7384
func finish() -> Void {
@@ -128,6 +139,32 @@ class BLEServer: NSObject, CBPeripheralManagerDelegate {
128139
}
129140
}
130141

142+
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
143+
// peripheral is ready to send updates again, taking from the queue
144+
log(tag: tag, message: "Peripheral is ready to send updates again")
145+
guard let characteristic = characteristic else {
146+
log(tag: tag, message: "Characteristic is nil after sending some updates, this should not happen, something went terribly wrong")
147+
return
148+
}
149+
150+
var updateResult = false
151+
152+
repeat {
153+
if outboundQueue.isEmpty {
154+
break
155+
}
156+
157+
let nextUpdate = outboundQueue.removeFirst()
158+
updateResult = peripheral.updateValue(nextUpdate, for: characteristic, onSubscribedCentrals: nil)
159+
160+
if !updateResult {
161+
log(tag: tag, message: "Cannot send the update chunk, the internal queue is full, returning to our own queue")
162+
outboundQueue.insert(nextUpdate, at: 0)
163+
}
164+
165+
} while !outboundQueue.isEmpty && updateResult
166+
}
167+
131168
private func handleWriteRequest(request: CBATTRequest) {
132169
log(tag: tag, message: "Handling write request")
133170

ios/Ble.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
63048A562934165300EC7BF5 /* BLEServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63048A552934165300EC7BF5 /* BLEServer.swift */; };
11+
6338BC482934F981003286FE /* MessageSplitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6338BC472934F981003286FE /* MessageSplitter.swift */; };
1112
6373FBEE290D6E5F00DB22BB /* BLEModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6373FBED290D6E5F00DB22BB /* BLEModule.swift */; };
1213
6373FBF5290D714400DB22BB /* BLEModuleExport.m in Sources */ = {isa = PBXBuildFile; fileRef = 6373FBF4290D714400DB22BB /* BLEModuleExport.m */; };
1314
639275CA290ED3AD00713511 /* BLEEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639275C9290ED3AD00713511 /* BLEEventType.swift */; };
@@ -34,6 +35,7 @@
3435
/* Begin PBXFileReference section */
3536
4523902D931F99DFFA85303A /* Pods-Ble.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Ble.release.xcconfig"; path = "Target Support Files/Pods-Ble/Pods-Ble.release.xcconfig"; sourceTree = "<group>"; };
3637
63048A552934165300EC7BF5 /* BLEServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BLEServer.swift; sourceTree = "<group>"; };
38+
6338BC472934F981003286FE /* MessageSplitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSplitter.swift; sourceTree = "<group>"; };
3739
6373FBED290D6E5F00DB22BB /* BLEModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BLEModule.swift; sourceTree = "<group>"; };
3840
6373FBF2290D6F0400DB22BB /* Ble-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Ble-Bridging-Header.h"; sourceTree = "<group>"; };
3941
6373FBF4290D714400DB22BB /* BLEModuleExport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BLEModuleExport.m; sourceTree = "<group>"; };
@@ -79,6 +81,7 @@
7981
58B511D21A9E6C8500147676 = {
8082
isa = PBXGroup;
8183
children = (
84+
6338BC472934F981003286FE /* MessageSplitter.swift */,
8285
63048A552934165300EC7BF5 /* BLEServer.swift */,
8386
639275C9290ED3AD00713511 /* BLEEventType.swift */,
8487
63A673EB290EA10F00D80A11 /* Peripheral.swift */,
@@ -191,6 +194,7 @@
191194
6373FBEE290D6E5F00DB22BB /* BLEModule.swift in Sources */,
192195
639275CA290ED3AD00713511 /* BLEEventType.swift in Sources */,
193196
6373FBF5290D714400DB22BB /* BLEModuleExport.m in Sources */,
197+
6338BC482934F981003286FE /* MessageSplitter.swift in Sources */,
194198
63A673E4290E7EDB00D80A11 /* BLEClient.swift in Sources */,
195199
63A673E6290E7F0400D80A11 /* Constants.swift in Sources */,
196200
63048A562934165300EC7BF5 /* BLEServer.swift in Sources */,

ios/MessageSplitter.swift

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// MessageSplitter.swift
3+
// Ble
4+
//
5+
// Created by AndrewNadraliev on 28.11.2022.
6+
// Copyright © 2022 Facebook. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
func splitMessage(data: Data, maxChunkLength: Int) -> [Data] {
12+
if data.isEmpty {
13+
return []
14+
}
15+
16+
var result: [Data] = []
17+
18+
var index = 0
19+
20+
repeat {
21+
let bottomBar = index * maxChunkLength
22+
let upperBar = min(data.count, (index + 1) * maxChunkLength)
23+
24+
result.append(data.subdata(in: bottomBar..<upperBar))
25+
26+
index += 1
27+
} while index * maxChunkLength < data.count
28+
29+
let lastChunk = result.last
30+
31+
if var lastChunk = lastChunk, lastChunk.count < maxChunkLength {
32+
// there is enough space for terminal operator
33+
lastChunk.append(contentsOf: [0])
34+
result[result.count - 1] = lastChunk
35+
} else {
36+
// not enough space in the last chunk, create a new one
37+
result.append(Data(repeating: 0, count: 1))
38+
}
39+
40+
return result
41+
}

ios/Utils.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010

1111
func log(tag: String, message: String, error: Error? = nil) {
1212
if let error = error {
13-
NSLog("%s: %s \n %s", tag, message, error.localizedDescription)
13+
NSLog("%@: %@ \n %@", tag, message, error.localizedDescription)
1414
} else {
1515
NSLog("%@: %@", tag, message)
1616
}

0 commit comments

Comments
 (0)