LETransceiver.m 11.7 KB
//
//  LETransceiver.m
//  ActsBluetoothSpeed
//
//  Created by inidhu on 2019/3/15.
//  Copyright © 2019 Actions. All rights reserved.
//

#import "LETransceiver.h"
#import <UIKit/UIKit.h>

#define BLE_UUID_SERVICE        @"e49a25f8-f69a-11e8-8eb2-f2801f1b9fd1"
#define BLE_UUID_SERVICE_WRITE  @"e49a25e0-f69a-11e8-8eb2-f2801f1b9fd1"
#define BLE_UUID_SERVICE_READ   @"e49a28e1-f69a-11e8-8eb2-f2801f1b9fd1"

@implementation LETransceiver {
    NSString *writeServiceUUID;
    NSString *writeCharacteristicUUID;
    NSString *indicateServiceUUID;
    NSString *indicateCharacteristicUUID;
    
//    CBCharacteristicWriteType writeType;
    
    CBPeripheral *connectedPeripheral;
    CBCharacteristic *characteristicWrite;
    CBCharacteristic *characteristicIndicate;
    
    NSTimer *connectTimer;
    BOOL isReadyToSendWrite;
    
   
}

- (void)closeOTA {
    [connectedPeripheral setNotifyValue:NO forCharacteristic:characteristicIndicate];
}

- (id) init {
    self = [super init];
    if (self) {
        NSDictionary *uuids = [NSDictionary dictionaryWithObjectsAndKeys:BLE_UUID_SERVICE, KeyWriteServiceUUID, BLE_UUID_SERVICE_WRITE, KeyWriteCharacteristicUUID, BLE_UUID_SERVICE, KeyIndicateServiceUUID, BLE_UUID_SERVICE_READ, KeyIndicateCharacteristicUUID, nil];
        [self setUUIDs:uuids];
    }
//    writeType = CBCharacteristicWriteWithoutResponse;
//    centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

    return self;
}

- (void)setUUIDs:(NSDictionary *) uuids {
    NSArray *keys = [uuids allKeys];
    for (NSString *key in keys) {
        if ([key isEqualToString:KeyWriteServiceUUID]) {
            writeServiceUUID = [[uuids objectForKey:KeyWriteServiceUUID] uppercaseString];
        } else if ([key isEqualToString:KeyIndicateServiceUUID]) {
            indicateServiceUUID = [[uuids objectForKey:KeyIndicateServiceUUID] uppercaseString];
        } else if ([key isEqualToString:KeyWriteCharacteristicUUID]) {
            writeCharacteristicUUID = [[uuids objectForKey:KeyWriteCharacteristicUUID] uppercaseString];
        } else if ([key isEqualToString:KeyIndicateCharacteristicUUID]) {
            indicateCharacteristicUUID = [[uuids objectForKey:KeyIndicateCharacteristicUUID] uppercaseString];
        }
    }
}

//- (void)scanStart {
//    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
//    /*
//    NSMutableArray *servicesUUID = [[NSMutableArray alloc] init];
//    if (writeServiceUUID)
//        [servicesUUID addObject:writeServiceUUID];
//    if (indicateServiceUUID)
//        [servicesUUID addObject:indicateServiceUUID];
//    */
//    [self.centralManager scanForPeripheralsWithServices:nil options:options];
//}

//- (void)scanStop {
//    [self.centralManager stopScan];
//}

//- (void)connect:(CBPeripheral *)peripheral {
//    [self scanStop];
//    
//    [self.centralManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES}];
//    
//    if (connectTimer) {
//        [connectTimer invalidate];
//    }
//    connectTimer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(connectTimeout:) userInfo:peripheral repeats:NO];
//}

//- (void)disconnect:(CBPeripheral *)peripheral {
//    if (![self isPeripheralConnected:peripheral]) {
//        return;
//    }
//    
//    NSLog(@"disconnect %@", peripheral.name);
//    [self.centralManager cancelPeripheralConnection:peripheral];
//}

//- (BOOL) isPeripheralConnected:(CBPeripheral *) peripheral {
//    if (peripheral.state == CBPeripheralStateConnected) {
//        return YES;
//    }
//    return NO;
//}

- (NSUInteger) getMtuForType:(CBCharacteristicWriteType) type {
    return [connectedPeripheral maximumWriteValueLengthForType:type];
}

- (void)write:(NSData *) data {
    if (characteristicWrite) {
        NSUInteger mtu = [self getMtuForType:CBCharacteristicWriteWithoutResponse];
        NSLog(@"writeData mtu: %ld, %@", mtu, data);
        for (NSUInteger index = 0; index < data.length; index += mtu) {
            NSUInteger len = (data.length - index) > mtu ? mtu : (data.length - index);
            NSData *value = [data subdataWithRange:NSMakeRange(index, len)];
            [connectedPeripheral writeValue:value forCharacteristic:characteristicWrite type:CBCharacteristicWriteWithoutResponse];
            NSLog(@"writeValue: %@", value);
        }
    }
}

- (void)write:(NSData *) data index:(int) i {
    if (characteristicWrite) {
        NSUInteger mtu = [self getMtuForType:CBCharacteristicWriteWithoutResponse];
        NSLog(@"i writeData mtu: %ld, %@", mtu, data);
        
        for (NSUInteger index = 0; index < data.length; index += mtu) {
            NSUInteger len = (data.length - index) > mtu ? mtu : (data.length - index);
            NSData *value = [data subdataWithRange:NSMakeRange(index, len)];
            if(i != 0 && i % 62 == 0) {
                NSData *value2 = [value subdataWithRange:NSMakeRange(0, 1)];
                NSData *value3 = [value subdataWithRange:NSMakeRange(1, value.length - 1)];
                [connectedPeripheral writeValue:value2 forCharacteristic:characteristicWrite type:CBCharacteristicWriteWithResponse];
                [connectedPeripheral writeValue:value3 forCharacteristic:characteristicWrite type:CBCharacteristicWriteWithoutResponse];
            } else {
                [connectedPeripheral writeValue:value forCharacteristic:characteristicWrite type:CBCharacteristicWriteWithoutResponse];
            }
            NSLog(@"writeValue: %@", value);
        }
    }
}

