Skip to content

Complete Device I/O Documentation - Implementation Guide #2

@ebowwa

Description

@ebowwa

Complete Device I/O Documentation for HeyCyan Glasses SDK

Overview

This issue provides exhaustive documentation of every input/output operation between iOS apps and HeyCyan glasses, with exact code examples and expected responses.

Table of Contents

  1. Device Discovery & Connection
  2. Device Information Retrieval
  3. Battery Management
  4. Photo Capture
  5. Video Recording
  6. Audio Recording
  7. AI Image Generation
  8. Media File Management
  9. Time Synchronization
  10. Error States & Handling

1. Device Discovery & Connection

1.1 Start Scanning

Input:

[[QCCentralManager shared] scan];

Output (via delegate):

- (void)didScanPeripherals:(NSArray *)peripheralArr {
    // Array of QCBlePeripheral objects
    // Each contains:
    // - peripheral.name: "HeyCyan-XXXX"
    // - mac: "AA:BB:CC:DD:EE:FF"
    // - peripheral.identifier: UUID
    // - peripheral.RSSI: Signal strength (-30 to -100)
}

1.2 Connect to Device

Input:

[[QCCentralManager shared] connect:selectedPeripheral];

Output States:

- (void)didState:(QCState)state {
    // QCStateConnecting → QCStateConnected (success)
    // QCStateConnecting → QCStateDisconnected (failure)
}

BLE Protocol Details:

  • Service UUID: 7905FFF0-B5CE-4E99-A40F-4B1E122D00D0
  • Secondary Service: 6e40fff0-b5a3-f393-e0a9-e50e24dcca9e

2. Device Information Retrieval

2.1 Get Version Information

Input:

[QCSDKCmdCreator getDeviceVersionInfoSuccess:^(NSString *hdVersion, 
                                               NSString *firmVersion, 
                                               NSString *hdWifiVersion, 
                                               NSString *firmWifiVersion) {
    // Success handler
} fail:^{
    // Failure handler
}];

Output Example:

hdVersion = "1.0.0"        // Hardware version
firmVersion = "2.3.1"      // Firmware version
hdWifiVersion = "1.0"      // WiFi hardware version
firmWifiVersion = "1.2.0"  // WiFi firmware version

2.2 Get MAC Address

Input:

[QCSDKCmdCreator getDeviceMacAddressSuccess:^(NSString *macAddress) {
    // Success handler
} fail:^{
    // Failure handler
}];

Output:

macAddress = "AA:BB:CC:DD:EE:FF"

3. Battery Management

3.1 Get Battery Status (One-time)

Input:

[QCSDKCmdCreator getDeviceBattery:^(NSInteger battery, BOOL charging) {
    // Success handler
} fail:^{
    // Failure handler
}];

Output:

battery = 85      // 0-100 percentage
charging = NO     // YES when plugged in, NO when on battery

3.2 Battery Updates (Automatic)

Setup:

[QCSDKManager shareInstance].delegate = self;

Output (Auto-triggered):

- (void)didUpdateBatteryLevel:(NSInteger)battery charging:(BOOL)charging {
    // Called every ~30 seconds or on significant change
    // battery: 0-100
    // charging: YES/NO
}

4. Photo Capture

Input:

[QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModePhoto 
                       success:^{
    // Photo captured and saved on device
} fail:^(NSInteger mode) {
    // Returns current mode if failed
}];

Output:

  • Success: Empty callback, photo saved on device storage
  • Failure: Returns current device mode (e.g., QCOperatorDeviceModeVideo if recording)

Timing: ~200ms execution time


5. Video Recording

5.1 Start Recording

Input:

[QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeVideo 
                       success:^{
    // Recording started
} fail:^(NSInteger mode) {
    // Current mode returned
}];

5.2 Stop Recording

Input:

[QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeVideoStop 
                       success:^{
    // Recording stopped
} fail:^(NSInteger mode) {
    // Current mode returned
}];

Important: Cannot record video and audio simultaneously


6. Audio Recording

6.1 Start Recording

Input:

[QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeAudio 
                       success:^{
    // Audio recording started
} fail:^(NSInteger mode) {
    // Current mode returned
}];

6.2 Stop Recording

Input:

[QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeAudioStop 
                       success:^{
    // Audio recording stopped
} fail:^(NSInteger mode) {
    // Current mode returned
}];

7. AI Image Generation

Input:

[QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeAIPhoto 
                       success:^{
    // AI generation started
} fail:^(NSInteger mode) {
    // Current mode returned
}];

Output (via delegate):

- (void)didReceiveAIChatImageData:(NSData *)imageData {
    // imageData: JPEG/PNG data
    // Size: Typically 100KB-2MB
    // Timing: 5-10 seconds after request
    
    UIImage *image = [UIImage imageWithData:imageData];
}

Protocol: Multi-packet BLE transfer with reassembly


8. Media File Management

8.1 Get Media Counts

Input:

[QCSDKCmdCreator getDeviceMedia:^(NSInteger photo, 
                                  NSInteger video, 
                                  NSInteger audio, 
                                  NSInteger type) {
    // Success handler
} fail:^{
    // Failure handler
}];

