# OSC API
[Core]

Make use of the OSC infrastructure for your own subsystems. More...

## Functions
int | Osc_RegisterSubsystem (const char *name, int(*subsystem_ReceiveMessage)(int channel, char *buffer, int length), int(*subsystem_Async)(int channel))
| Register your subsystem with the OSC system.
int | Osc_SubsystemError (int channel, char *subsystem, char *string)
| Send an error back via OSC from your subsystem.
int | Osc_BlobReceiverHelper (int channel, char *message, int length, char *subsystemName, int(*blobPropertySet)(int property, uchar *buffer, int length), int(*blobPropertyGet)(int property, uchar *buffer, int size), char *blobPropertyNames[])
| Receive an OSC blob for a subsystem with no indexes.
int | Osc_IndexBlobReceiverHelper (int channel, char *message, int length, int indexCount, char *subsystemName, int(*blobPropertySet)(int index, int property, uchar *buffer, int length), int(*blobPropertyGet)(int index, int property, uchar *buffer, int length), char *blobPropertyNames[])
| Receive an OSC blob for a subsystem with indexes.
int | Osc_IntReceiverHelper (int channel, char *message, int length, char *subsystemName, int(*propertySet)(int property, int value), int(*propertyGet)(int property), char *propertyNames[])
| Receive an integer for a subsystem with no indexes.
int | Osc_GeneralReceiverHelper (int channel, char *message, int length, char *subsystemName, int(*propertySet)(int property, char *typedata, int channel), int(*propertyGet)(int property, int channel), char *propertyNames[])
| Receive data for a subsystem that receives a variety of different data types.
int | Osc_IndexIntReceiverHelper (int channel, char *message, int length, int indexCount, char *subsystemName, int(*propertySet)(int index, int property, int value), int(*propertyGet)(int index, int property), char *propertyNames[])
| Receive integers for a subsystem with multiple indexes.

## Detailed Description

Make use of the OSC infrastructure for your own subsystems.

You can use the existing OSC infrastructure to create your own OSC subsystems. It's expected that you'll have a few things lined up to use this API:

1. The name of your subsystem
2. The properties that your subsystem will support. This must be in an array with '0' as the last element.
3. Getters and setters for each of those properties and functions to call them by property index.
4. A function to call the correct helper when Osc calls you.
5. Finally, once you've done all this, you'll need to add your subsystem to the list that Osc knows about.

Example
  So this might look something like:

        // our system name and a function to get it
        static char* MySubsystemOsc_Name = "my-system";
        const char* MySubsystemOsc_GetName( void )
        {
          return MySubsystemOsc_Name;
        }

        // our property names
        static char* MySubsystemOsc_PropertyNames[] = { "prop0", "prop1", 0 }; // must end with a zero

        // A getter and setter, each dealing with the property given to us by the OSC system
        int MyGPSOsc_PropertySet( int index, int property, int value )
        {
          switch ( property )
          {
            case 0:
              MySubsystem_SetProperty0( index, value );
              break;
            case 1:
              MySubsystem_SetProperty1( index, value );
              break;
           }
          return CONTROLLER_OK;
        }

        int MySubsystemOsc_PropertyGet( int index, int property )
        {
          int value;
           switch ( property )
           {
            case 0:
              value = MySubsystem_GetProperty0( index );
              break;
            case 1:
              value = MySubsystem_GetProperty1( index );
              break;
          }
          return value;
        }

        // this is called when the OSC system determines an incoming message is for you.
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
           // depending on your subsystem, use one of the OSC helpers to parse the incoming message
           return Osc_IndexGeneralReceiverHelper( channel, message, length,
                                              MySubsystemOsc_Name,
                                              MySubsystemOsc_PropertySet,
                                              MySubsystemOsc_PropertyGet,
                                              MySubsystemOsc_PropertyNames );
        }

        // lastly, we'll need to register our system with OSC
        Run( ) // this is our startup task in make.c
        {
          // other startup stuff
          Osc_RegisterSubsystem( MySubsystemOsc_GetName(), MySubsystemOsc_ReceiveMessage, NULL );
        }

Check the how-to at http://www.makingthings.com/documentation/how-to/create-your-own-osc-subsystem for details.

## Function Documentation

int Osc_BlobReceiverHelper | ( | int | channel,
|  | char * | message,
|  | int | length,
|  | char * | subsystemName,
|  | int(*)(int property, uchar *buffer, int length) | blobPropertySet,
|  | int(*)(int property, uchar *buffer, int size) | blobPropertyGet,
|  | char * | blobPropertyNames[] |
| ) |  |  |

Receive an OSC blob for a subsystem with no indexes.

You'll usually want to call this when the OSC system calls you with a new message.