//- (void)connectTimeout:(NSTimer *)timer {
//    CBPeripheral *peripheral = (CBPeripheral *)[timer userInfo];
//    [self disconnect:peripheral];
//}

//#pragma mark -- CBCentralManagerDelegate
//- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
//    NSString *messtoshow;
//    switch (central.state) {
//        case CBManagerStatePoweredOn:{
//            messtoshow=[NSString stringWithFormat:@"CBCentralManagerStatePoweredOn"];
//            [self scanStart];
//            break;
//        }
//        case CBManagerStateUnknown:
//        {
//            messtoshow=[NSString stringWithFormat:@"State unknown, update imminent"];
//            break;
//        }
//        case CBManagerStateResetting:
//        {
//            messtoshow=[NSString stringWithFormat:@"The connection with the system service was momentarily lost, update imminent."];
//            break;
//        }
//        case CBManagerStateUnsupported:
//        {
//            messtoshow=[NSString stringWithFormat:@"The platform doesn't support Bluetooth Low Energy"];
//            break;
//        }
//        case CBManagerStateUnauthorized:
//        {
//            messtoshow=[NSString stringWithFormat:@"The app is not authorized to use Bluetooth Low Energy"];
//            break;
//        }
//        case CBManagerStatePoweredOff:
//        {
//            [self disconnect:connectedPeripheral];
//            
//            messtoshow=[NSString stringWithFormat:@"Bluetooth is currently powered off"];
//            break;
//        }
//        default:
//            break;
//    }
//    NSLog(@"%@",messtoshow);
//}

//- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
////    NSLog(@"didDiscoverPeripheral: %@", peripheral);
//    
//    if(_connectionDelegate && [_connectionDelegate respondsToSelector:@selector(onFoundPeripheral:advertisementData:)]) {
//        [_connectionDelegate onFoundPeripheral:peripheral advertisementData:advertisementData];
//    }
//}

//- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
//    NSLog(@"didConnectPeripheral: %@", peripheral.name);
//    
//    peripheral.delegate = self;
//    [peripheral discoverServices:nil];
//}

//- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
//    NSLog(@"Fail to connect: %@", peripheral.name);
//}

//- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
//    NSLog(@"didDisconnectPeripheral %@, error: %@",peripheral, error);
//    
//    connectedPeripheral = nil;
//    characteristicWrite = nil;
//    characteristicIndicate = nil;
//    if(_connectionDelegate && [_connectionDelegate respondsToSelector:@selector(onDisconnectedPeripheral:)]) {
//        [_connectionDelegate onDisconnectedPeripheral:peripheral];
//    }
//}

//#pragma mark -- CBPeripheralDelegate
//- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
//    NSLog(@"didDiscoverServices: %@", peripheral.name);
//    if (error) {
//        NSLog(@"Error discovering service:%@", [error localizedDescription]);
//        return;
//    }
//    
//    for (CBService *service in peripheral.services) {
//        
//        NSLog(@"service: %@", service);
//        [peripheral discoverCharacteristics:nil forService:service];
//    }
//    
//}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    NSLog(@"didDiscoverCharacteristicsForService: %@, %@", peripheral.name, service.UUID.UUIDString);
    if (error) {
        NSLog(@"Error didDiscoverCharacteristicsForService:%@",[error localizedDescription]);
        return;
    }
    
    NSLog(@"UUID: %@, %@, %@", service.UUID.UUIDString, writeServiceUUID, indicateServiceUUID);
    if ([writeServiceUUID containsString:service.UUID.UUIDString]) {
        for (CBCharacteristic *characteristic in service.characteristics) {
            NSLog(@"DiscoverCharacteristics: %@", characteristic.UUID);
            
            if ([characteristic.UUID.UUIDString isEqualToString:writeCharacteristicUUID])
                characteristicWrite = characteristic;
        }
    }
    
    if ([indicateServiceUUID containsString:service.UUID.UUIDString]) {
        for (CBCharacteristic *characteristic in service.characteristics) {
            NSLog(@"DiscoverCharacteristics: %@", characteristic.UUID);
            
            if ([characteristic.UUID.UUIDString isEqualToString:indicateCharacteristicUUID]) {
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                characteristicIndicate = characteristic;
            }
        }
    }
    
    
    if (characteristicWrite && characteristicIndicate) {
        connectedPeripheral = peripheral;
        [connectTimer invalidate];
        
        if(_connectionDelegate && [_connectionDelegate respondsToSelector:@selector(onConnectedPeripheral:)]) {
            [_connectionDelegate onConnectedPeripheral:peripheral];
        }
    }
}

//- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(nullable NSError *)error {
//    
//}

//- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
//    
//    if (error) {
//        NSLog(@"%@,%@,Error didWriteValueForCharacteristic:%@",characteristic.UUID,[characteristic value], [error localizedDescription]);
//        return;
//    }
//    
//}

//- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
//    if (error) {
//        NSLog(@"Error didUpdateValueForCharacteristic:%@", [error localizedDescription]);
//        return;
//    }
//    NSLog(@"didUpdateValueForCharacteristic: %@  %@", characteristic.UUID, characteristic.value);
//    
//    if (_dataDelegate && [_dataDelegate respondsToSelector:@selector(onDataReceive:)]) {
//        [_dataDelegate onDataReceive:[characteristic value]];
//    }
//}

@end