Output:

photo = 125    // Number of photos
video = 8      // Number of videos  
audio = 3      // Number of audio files
type = 0       // Reserved for future use

8.2 Media Updates (Automatic)

Output (Auto-triggered after media operations):

- (void)didUpdateMediaWithPhotoCount:(NSInteger)photo 
                          videoCount:(NSInteger)video 
                          audioCount:(NSInteger)audio 
                                type:(NSInteger)type {
    // Called after any photo/video/audio operation
}

9. Time Synchronization

Input:

[QCSDKCmdCreator setupDeviceDateTime:^(BOOL isSuccess, NSError *err) {
    // Completion handler
}];

Output:

isSuccess = YES, err = nil           // Success
isSuccess = NO, err = NSError {...}  // Failure with error details

Note: Uses iOS device's current time


10. Error States & Handling

10.1 Connection Errors

- (void)didFailConnected:(CBPeripheral *)peripheral {
    // Connection attempt failed
    // Reasons: Out of range, already connected elsewhere, pairing rejected
}

10.2 Command Errors

fail:^(NSInteger mode) {
    // mode indicates why command failed:
    // - Device in wrong mode (e.g., recording)
    // - Device disconnected
    // - Command timeout
}

10.3 Bluetooth State

- (void)didBluetoothState:(QCBluetoothState)state {
    // Monitor Bluetooth availability
    // States: On, Off, Unsupported, Unauthorized
}

Complete Working Example

@interface ExampleViewController () <QCCentralManagerDelegate, QCSDKManagerDelegate>
@property (nonatomic, assign) BOOL isRecording;
@end

@implementation ExampleViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Setup delegates
    [QCCentralManager shared].delegate = self;
    [QCSDKManager shareInstance].delegate = self;
    
    // Start discovery
    [[QCCentralManager shared] scan];
}

// Device found
- (void)didScanPeripherals:(NSArray *)peripheralArr {
    if (peripheralArr.count > 0) {
        QCBlePeripheral *device = peripheralArr[0];
        NSLog(@"Found: %@ (%@)", device.peripheral.name, device.mac);
        
        [[QCCentralManager shared] stopScan];
        [[QCCentralManager shared] connect:device.peripheral];
    }
}

// Connection state changed
- (void)didState:(QCState)state {
    switch(state) {
        case QCStateConnected:
            NSLog(@"Connected\!");
            [self performInitialQueries];
            break;
            
        case QCStateDisconnected:
            NSLog(@"Disconnected");
            self.isRecording = NO;
            break;
    }
}

// Get initial device state
- (void)performInitialQueries {
    // Get versions
    [QCSDKCmdCreator getDeviceVersionInfoSuccess:^(NSString *hdVersion, 
                                                   NSString *firmVersion, 
                                                   NSString *hdWifiVersion, 
                                                   NSString *firmWifiVersion) {
        NSLog(@"HW: %@, FW: %@", hdVersion, firmVersion);
    } fail:^{
        NSLog(@"Version query failed");
    }];
    
    // Get battery
    [QCSDKCmdCreator getDeviceBattery:^(NSInteger battery, BOOL charging) {
        NSLog(@"Battery: %ld%% %@", battery, charging ? @"(charging)" : @"");
    } fail:^{
        NSLog(@"Battery query failed");
    }];
}

// Take a photo
- (IBAction)capturePhoto {
    [QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModePhoto 
                           success:^{
        NSLog(@"Photo captured\!");
    } fail:^(NSInteger mode) {
        NSLog(@"Cannot take photo in mode %ld", mode);
    }];
}

// Toggle video recording
- (IBAction)toggleVideo {
    if (\!self.isRecording) {
        [QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeVideo 
                               success:^{
            self.isRecording = YES;
            NSLog(@"Recording started");
        } fail:^(NSInteger mode) {
            NSLog(@"Cannot start recording");
        }];
    } else {
        [QCSDKCmdCreator setDeviceMode:QCOperatorDeviceModeVideoStop 
                               success:^{
            self.isRecording = NO;
            NSLog(@"Recording stopped");
        } fail:^(NSInteger mode) {
            NSLog(@"Cannot stop recording");
        }];
    }
}

// Battery updates (automatic)
- (void)didUpdateBatteryLevel:(NSInteger)battery charging:(BOOL)charging {
    NSLog(@"Battery updated: %ld%%", battery);
}

// AI image received
- (void)didReceiveAIChatImageData:(NSData *)imageData {
    UIImage *aiImage = [UIImage imageWithData:imageData];
    NSLog(@"AI Image received: %.1fKB", imageData.length / 1024.0);
    // Display or save image
}

@end

Key Implementation Notes

  1. Thread Safety: All callbacks occur on main thread
  2. Connection Required: All commands except scan require active connection
  3. State Management: Track recording states to prevent conflicts
  4. Error Recovery: Implement reconnection logic for robustness
  5. Battery Monitoring: Automatic updates every ~30 seconds
  6. Command Timing: Allow 200-500ms between commands
  7. AI Image Size: Prepare for 100KB-2MB transfers

Questions or Issues?

Please comment below if any operation needs clarification or if you encounter unexpected behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions