matthiasmauch@114: /* matthiasmauch@114: * Copyright (C) 2004 Steve Harris matthiasmauch@114: * matthiasmauch@114: * This program is free software; you can redistribute it and/or matthiasmauch@114: * modify it under the terms of the GNU Lesser General Public License matthiasmauch@114: * as published by the Free Software Foundation; either version 2.1 matthiasmauch@114: * of the License, or (at your option) any later version. matthiasmauch@114: * matthiasmauch@114: * This program is distributed in the hope that it will be useful, matthiasmauch@114: * but WITHOUT ANY WARRANTY; without even the implied warranty of matthiasmauch@114: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the matthiasmauch@114: * GNU Lesser General Public License for more details. matthiasmauch@114: * matthiasmauch@114: * $Id$ matthiasmauch@114: */ matthiasmauch@114: matthiasmauch@114: #ifndef LO_LOWLEVEL_H matthiasmauch@114: #define LO_LOWLEVEL_H matthiasmauch@114: matthiasmauch@114: #include "lo/lo_osc_types.h" matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \file lo_lowlevel.h The liblo headerfile defining the low-level API matthiasmauch@114: * functions. matthiasmauch@114: */ matthiasmauch@114: matthiasmauch@114: #ifdef __cplusplus matthiasmauch@114: extern "C" { matthiasmauch@114: #endif matthiasmauch@114: matthiasmauch@114: #include matthiasmauch@114: #ifdef _MSC_VER matthiasmauch@114: #define ssize_t SSIZE_T matthiasmauch@114: #define uint32_t unsigned __int32 matthiasmauch@114: #else matthiasmauch@114: #include matthiasmauch@114: #endif matthiasmauch@114: matthiasmauch@114: #include "lo/lo_types.h" matthiasmauch@114: #include "lo/lo_errors.h" matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \defgroup liblolowlevel Low-level OSC API matthiasmauch@114: * matthiasmauch@114: * Use these functions if you require more precise control over OSC message matthiasmauch@114: * contruction or handling that what is provided in the high-level functions matthiasmauch@114: * described in liblo. matthiasmauch@114: * @{ matthiasmauch@114: */ matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Type used to represent numerical values in conversions between OSC matthiasmauch@114: * types. matthiasmauch@114: */ matthiasmauch@114: typedef long double lo_hires; matthiasmauch@114: matthiasmauch@114: matthiasmauch@114: matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Send a lo_message object to target targ matthiasmauch@114: * matthiasmauch@114: * This is slightly more efficient than lo_send() if you want to send a lot of matthiasmauch@114: * similar messages. The messages are constructed with the lo_message_new() and matthiasmauch@114: * \ref lo_message_add_int32 "lo_message_add*()" functions. matthiasmauch@114: */ matthiasmauch@114: int lo_send_message(lo_address targ, const char *path, lo_message msg); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Send a lo_message object to target targ from address of serv matthiasmauch@114: * matthiasmauch@114: * This is slightly more efficient than lo_send() if you want to send a lot of matthiasmauch@114: * similar messages. The messages are constructed with the lo_message_new() and matthiasmauch@114: * \ref lo_message_add_int32 "lo_message_add*()" functions. matthiasmauch@114: * matthiasmauch@114: * \param targ The address to send the message to matthiasmauch@114: * \param serv The server socket to send the message from matthiasmauch@114: * (can be NULL to use new socket) matthiasmauch@114: * \param path The path to send the message to matthiasmauch@114: * \param msg The bundle itself matthiasmauch@114: */ matthiasmauch@114: int lo_send_message_from(lo_address targ, lo_server serv, matthiasmauch@114: const char *path, lo_message msg); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Send a lo_bundle object to address targ matthiasmauch@114: * matthiasmauch@114: * Bundles are constructed with the matthiasmauch@114: * lo_bundle_new() and lo_bundle_add_message() functions. matthiasmauch@114: */ matthiasmauch@114: int lo_send_bundle(lo_address targ, lo_bundle b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Send a lo_bundle object to address targ from address of serv matthiasmauch@114: * matthiasmauch@114: * Bundles are constructed with the matthiasmauch@114: * lo_bundle_new() and lo_bundle_add_message() functions. matthiasmauch@114: * matthiasmauch@114: * \param targ The address to send the bundle to matthiasmauch@114: * \param serv The server socket to send the bundle from matthiasmauch@114: * (can be NULL to use new socket) matthiasmauch@114: * \param b The bundle itself matthiasmauch@114: */ matthiasmauch@114: int lo_send_bundle_from(lo_address targ, lo_server serv, lo_bundle b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new lo_message object matthiasmauch@114: */ matthiasmauch@114: lo_message lo_message_new(); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Free memory allocated by lo_message_new() and any subsequent matthiasmauch@114: * \ref lo_message_add_int32 lo_message_add*() calls. matthiasmauch@114: */ matthiasmauch@114: void lo_message_free(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a number of arguments to a message. matthiasmauch@114: * matthiasmauch@114: * The data will be added in OSC byteorder (bigendian). matthiasmauch@114: * matthiasmauch@114: * \param m The message to be extended. matthiasmauch@114: * \param types The types of the data items in the message, types are defined in matthiasmauch@114: * lo_types_common.h matthiasmauch@114: * \param ... The data values to be transmitted. The types of the arguments matthiasmauch@114: * passed here must agree with the types specified in the type parameter. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add(lo_message m, const char *types, ...); matthiasmauch@114: matthiasmauch@114: /** \internal \brief the real message_add function (don't call directly) */ matthiasmauch@114: int lo_message_add_internal(lo_message m, const char *file, const int line, matthiasmauch@114: const char *types, ...); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a varargs list to a message. matthiasmauch@114: * matthiasmauch@114: * The data will be added in OSC byteorder (bigendian). matthiasmauch@114: * IMPORTANT: args list must be terminated with LO_ARGS_END, or this call will matthiasmauch@114: * fail. This is used to do simple error checking on the sizes of parameters matthiasmauch@114: * passed. matthiasmauch@114: * matthiasmauch@114: * \param m The message to be extended. matthiasmauch@114: * \param types The types of the data items in the message, types are defined in matthiasmauch@114: * lo_types_common.h matthiasmauch@114: * \param ap The va_list created by a C function declared with an matthiasmauch@114: * ellipsis (...) argument, and pre-initialised with matthiasmauch@114: * "va_start(ap)". The types of the arguments passed here must agree matthiasmauch@114: * with the types specified in the type parameter. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_varargs(lo_message m, const char *types, va_list ap); matthiasmauch@114: matthiasmauch@114: /** \internal \brief the real message_add_varargs function (don't call directly) */ matthiasmauch@114: int lo_message_add_varargs_internal(lo_message m, const char *types, va_list ap, matthiasmauch@114: const char *file, const int line); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * matthiasmauch@114: * The data will be added in OSC byteorder (bigendian). matthiasmauch@114: * matthiasmauch@114: * \param m The message to be extended. matthiasmauch@114: * \param a The data item. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_int32(lo_message m, int32_t a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_float(lo_message m, float a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_string(lo_message m, const char *a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_blob(lo_message m, lo_blob a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_int64(lo_message m, int64_t a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_timetag(lo_message m, lo_timetag a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_double(lo_message m, double a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_symbol(lo_message m, const char *a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_char(lo_message m, char a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_midi(lo_message m, uint8_t a[4]); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_true(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_false(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_nil(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Append a data item and typechar of the specified type to a message. matthiasmauch@114: * See lo_message_add_int32() for details. matthiasmauch@114: * matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_message_add_infinitum(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Returns the source (lo_address) of an incoming message. matthiasmauch@114: * matthiasmauch@114: * Returns NULL if the message is outgoing. Do not free the returned address. matthiasmauch@114: */ matthiasmauch@114: lo_address lo_message_get_source(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Returns the timestamp (lo_timetag *) of a bundled incoming message. matthiasmauch@114: * matthiasmauch@114: * Returns LO_TT_IMMEDIATE if the message is outgoing, or did not arrive matthiasmauch@114: * contained in a bundle. Do not free the returned timetag. matthiasmauch@114: */ matthiasmauch@114: lo_timetag lo_message_get_timestamp(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the message type tag string. matthiasmauch@114: * matthiasmauch@114: * The result is valid until further data is added with lo_message_add*(). matthiasmauch@114: */ matthiasmauch@114: char *lo_message_get_types(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the message argument count. matthiasmauch@114: * matthiasmauch@114: * The result is valid until further data is added with lo_message_add*(). matthiasmauch@114: */ matthiasmauch@114: int lo_message_get_argc(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the message arguments. Do not free the returned data. matthiasmauch@114: * matthiasmauch@114: * The result is valid until further data is added with lo_message_add*(). matthiasmauch@114: */ matthiasmauch@114: lo_arg **lo_message_get_argv(lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the length of a message in bytes. matthiasmauch@114: * matthiasmauch@114: * \param m The message to be sized matthiasmauch@114: * \param path The path the message will be sent to matthiasmauch@114: */ matthiasmauch@114: size_t lo_message_length(lo_message m, const char *path); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Serialise the lo_message object to an area of memory and return a matthiasmauch@114: * pointer to the serialised form. Opposite of lo_message_deserialise(). matthiasmauch@114: * matthiasmauch@114: * \param m The message to be serialised matthiasmauch@114: * \param path The path the message will be sent to matthiasmauch@114: * \param to The address to serialise to, memory will be allocated if to is matthiasmauch@114: * NULL. matthiasmauch@114: * \param size If this pointer is non-NULL the size of the memory area matthiasmauch@114: * will be written here matthiasmauch@114: * matthiasmauch@114: * The returned form is suitable to be sent over a low level OSC transport, matthiasmauch@114: * having the correct endianess and bit-packed structure. matthiasmauch@114: */ matthiasmauch@114: void *lo_message_serialise(lo_message m, const char *path, void *to, matthiasmauch@114: size_t *size); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Deserialise a raw OSC message and return a new lo_message object. matthiasmauch@114: * Opposite of lo_message_serialise(). matthiasmauch@114: * matthiasmauch@114: * \param data Pointer to the raw OSC message data in network transmission form matthiasmauch@114: * (network byte order where appropriate). matthiasmauch@114: * \param size The size of data in bytes matthiasmauch@114: * \param result If this pointer is non-NULL, the result or error code will matthiasmauch@114: * be written here. matthiasmauch@114: * matthiasmauch@114: * Returns a new lo_message, or NULL if deserialisation fails. matthiasmauch@114: * Use lo_message_free() to free the resulting object. matthiasmauch@114: */ matthiasmauch@114: lo_message lo_message_deserialise(void *data, size_t size, int *result); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Dispatch a raw block of memory containing an OSC message. matthiasmauch@114: * matthiasmauch@114: * This is useful when a raw block of memory is available that is matthiasmauch@114: * structured as OSC, and you wish to use liblo to dispatch the matthiasmauch@114: * message to a handler function as if it had been received over the matthiasmauch@114: * network. matthiasmauch@114: * matthiasmauch@114: * \param s The lo_server to use for dispatching. matthiasmauch@114: * \param data Pointer to the raw OSC message data in network transmission form matthiasmauch@114: * (network byte order where appropriate). matthiasmauch@114: * \param size The size of data in bytes matthiasmauch@114: * matthiasmauch@114: * Returns the number of bytes used if successful, or less than 0 otherwise. matthiasmauch@114: */ matthiasmauch@114: int lo_server_dispatch_data(lo_server s, void *data, size_t size); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the hostname of a lo_address object matthiasmauch@114: * matthiasmauch@114: * Returned value must not be modified or free'd. Value will be a dotted quad, matthiasmauch@114: * colon'd IPV6 address, or resolvable name. matthiasmauch@114: */ matthiasmauch@114: const char *lo_address_get_hostname(lo_address a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the port/service name of a lo_address object matthiasmauch@114: * matthiasmauch@114: * Returned value must not be modified or free'd. Value will be a service name matthiasmauch@114: * or ASCII representation of the port number. matthiasmauch@114: */ matthiasmauch@114: const char *lo_address_get_port(lo_address a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the protocol of a lo_address object matthiasmauch@114: * matthiasmauch@114: * Returned value will be one of LO_UDP, LO_TCP or LO_UNIX. matthiasmauch@114: */ matthiasmauch@114: int lo_address_get_protocol(lo_address a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return a URL representing an OSC address matthiasmauch@114: * matthiasmauch@114: * Returned value must be free'd. matthiasmauch@114: */ matthiasmauch@114: char *lo_address_get_url(lo_address a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Set the Time-to-Live value for a given target address. matthiasmauch@114: * matthiasmauch@114: * This is required for sending multicast UDP messages. A value of 1 matthiasmauch@114: * (the usual case) keeps the message within the subnet, while 255 matthiasmauch@114: * means a global, unrestricted scope. matthiasmauch@114: * matthiasmauch@114: * \param t An OSC address. matthiasmauch@114: * \param ttl An integer specifying the scope of a multicast UDP message. matthiasmauch@114: */ matthiasmauch@114: void lo_address_set_ttl(lo_address t, int ttl); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Get the Time-to-Live value for a given target address. matthiasmauch@114: * matthiasmauch@114: * \param t An OSC address. matthiasmauch@114: * \return An integer specifying the scope of a multicast UDP message. matthiasmauch@114: */ matthiasmauch@114: int lo_address_get_ttl(lo_address t); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new bundle object. matthiasmauch@114: * matthiasmauch@114: * OSC Bundles encapsulate one or more OSC messages and may include a timestamp matthiasmauch@114: * indicating when the bundle should be dispatched. matthiasmauch@114: * matthiasmauch@114: * \param tt The timestamp when the bundle should be handled by the receiver. matthiasmauch@114: * Pass LO_TT_IMMEDIATE if you want the receiving server to dispatch matthiasmauch@114: * the bundle as soon as it receives it. matthiasmauch@114: */ matthiasmauch@114: lo_bundle lo_bundle_new(lo_timetag tt); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Adds an OSC message to an existing bundle. matthiasmauch@114: * matthiasmauch@114: * The message passed is appended to the list of messages in the bundle to be matthiasmauch@114: * dispatched to 'path'. matthiasmauch@114: * matthiasmauch@114: * \return 0 if successful, less than 0 otherwise. matthiasmauch@114: */ matthiasmauch@114: int lo_bundle_add_message(lo_bundle b, const char *path, lo_message m); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the length of a bundle in bytes. matthiasmauch@114: * matthiasmauch@114: * Includes the marker and typetage length. matthiasmauch@114: * matthiasmauch@114: * \param b The bundle to be sized matthiasmauch@114: */ matthiasmauch@114: size_t lo_bundle_length(lo_bundle b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Serialise the bundle object to an area of memory and return a matthiasmauch@114: * pointer to the serialised form. matthiasmauch@114: * matthiasmauch@114: * \param b The bundle to be serialised matthiasmauch@114: * \param to The address to serialise to, memory will be allocated if to is matthiasmauch@114: * NULL. matthiasmauch@114: * \param size If this pointer is non-NULL the size of the memory area matthiasmauch@114: * will be written here matthiasmauch@114: * matthiasmauch@114: * The returned form is suitable to be sent over a low level OSC transport, matthiasmauch@114: * having the correct endianess and bit-packed structure. matthiasmauch@114: */ matthiasmauch@114: void *lo_bundle_serialise(lo_bundle b, void *to, size_t *size); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Frees the memory taken by a bundle object. matthiasmauch@114: * matthiasmauch@114: * \param b The bundle to be freed. matthiasmauch@114: */ matthiasmauch@114: void lo_bundle_free(lo_bundle b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Frees the memory taken by a bundle object and messages in the bundle. matthiasmauch@114: * matthiasmauch@114: * \param b The bundle, which may contain messages, to be freed. matthiasmauch@114: */ matthiasmauch@114: void lo_bundle_free_messages(lo_bundle b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return true if the type specified has a numerical value, such as matthiasmauch@114: * LO_INT32, LO_FLOAT etc. matthiasmauch@114: * matthiasmauch@114: * \param a The type to be tested. matthiasmauch@114: */ matthiasmauch@114: int lo_is_numerical_type(lo_type a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return true if the type specified has a textual value, such as matthiasmauch@114: * LO_STRING or LO_SYMBOL. matthiasmauch@114: * matthiasmauch@114: * \param a The type to be tested. matthiasmauch@114: */ matthiasmauch@114: int lo_is_string_type(lo_type a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Attempt to convert one OSC type to another. matthiasmauch@114: * matthiasmauch@114: * Numerical types (eg LO_INT32, LO_FLOAT etc.) may be converted to other matthiasmauch@114: * numerical types and string types (LO_STRING and LO_SYMBOL) may be converted matthiasmauch@114: * to the other type. This is done automatically if a received message matches matthiasmauch@114: * the path, but not the exact types, and is coercible (ie. all numerical matthiasmauch@114: * types in numerical positions). matthiasmauch@114: * matthiasmauch@114: * On failure no translation occurs and false is returned. matthiasmauch@114: * matthiasmauch@114: * \param type_to The type of the destination variable. matthiasmauch@114: * \param to A pointer to the destination variable. matthiasmauch@114: * \param type_from The type of the source variable. matthiasmauch@114: * \param from A pointer to the source variable. matthiasmauch@114: */ matthiasmauch@114: int lo_coerce(lo_type type_to, lo_arg *to, lo_type type_from, lo_arg *from); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the numerical value of the given argument with the matthiasmauch@114: * maximum native system precision. matthiasmauch@114: */ matthiasmauch@114: lo_hires lo_hires_val(lo_type type, lo_arg *p); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new server instance. matthiasmauch@114: * matthiasmauch@114: * Using lo_server_recv(), lo_servers block until they receive OSC matthiasmauch@114: * messages. If you want non-blocking behaviour see matthiasmauch@114: * lo_server_recv_noblock() or the \ref lo_server_thread_new matthiasmauch@114: * "lo_server_thread_*" functions. matthiasmauch@114: * matthiasmauch@114: * \param port If NULL is passed then an unused UDP port will be chosen by the matthiasmauch@114: * system, its number may be retrieved with lo_server_thread_get_port() matthiasmauch@114: * so it can be passed to clients. Otherwise a decimal port number, service matthiasmauch@114: * name or UNIX domain socket path may be passed. matthiasmauch@114: * \param err_h An error callback function that will be called if there is an matthiasmauch@114: * error in messge reception or server creation. Pass NULL if you do not want matthiasmauch@114: * error handling. matthiasmauch@114: */ matthiasmauch@114: lo_server lo_server_new(const char *port, lo_err_handler err_h); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new server instance, specifying protocol. matthiasmauch@114: * matthiasmauch@114: * Using lo_server_recv(), lo_servers block until they receive OSC matthiasmauch@114: * messages. If you want non-blocking behaviour see matthiasmauch@114: * lo_server_recv_noblock() or the \ref lo_server_thread_new matthiasmauch@114: * "lo_server_thread_*" functions. matthiasmauch@114: * matthiasmauch@114: * \param port If using UDP then NULL may be passed to find an unused port. matthiasmauch@114: * Otherwise a decimal port number orservice name or may be passed. matthiasmauch@114: * If using UNIX domain sockets then a socket path should be passed here. matthiasmauch@114: * \param proto The protocol to use, should be one of LO_UDP, LO_TCP or LO_UNIX. matthiasmauch@114: * \param err_h An error callback function that will be called if there is an matthiasmauch@114: * error in messge reception or server creation. Pass NULL if you do not want matthiasmauch@114: * error handling. matthiasmauch@114: */ matthiasmauch@114: lo_server lo_server_new_with_proto(const char *port, int proto, matthiasmauch@114: lo_err_handler err_h); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new server instance, and join a UDP multicast group. matthiasmauch@114: * matthiasmauch@114: * \param group The multicast group to join. See documentation on IP matthiasmauch@114: * multicast for the acceptable address range; e.g., http://tldp.org/HOWTO/Multicast-HOWTO-2.html matthiasmauch@114: * \param port If using UDP then NULL may be passed to find an unused port. matthiasmauch@114: * Otherwise a decimal port number or service name or may be passed. matthiasmauch@114: * If using UNIX domain sockets then a socket path should be passed here. matthiasmauch@114: * \param err_h An error callback function that will be called if there is an matthiasmauch@114: * error in messge reception or server creation. Pass NULL if you do not want matthiasmauch@114: * error handling. matthiasmauch@114: */ matthiasmauch@114: lo_server lo_server_new_multicast(const char *group, const char *port, matthiasmauch@114: lo_err_handler err_h); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Free up memory used by the lo_server object matthiasmauch@114: */ matthiasmauch@114: void lo_server_free(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Wait for an OSC message to be received matthiasmauch@114: * matthiasmauch@114: * \param s The server to wait for connections on. matthiasmauch@114: * \param timeout A timeout in milliseconds to wait for the incoming packet. matthiasmauch@114: * a value of 0 will return immediately. matthiasmauch@114: * matthiasmauch@114: * The return value is 1 if there is a message waiting or 0 if matthiasmauch@114: * there is no message. If there is a message waiting you can now matthiasmauch@114: * call lo_server_recv() to receive that message. matthiasmauch@114: */ matthiasmauch@114: int lo_server_wait(lo_server s, int timeout); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Look for an OSC message waiting to be received matthiasmauch@114: * matthiasmauch@114: * \param s The server to wait for connections on. matthiasmauch@114: * \param timeout A timeout in milliseconds to wait for the incoming packet. matthiasmauch@114: * a value of 0 will return immediately. matthiasmauch@114: * matthiasmauch@114: * The return value is the number of bytes in the received message or 0 if matthiasmauch@114: * there is no message. The message will be dispatched to a matching method matthiasmauch@114: * if one is found. matthiasmauch@114: */ matthiasmauch@114: int lo_server_recv_noblock(lo_server s, int timeout); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Block, waiting for an OSC message to be received matthiasmauch@114: * matthiasmauch@114: * The return value is the number of bytes in the received message. The message matthiasmauch@114: * will be dispatched to a matching method if one is found. matthiasmauch@114: */ matthiasmauch@114: int lo_server_recv(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Add an OSC method to the specifed server. matthiasmauch@114: * matthiasmauch@114: * \param s The server the method is to be added to. matthiasmauch@114: * \param path The OSC path to register the method to. If NULL is passed the matthiasmauch@114: * method will match all paths. matthiasmauch@114: * \param typespec The typespec the method accepts. Incoming messages with matthiasmauch@114: * similar typespecs (e.g. ones with numerical types in the same position) will matthiasmauch@114: * be coerced to the typespec given here. matthiasmauch@114: * \param h The method handler callback function that will be called if a matthiasmauch@114: * matching message is received matthiasmauch@114: * \param user_data A value that will be passed to the callback function, h, matthiasmauch@114: * when its invoked matching from this method. matthiasmauch@114: */ matthiasmauch@114: lo_method lo_server_add_method(lo_server s, const char *path, matthiasmauch@114: const char *typespec, lo_method_handler h, matthiasmauch@114: void *user_data); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Delete an OSC method from the specifed server. matthiasmauch@114: * matthiasmauch@114: * \param s The server the method is to be removed from. matthiasmauch@114: * \param path The OSC path of the method to delete. If NULL is passed the matthiasmauch@114: * method will match the generic handler. matthiasmauch@114: * \param typespec The typespec the method accepts. matthiasmauch@114: */ matthiasmauch@114: void lo_server_del_method(lo_server s, const char *path, matthiasmauch@114: const char *typespec); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the file descriptor of the server socket. matthiasmauch@114: * matthiasmauch@114: * If the server protocol supports exposing the server's underlying matthiasmauch@114: * receive mechanism for monitoring with select() or poll(), this function matthiasmauch@114: * returns the file descriptor needed, otherwise, it returns -1. matthiasmauch@114: * matthiasmauch@114: * WARNING: when using this function beware that not all OSC packets that are matthiasmauch@114: * received are dispatched immediately. lo_server_events_pending() and matthiasmauch@114: * lo_server_next_event_delay() can be used to tell if there are pending matthiasmauch@114: * events and how long before you should attempt to receive them. matthiasmauch@114: */ matthiasmauch@114: int lo_server_get_socket_fd(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the port number that the server has bound to. matthiasmauch@114: * matthiasmauch@114: * Useful when NULL is passed for the port number and you wish to know how to matthiasmauch@114: * address the server. matthiasmauch@114: */ matthiasmauch@114: int lo_server_get_port(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the protocol that the server is using. matthiasmauch@114: * matthiasmauch@114: * Returned value will be one of LO_UDP, LO_TCP or LO_UNIX. matthiasmauch@114: */ matthiasmauch@114: int lo_server_get_protocol(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return an OSC URL that can be used to contact the server. matthiasmauch@114: * matthiasmauch@114: * The return value should be free()'d when it is no longer needed. matthiasmauch@114: */ matthiasmauch@114: char *lo_server_get_url(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return true if there are scheduled events (eg. from bundles) matthiasmauch@114: * waiting to be dispatched by the server matthiasmauch@114: */ matthiasmauch@114: int lo_server_events_pending(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the time in seconds until the next scheduled event. matthiasmauch@114: * matthiasmauch@114: * If the delay is greater than 100 seconds then it will return 100.0. matthiasmauch@114: */ matthiasmauch@114: double lo_server_next_event_delay(lo_server s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the protocol portion of an OSC URL, eg. udp, tcp. matthiasmauch@114: * matthiasmauch@114: * This library uses OSC URLs of the form: osc.prot://hostname:port/path if the matthiasmauch@114: * prot part is missing, UDP is assumed. matthiasmauch@114: * matthiasmauch@114: * The return value should be free()'d when it is no longer needed. matthiasmauch@114: */ matthiasmauch@114: char *lo_url_get_protocol(const char *url); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the protocol ID of an OSC URL. matthiasmauch@114: * matthiasmauch@114: * This library uses OSC URLs of the form: osc.prot://hostname:port/path if the matthiasmauch@114: * prot part is missing, UDP is assumed. matthiasmauch@114: * Returned value will be one of LO_UDP, LO_TCP, LO_UNIX or -1. matthiasmauch@114: * matthiasmauch@114: * \return An integer specifying the protocol. Return -1 when the protocol is matthiasmauch@114: * not supported by liblo. matthiasmauch@114: * matthiasmauch@114: */ matthiasmauch@114: int lo_url_get_protocol_id(const char *url); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the hostname portion of an OSC URL. matthiasmauch@114: * matthiasmauch@114: * The return value should be free()'d when it is no longer needed. matthiasmauch@114: */ matthiasmauch@114: char *lo_url_get_hostname(const char *url); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the port portion of an OSC URL. matthiasmauch@114: * matthiasmauch@114: * The return value should be free()'d when it is no longer needed. matthiasmauch@114: */ matthiasmauch@114: char *lo_url_get_port(const char *url); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the path portion of an OSC URL. matthiasmauch@114: * matthiasmauch@114: * The return value should be free()'d when it is no longer needed. matthiasmauch@114: */ matthiasmauch@114: char *lo_url_get_path(const char *url); matthiasmauch@114: matthiasmauch@114: /* utility functions */ matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief A function to calculate the amount of OSC message space required by a matthiasmauch@114: * C char *. matthiasmauch@114: * matthiasmauch@114: * Returns the storage size in bytes, which will always be a multiple of four. matthiasmauch@114: */ matthiasmauch@114: int lo_strsize(const char *s); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief A function to calculate the amount of OSC message space required by a matthiasmauch@114: * lo_blob object. matthiasmauch@114: * matthiasmauch@114: * Returns the storage size in bytes, which will always be a multiple of four. matthiasmauch@114: */ matthiasmauch@114: uint32_t lo_blobsize(lo_blob b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Test a string against an OSC pattern glob matthiasmauch@114: * matthiasmauch@114: * \param str The string to test matthiasmauch@114: * \param p The pattern to test against matthiasmauch@114: */ matthiasmauch@114: int lo_pattern_match(const char *str, const char *p); matthiasmauch@114: matthiasmauch@114: /** \internal \brief the real send function (don't call directly) */ matthiasmauch@114: int lo_send_internal(lo_address t, const char *file, const int line, matthiasmauch@114: const char *path, const char *types, ...); matthiasmauch@114: /** \internal \brief the real send_timestamped function (don't call directly) */ matthiasmauch@114: int lo_send_timestamped_internal(lo_address t, const char *file, const int line, matthiasmauch@114: lo_timetag ts, const char *path, const char *types, ...); matthiasmauch@114: /** \internal \brief the real lo_send_from() function (don't call directly) */ matthiasmauch@114: int lo_send_from_internal(lo_address targ, lo_server from, const char *file, matthiasmauch@114: const int line, const lo_timetag ts, matthiasmauch@114: const char *path, const char *types, ...); matthiasmauch@114: matthiasmauch@114: matthiasmauch@114: /** \brief Find the time difference between two timetags matthiasmauch@114: * matthiasmauch@114: * Returns a - b in seconds. matthiasmauch@114: */ matthiasmauch@114: double lo_timetag_diff(lo_timetag a, lo_timetag b); matthiasmauch@114: matthiasmauch@114: /** \brief Return a timetag for the current time matthiasmauch@114: * matthiasmauch@114: * On exit the timetag pointed to by t is filled with the OSC matthiasmauch@114: * representation of this instant in time. matthiasmauch@114: */ matthiasmauch@114: void lo_timetag_now(lo_timetag *t); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the storage size, in bytes, of the given argument. matthiasmauch@114: */ matthiasmauch@114: size_t lo_arg_size(lo_type type, void *data); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Given a raw OSC message, return the message path. matthiasmauch@114: * matthiasmauch@114: * \param data A pointer to the raw OSC message data. matthiasmauch@114: * \param size The size of data in bytes (total buffer bytes). matthiasmauch@114: * matthiasmauch@114: * Returns the message path or NULL if an error occurs. matthiasmauch@114: * Do not free() the returned pointer. matthiasmauch@114: */ matthiasmauch@114: char *lo_get_path(void *data, ssize_t size); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Convert the specified argument to host byte order where necessary. matthiasmauch@114: * matthiasmauch@114: * \param type The OSC type of the data item (eg. LO_FLOAT). matthiasmauch@114: * \param data A pointer to the data item to be converted. It is changed matthiasmauch@114: * in-place. matthiasmauch@114: */ matthiasmauch@114: void lo_arg_host_endian(lo_type type, void *data); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Convert the specified argument to network byte order where necessary. matthiasmauch@114: * matthiasmauch@114: * \param type The OSC type of the data item (eg. LO_FLOAT). matthiasmauch@114: * \param data A pointer to the data item to be converted. It is changed matthiasmauch@114: * in-place. matthiasmauch@114: */ matthiasmauch@114: void lo_arg_network_endian(lo_type type, void *data); matthiasmauch@114: matthiasmauch@114: /** @} */ matthiasmauch@114: matthiasmauch@114: /* prettyprinters */ matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \defgroup pp Prettyprinting functions matthiasmauch@114: * matthiasmauch@114: * These functions all print an ASCII representation of their argument to matthiasmauch@114: * stdout. Useful for debugging. matthiasmauch@114: * @{ matthiasmauch@114: */ matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a lo_bundle object. */ matthiasmauch@114: void lo_bundle_pp(lo_bundle b); matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a lo_message object. */ matthiasmauch@114: void lo_message_pp(lo_message m); matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a set of typed arguments. matthiasmauch@114: * \param type A type string in the form provided to lo_send(). matthiasmauch@114: * \param data An OSC data pointer, like that provided in the matthiasmauch@114: * lo_method_handler. matthiasmauch@114: */ matthiasmauch@114: void lo_arg_pp(lo_type type, void *data); matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a lo_server object. */ matthiasmauch@114: void lo_server_pp(lo_server s); matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a lo_method object. */ matthiasmauch@114: void lo_method_pp(lo_method m); matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a lo_method object, but prepend a given prefix matthiasmauch@114: * to all field names. */ matthiasmauch@114: void lo_method_pp_prefix(lo_method m, const char *p); matthiasmauch@114: matthiasmauch@114: /** \brief Pretty-print a lo_server_thread object. */ matthiasmauch@114: void lo_server_thread_pp(lo_server_thread st); matthiasmauch@114: /** @} */ matthiasmauch@114: matthiasmauch@114: #ifdef __cplusplus matthiasmauch@114: } matthiasmauch@114: #endif matthiasmauch@114: matthiasmauch@114: #endif