Home | History | Annotate | Download | only in WALT
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #import <Foundation/Foundation.h>
     18 
     19 #import "MIDIClient.h"
     20 #import "MIDIMessage.h"
     21 
     22 extern NSString * const WALTClientErrorDomain;
     23 
     24 /** A reasonable timeout to use when reading from the WALT. */
     25 extern const NSTimeInterval kWALTReadTimeout;
     26 
     27 typedef NS_ENUM(MIDIByte, WALTCommand) {
     28   WALTDelayedPingCommand     = 'D',  // Ping with a delay
     29   WALTResetCommand           = 'F',  // Reset all vars
     30   WALTSendSyncCommand        = 'I',  // Send some digits for clock sync
     31   WALTPingCommand            = 'P',  // Ping with a single byte
     32   WALTVersionCommand         = 'V',  // Determine WALT's firmware version
     33   WALTReadoutSyncCommand     = 'R',  // Read out sync times
     34   WALTGShockCommand          = 'G',  // Send last shock time and watch for another
     35   WALTTimeCommand            = 'T',  // Current time
     36   WALTZeroSyncCommand        = 'Z',  // Initial zero
     37   WALTScreenOnCommand        = 'C',  // Send a message on screen color change
     38   WALTScreenOffCommand       = 'c',
     39   WALTSendLastScreenCommand  = 'E',  // Send info about last screen color change
     40   WALTBrightnessCurveCommand = 'U',  // Probe screen for brightness vs time curve
     41   WALTLaserOnCommand         = 'L',  // Send messages on state change of the laser
     42   WALTLaserOffCommand        = 'l',
     43   WALTSendLastLaserCommand   = 'J',
     44   WALTAudioCommand           = 'A',  // Start watching for signal on audio out line
     45   WALTBeepCommand            = 'B',  // Generate a tone into the mic and send timestamp
     46   WALTBeepStopCommand        = 'S',  // Stop generating tone
     47   WALTMIDICommand            = 'M',  // Start listening for a MIDI message
     48   WALTNoteCommand            = 'N',  // Generate a MIDI NoteOn message
     49 };
     50 
     51 typedef struct {
     52   char tag;
     53   NSTimeInterval t;
     54   int value;
     55   unsigned int count;
     56 } WALTTrigger;
     57 
     58 /**
     59  * A client for a WALT device.
     60  *
     61  * The client will automatically try to connect to any available WALT device, and monitor the system
     62  * for device connections/disconnections. Users should observe the "connected" key to be notified of
     63  * connection changes.
     64  *
     65  * Most commands produce a corresponding response from the WALT. The -sendCommand:error: method
     66  * should be used to send the command, and -readResponse used to collect the response.
     67  */
     68 @interface WALTClient : NSObject <MIDIClientDelegate>
     69 @property (readonly, nonatomic, getter=isConnected) BOOL connected;
     70 
     71 /**
     72  * Returns the base time of the WALT device.
     73  *
     74  * The time value is an adjusted version of -currentTime.
     75  */
     76 @property (readonly, nonatomic) NSTimeInterval baseTime;
     77 
     78 /** Returns the number of seconds the system has been awake since it was last restarted. */
     79 @property (readonly, nonatomic) NSTimeInterval currentTime;
     80 
     81 /** Initialises the client and attempts to connect to any available WALT device. */
     82 - (instancetype)initWithError:(NSError **)error;
     83 
     84 /** Sends a command to the WALT. */
     85 - (BOOL)sendCommand:(WALTCommand)command error:(NSError **)error;
     86 
     87 /** Reads a response from the WALT, blocking up to timeout until one becomes available. */
     88 - (NSData *)readResponseWithTimeout:(NSTimeInterval)timeout;
     89 
     90 /**
     91  * Reads a trigger response from the WALT.
     92  *
     93  * If an error occurs, the trigger's tag will be '\0'.
     94  */
     95 - (WALTTrigger)readTriggerWithTimeout:(NSTimeInterval)timeout;
     96 
     97 /** Returns YES if the response data contains a valid acknowledgement for a command. */
     98 - (BOOL)checkResponse:(NSData *)response forCommand:(WALTCommand)command;
     99 
    100 /** Forces a complete clock synchronisation with the WALT. */
    101 - (BOOL)syncClocksWithError:(NSError **)error;
    102 
    103 /** Refreshes the min/max error synchronisation bounds. */
    104 - (BOOL)updateSyncBoundsWithError:(NSError **)error;
    105 
    106 @property (readonly, nonatomic) int64_t minError;
    107 @property (readonly, nonatomic) int64_t maxError;
    108 
    109 /**
    110  * Confirms the connection with the WALT (by setting -isConnected).
    111  *
    112  * Note that this method will only return NO if there is an error in the connection process. The
    113  * absence of a device is not such an error.
    114  */
    115 - (BOOL)checkConnectionWithError:(NSError **)error;
    116 
    117 /** Returns the time of the last shock detected by the WALT. */
    118 - (NSTimeInterval)lastShockTimeWithError:(NSError **)error;
    119 @end
    120