Parameters:

  | channel | An index for which OSC channel is being used (usually USB or Ethernet). Usually provided for you by the OSC system.
  | message | The OSC message being received. Usually provided for you by the OSC system.
  | length | The length of the incoming message. Usually provided for you by the OSC system.
  | subsystemName | The name of your subsystem.
  | blobPropertySet | A pointer to the function to be called in order to write a property of your subsystem.
  | blobPropertyGet | A pointer to the function to be called in order to read a property of your subsystem.
  | blobPropertyNames | An array of all the property names in your subsystem.

Example

        // this is where OSC calls us when an incoming message for us has arrived
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
          int status = Osc_BlobReceiverHelper( channel, message, length,
                                            MySubsystemOsc_Name,
                                            MySubsystemOsc_BlobPropertySet, MySubsystemOsc_BlobPropertyGet,
                                            MySubsystemOsc_BlobPropertyNames );

          if ( status != CONTROLLER_OK )
            return Osc_SendError( channel, MySubsystemOsc_Name, status );
          return CONTROLLER_OK;
        }

Definition at line 847 of file osc.c.

int Osc_GeneralReceiverHelper | ( | int | channel,
|  | char * | message,
|  | int | length,
|  | char * | subsystemName,
|  | int(*)(int property, char *typedata, int channel) | propertySet,
|  | int(*)(int property, int channel) | propertyGet,
|  | char * | propertyNames[] |
| ) |  |  |

Receive data for a subsystem that receives a variety of different data types.

An example of this kind of situation is the network system - you have a variety of different properties, several of which are both ints and strings.

You'll usually want to call this when the OSC system calls you with a new message.

Parameters:

  | channel | An index for which OSC channel is being used (usually USB or Ethernet). Usually provided for you by the OSC system.
  | message | The OSC message being received. Usually provided for you by the OSC system.
  | length | The length of the incoming message. Usually provided for you by the OSC system.
  | subsystemName | The name of your subsystem.
  | propertySet | A pointer to the function to be called in order to write a property of your subsystem.
  | propertyGet | A pointer to the function to be called in order to read a property of your subsystem.
  | propertyNames | An array of all the property names in your subsystem.

Example

        // this is where OSC calls us when an incoming message for us has arrived
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
          int status = Osc_GeneralReceiverHelper( channel, message, length,
                                              MySubsystemOsc_Name,
                                              MySubsystemOsc_PropertySet, MySubsystemOsc_PropertyGet,
                                              MySubsystemOsc_PropertyNames );

          if ( status != CONTROLLER_OK )
            return Osc_SendError( channel, MySubsystemOsc_Name, status );
          return CONTROLLER_OK;
        }

Definition at line 1207 of file osc.c.

int Osc_IndexBlobReceiverHelper | ( | int | channel,
|  | char * | message,
|  | int | length,
|  | int | indexCount,
|  | char * | subsystemName,
|  | int(*)(int index, int property, uchar *buffer, int length) | blobPropertySet,
|  | int(*)(int index, int property, uchar *buffer, int length) | blobPropertyGet,
|  | char * | blobPropertyNames[] |
| ) |  |  |

Receive an OSC blob for a subsystem with indexes.

You'll usually want to call this when the OSC system calls you with a new message.

Parameters:

  | channel | An index for which OSC channel is being used (usually USB or Ethernet). Usually provided for you by the OSC system.
  | message | The OSC message being received. Usually provided for you by the OSC system.
  | length | The length of the incoming message. Usually provided for you by the OSC system.
  | indexCount | The number of indexes in your subsystem.
  | subsystemName | The name of your subsystem.
  | blobPropertySet | A pointer to the function to be called in order to write a property of your subsystem.
  | blobPropertyGet | A pointer to the function to be called in order to read a property of your subsystem.
  | blobPropertyNames | An array of all the property names in your subsystem.

Example

        // this is where OSC calls us when an incoming message for us has arrived
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
          int status = Osc_IndexBlobReceiverHelper( channel, message, length, 2,
                                              MySubsystemOsc_Name,
                                              MySubsystemOsc_BlobPropertySet, MySubsystemOsc_BlobPropertyGet,
                                              MySubsystemOsc_BlobPropertyNames );

          if ( status != CONTROLLER_OK )
            return Osc_SendError( channel, MySubsystemOsc_Name, status );
          return CONTROLLER_OK;
        }

Definition at line 945 of file osc.c.

int Osc_IndexIntReceiverHelper | ( | int | channel,
|  | char * | message,
|  | int | length,
|  | int | indexCount,
|  | char * | subsystemName,
|  | int(*)(int index, int property, int value) | propertySet,
|  | int(*)(int index, int property) | propertyGet,
|  | char * | propertyNames[] |
| ) |  |  |

Receive integers for a subsystem with multiple indexes.

