mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 18:25:19 +00:00
Use unique transfer identifiers
This commit is contained in:
@@ -707,7 +707,7 @@ final class BLEService: NSObject {
|
|||||||
sendPrivateMessage(content, to: peerID.id, messageID: messageID)
|
sendPrivateMessage(content, to: peerID.id, messageID: messageID)
|
||||||
|
|
||||||
|
|
||||||
func sendFileBroadcast(_ filePacket: BitchatFilePacket) {
|
func sendFileBroadcast(_ filePacket: BitchatFilePacket, transferId: String) {
|
||||||
messageQueue.async { [weak self] in
|
messageQueue.async { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
guard let payload = filePacket.encode() else {
|
guard let payload = filePacket.encode() else {
|
||||||
@@ -731,12 +731,12 @@ final class BLEService: NSObject {
|
|||||||
self.messageDeduplicator.markProcessed(dedupID)
|
self.messageDeduplicator.markProcessed(dedupID)
|
||||||
|
|
||||||
SecureLogger.debug("📁 Broadcasting file transfer payload bytes=\(payload.count)", category: .session)
|
SecureLogger.debug("📁 Broadcasting file transfer payload bytes=\(payload.count)", category: .session)
|
||||||
self.broadcastPacket(packet)
|
self.broadcastPacket(packet, transferId: transferId)
|
||||||
self.gossipSyncManager?.onPublicPacketSeen(packet)
|
self.gossipSyncManager?.onPublicPacketSeen(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendFilePrivate(_ filePacket: BitchatFilePacket, to peerID: PeerID) {
|
func sendFilePrivate(_ filePacket: BitchatFilePacket, to peerID: PeerID, transferId: String) {
|
||||||
messageQueue.async { [weak self] in
|
messageQueue.async { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
guard let payload = filePacket.encode() else {
|
guard let payload = filePacket.encode() else {
|
||||||
@@ -764,7 +764,7 @@ final class BLEService: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SecureLogger.debug("📁 Sending private file transfer to \(peerID.prefix(8))… bytes=\(payload.count)", category: .session)
|
SecureLogger.debug("📁 Sending private file transfer to \(peerID.prefix(8))… bytes=\(payload.count)", category: .session)
|
||||||
self.broadcastPacket(packet)
|
self.broadcastPacket(packet, transferId: transferId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -841,11 +841,11 @@ final class BLEService: NSObject {
|
|||||||
|
|
||||||
// MARK: - Packet Broadcasting
|
// MARK: - Packet Broadcasting
|
||||||
|
|
||||||
private func broadcastPacket(_ packet: BitchatPacket) {
|
private func broadcastPacket(_ packet: BitchatPacket, transferId: String? = nil) {
|
||||||
// Encode once using a small per-type padding policy, then delegate by type
|
// Encode once using a small per-type padding policy, then delegate by type
|
||||||
let padForBLE = padPolicy(for: packet.type)
|
let padForBLE = padPolicy(for: packet.type)
|
||||||
if packet.type == MessageType.fileTransfer.rawValue {
|
if packet.type == MessageType.fileTransfer.rawValue {
|
||||||
sendFragmentedPacket(packet, pad: padForBLE, maxChunk: nil, directedOnlyPeer: nil)
|
sendFragmentedPacket(packet, pad: padForBLE, maxChunk: nil, directedOnlyPeer: nil, transferId: transferId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard let data = packet.toBinaryData(padding: padForBLE) else {
|
guard let data = packet.toBinaryData(padding: padForBLE) else {
|
||||||
@@ -1106,7 +1106,7 @@ final class BLEService: NSObject {
|
|||||||
|
|
||||||
// MARK: - Fragmentation (Required for messages > BLE MTU)
|
// MARK: - Fragmentation (Required for messages > BLE MTU)
|
||||||
|
|
||||||
private func sendFragmentedPacket(_ packet: BitchatPacket, pad: Bool, maxChunk: Int? = nil, directedOnlyPeer: String? = nil) {
|
private func sendFragmentedPacket(_ packet: BitchatPacket, pad: Bool, maxChunk: Int? = nil, directedOnlyPeer: String? = nil, transferId: String? = nil) {
|
||||||
guard let fullData = packet.toBinaryData(padding: pad) else { return }
|
guard let fullData = packet.toBinaryData(padding: pad) else { return }
|
||||||
// Fragment the unpadded frame; each fragment will be encoded independently
|
// Fragment the unpadded frame; each fragment will be encoded independently
|
||||||
|
|
||||||
@@ -1134,9 +1134,9 @@ final class BLEService: NSObject {
|
|||||||
}
|
}
|
||||||
let perFragMs = (directedOnlyPeer != nil || packet.recipientID != nil) ? TransportConfig.bleFragmentSpacingDirectedMs : TransportConfig.bleFragmentSpacingMs
|
let perFragMs = (directedOnlyPeer != nil || packet.recipientID != nil) ? TransportConfig.bleFragmentSpacingDirectedMs : TransportConfig.bleFragmentSpacingMs
|
||||||
|
|
||||||
let transferId: String? = {
|
let transferIdentifier: String? = {
|
||||||
guard packet.type == MessageType.fileTransfer.rawValue else { return nil }
|
guard packet.type == MessageType.fileTransfer.rawValue else { return nil }
|
||||||
let id = packet.payload.sha256Hex()
|
let id = transferId ?? packet.payload.sha256Hex()
|
||||||
collectionsQueue.sync(flags: .barrier) {
|
collectionsQueue.sync(flags: .barrier) {
|
||||||
self.activeTransfers[id] = ActiveTransferState(totalFragments: totalFragments, sentFragments: 0, workItems: [])
|
self.activeTransfers[id] = ActiveTransferState(totalFragments: totalFragments, sentFragments: 0, workItems: [])
|
||||||
}
|
}
|
||||||
@@ -1171,12 +1171,12 @@ final class BLEService: NSObject {
|
|||||||
|
|
||||||
let workItem = DispatchWorkItem { [weak self] in
|
let workItem = DispatchWorkItem { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
if let transferId = transferId {
|
if let transferId = transferIdentifier {
|
||||||
let isActive = self.collectionsQueue.sync { self.activeTransfers[transferId] != nil }
|
let isActive = self.collectionsQueue.sync { self.activeTransfers[transferId] != nil }
|
||||||
guard isActive else { return }
|
guard isActive else { return }
|
||||||
}
|
}
|
||||||
self.broadcastPacket(fragmentPacket)
|
self.broadcastPacket(fragmentPacket)
|
||||||
if let transferId = transferId {
|
if let transferId = transferIdentifier {
|
||||||
self.markFragmentSent(transferId: transferId)
|
self.markFragmentSent(transferId: transferId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1184,7 @@ final class BLEService: NSObject {
|
|||||||
scheduledItems.append((item: workItem, index: index))
|
scheduledItems.append((item: workItem, index: index))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let transferId = transferId {
|
if let transferId = transferIdentifier {
|
||||||
let workItems = scheduledItems.map { $0.item }
|
let workItems = scheduledItems.map { $0.item }
|
||||||
collectionsQueue.async(flags: .barrier) { [weak self] in
|
collectionsQueue.async(flags: .barrier) { [weak self] in
|
||||||
guard let self = self, var state = self.activeTransfers[transferId] else { return }
|
guard let self = self, var state = self.activeTransfers[transferId] else { return }
|
||||||
|
|||||||
@@ -2386,6 +2386,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
let targetPeer = selectedPrivateChatPeer
|
let targetPeer = selectedPrivateChatPeer
|
||||||
let message = enqueueMediaMessage(content: "[voice] \(url.path)", targetPeer: targetPeer)
|
let message = enqueueMediaMessage(content: "[voice] \(url.path)", targetPeer: targetPeer)
|
||||||
let messageID = message.id
|
let messageID = message.id
|
||||||
|
let transferId = makeTransferID(messageID: messageID)
|
||||||
|
|
||||||
Task.detached(priority: .userInitiated) { [weak self] in
|
Task.detached(priority: .userInitiated) { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
@@ -2406,13 +2407,12 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
content: data
|
content: data
|
||||||
)
|
)
|
||||||
guard let payload = packet.encode() else { throw MediaSendError.encodingFailed }
|
guard let payload = packet.encode() else { throw MediaSendError.encodingFailed }
|
||||||
let transferId = payload.sha256Hex()
|
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
self.registerTransfer(transferId: transferId, messageID: messageID)
|
self.registerTransfer(transferId: transferId, messageID: messageID)
|
||||||
if let peerID = targetPeer {
|
if let peerID = targetPeer {
|
||||||
self.meshService.sendFilePrivate(packet, to: peerID)
|
self.meshService.sendFilePrivate(packet, to: peerID, transferId: transferId)
|
||||||
} else {
|
} else {
|
||||||
self.meshService.sendFileBroadcast(packet)
|
self.meshService.sendFileBroadcast(packet, transferId: transferId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -2450,15 +2450,15 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
content: data
|
content: data
|
||||||
)
|
)
|
||||||
guard let payload = packet.encode() else { throw MediaSendError.encodingFailed }
|
guard let payload = packet.encode() else { throw MediaSendError.encodingFailed }
|
||||||
let transferId = payload.sha256Hex()
|
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
let message = self.enqueueMediaMessage(content: "[image] \(outputURL.path)", targetPeer: targetPeer)
|
let message = self.enqueueMediaMessage(content: "[image] \(outputURL.path)", targetPeer: targetPeer)
|
||||||
let messageID = message.id
|
let messageID = message.id
|
||||||
|
let transferId = self.makeTransferID(messageID: messageID)
|
||||||
self.registerTransfer(transferId: transferId, messageID: messageID)
|
self.registerTransfer(transferId: transferId, messageID: messageID)
|
||||||
if let peerID = targetPeer {
|
if let peerID = targetPeer {
|
||||||
self.meshService.sendFilePrivate(packet, to: peerID)
|
self.meshService.sendFilePrivate(packet, to: peerID, transferId: transferId)
|
||||||
} else {
|
} else {
|
||||||
self.meshService.sendFileBroadcast(packet)
|
self.meshService.sendFileBroadcast(packet, transferId: transferId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -2500,16 +2500,16 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
try? FileManager.default.removeItem(at: destination)
|
try? FileManager.default.removeItem(at: destination)
|
||||||
throw MediaSendError.encodingFailed
|
throw MediaSendError.encodingFailed
|
||||||
}
|
}
|
||||||
let transferId = payload.sha256Hex()
|
|
||||||
|
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
let message = self.enqueueMediaMessage(content: "[file] \(destination.path)", targetPeer: targetPeer)
|
let message = self.enqueueMediaMessage(content: "[file] \(destination.path)", targetPeer: targetPeer)
|
||||||
let messageID = message.id
|
let messageID = message.id
|
||||||
|
let transferId = self.makeTransferID(messageID: messageID)
|
||||||
self.registerTransfer(transferId: transferId, messageID: messageID)
|
self.registerTransfer(transferId: transferId, messageID: messageID)
|
||||||
if let peerID = targetPeer {
|
if let peerID = targetPeer {
|
||||||
self.meshService.sendFilePrivate(packet, to: peerID)
|
self.meshService.sendFilePrivate(packet, to: peerID, transferId: transferId)
|
||||||
} else {
|
} else {
|
||||||
self.meshService.sendFileBroadcast(packet)
|
self.meshService.sendFileBroadcast(packet, transferId: transferId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch MediaSendError.tooLarge {
|
} catch MediaSendError.tooLarge {
|
||||||
@@ -2637,6 +2637,10 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
messageIDToTransferId[messageID] = transferId
|
messageIDToTransferId[messageID] = transferId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func makeTransferID(messageID: String) -> String {
|
||||||
|
"\(messageID)-\(UUID().uuidString)"
|
||||||
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
private func clearTransferMapping(for messageID: String) {
|
private func clearTransferMapping(for messageID: String) {
|
||||||
guard let transferId = messageIDToTransferId.removeValue(forKey: messageID) else { return }
|
guard let transferId = messageIDToTransferId.removeValue(forKey: messageID) else { return }
|
||||||
|
|||||||
Reference in New Issue
Block a user