An example of this kind of situation is the analog in system - you have 8 channels (indexes) and you're only going to be receiving integers.

You'll usually want to call this when the OSC system calls you with a new message.

Parameters:

  | channel | An index for which OSC channel is being used (usually USB or Ethernet). Usually provided for you by the OSC system.
  | message | The OSC message being received. Usually provided for you by the OSC system.
  | length | The length of the incoming message. Usually provided for you by the OSC system.
  | indexCount | The number of indexes in your subsystem.
  | subsystemName | The name of your subsystem.
  | propertySet | A pointer to the function to be called in order to write a property of your subsystem.
  | propertyGet | A pointer to the function to be called in order to read a property of your subsystem.
  | propertyNames | An array of all the property names in your subsystem.

Example

        // this is where OSC calls us when an incoming message for us has arrived
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
          int status = Osc_GeneralReceiverHelper( channel, message, length,
                                              5, // our index count
                                              MySubsystemOsc_Name,
                                              MySubsystemOsc_PropertySet, MySubsystemOsc_PropertyGet,
                                              MySubsystemOsc_PropertyNames );

          if ( status != CONTROLLER_OK )
            return Osc_SendError( channel, MySubsystemOsc_Name, status );
          return CONTROLLER_OK;
        }

Definition at line 1311 of file osc.c.

int Osc_IntReceiverHelper | ( | int | channel,
|  | char * | message,
|  | int | length,
|  | char * | subsystemName,
|  | int(*)(int property, int value) | propertySet,
|  | int(*)(int property) | propertyGet,
|  | char * | propertyNames[] |
| ) |  |  |

Receive an integer for a subsystem with no indexes.

You'll usually want to call this when the OSC system calls you with a new message.

Parameters:

  | channel | An index for which OSC channel is being used (usually USB or Ethernet). Usually provided for you by the OSC system.
  | message | The OSC message being received. Usually provided for you by the OSC system.
  | length | The length of the incoming message. Usually provided for you by the OSC system.
  | subsystemName | The name of your subsystem.
  | propertySet | A pointer to the function to be called in order to write a property of your subsystem.
  | propertyGet | A pointer to the function to be called in order to read a property of your subsystem.
  | propertyNames | An array of all the property names in your subsystem.

Example

        // this is where OSC calls us when an incoming message for us has arrived
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
          int status = Osc_IntReceiverHelper( channel, message, length,
                                              MySubsystemOsc_Name,
                                              MySubsystemOsc_PropertySet, MySubsystemOsc_PropertyGet,
                                              MySubsystemOsc_PropertyNames );

          if ( status != CONTROLLER_OK )
            return Osc_SendError( channel, MySubsystemOsc_Name, status );
          return CONTROLLER_OK;
        }

Definition at line 1099 of file osc.c.

int Osc_RegisterSubsystem | ( | const char * | name,
|  | int(*)(int channel, char *buffer, int length) | subsystem_ReceiveMessage,
|  | int(*)(int channel) | subsystem_Async |
| ) |  |  |

Register your subsystem with the OSC system.

You'll usually want to do this on startup.

Parameters:

  | name | The name of your subsystem.
  | subsystem_ReceiveMessage | The function to call when an OSC message for this subsystem has arrived.
  | subsystem_Async | The function to be called by the OSC Async system. This is a task that will call you at regular intervals, if enabled, so you can check for status changes and send a message out automatically if you like. See the analog in source for an example. Pass in NULL if you don't want to use the Async system.

Example

        Run( ) // this is our startup task in make.c
        {
          // other startup stuff
          Osc_RegisterSubsystem( MySubsystemOsc_GetName(), MySubsystemOsc_ReceiveMessage, NULL );
        }

Definition at line 768 of file osc.c.

int Osc_SubsystemError | ( | int | channel,
|  | char * | subsystem,
|  | char * | string |
| ) |  |  |

Send an error back via OSC from your subsystem.

You'll usually want to call this when the OSC system calls you with a new message, you've tried to parse it, and you've gotten an error.

Parameters:

  | channel | An index for which OSC channel is being used (usually USB or Ethernet). Usually provided for you by the OSC system.
  | subsystem | The name of the subsystem sending the error.
  | string | The actual contents of the error message.

Example

        // this is where OSC calls us when an incoming message for us has arrived
        int MySubsystemOsc_ReceiveMessage( int channel, char* message, int length )
        {
          int status = Osc_IntReceiverHelper( channel, message, length,
                                              MySubsystemOsc_Name,
                                              MySubsystemOsc_PropertySet, MySubsystemOsc_PropertyGet,
                                              MySubsystemOsc_PropertyNames );

          if ( status != CONTROLLER_OK )
            Osc_SubsystemError( channel, MySubsystemOsc_Name, "Oh no. Bad data." );
        }

Definition at line 807 of file osc.c.