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_H matthiasmauch@114: #define LO_H matthiasmauch@114: matthiasmauch@114: #ifdef __cplusplus matthiasmauch@114: extern "C" { matthiasmauch@114: #endif matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \file lo.h The liblo main headerfile and high-level API functions. matthiasmauch@114: */ matthiasmauch@114: matthiasmauch@114: #include "lo/lo_endian.h" matthiasmauch@114: #include "lo/lo_types.h" matthiasmauch@114: #include "lo/lo_osc_types.h" matthiasmauch@114: #include "lo/lo_errors.h" matthiasmauch@114: #include "lo/lo_lowlevel.h" matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \defgroup liblo High-level OSC API matthiasmauch@114: * matthiasmauch@114: * Defines the high-level API functions necessary to implement OSC support. matthiasmauch@114: * Should be adequate for most applications, but if you require lower level matthiasmauch@114: * control you can use the functions defined in lo_lowlevel.h matthiasmauch@114: * @{ matthiasmauch@114: */ matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Declare an OSC destination, given IP address and port number. matthiasmauch@114: * Same as lo_address_new_with_proto(), but using UDP. matthiasmauch@114: * matthiasmauch@114: * \param host An IP address or number, or NULL for the local machine. matthiasmauch@114: * \param port a decimal port number or service name. matthiasmauch@114: * matthiasmauch@114: * The lo_address object may be used as the target of OSC messages. matthiasmauch@114: * matthiasmauch@114: * Note: if you wish to receive replies from the target of this address, you matthiasmauch@114: * must first create a lo_server_thread or lo_server object which will receive matthiasmauch@114: * the replies. The last lo_server(_thread) object creted will be the receiver. matthiasmauch@114: */ matthiasmauch@114: lo_address lo_address_new(const char *host, const char *port); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Declare an OSC destination, given IP address and port number, matthiasmauch@114: * specifying protocol. matthiasmauch@114: * matthiasmauch@114: * \param proto The protocol to use, must be one of LO_UDP, LO_TCP or LO_UNIX. matthiasmauch@114: * \param host An IP address or number, or NULL for the local machine. matthiasmauch@114: * \param port a decimal port number or service name. matthiasmauch@114: * matthiasmauch@114: * The lo_address object may be used as the target of OSC messages. matthiasmauch@114: * matthiasmauch@114: * Note: if you wish to receive replies from the target of this address, you matthiasmauch@114: * must first create a lo_server_thread or lo_server object which will receive matthiasmauch@114: * the replies. The last lo_server(_thread) object creted will be the receiver. matthiasmauch@114: */ matthiasmauch@114: lo_address lo_address_new_with_proto(int proto, const char *host, const char *port); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a lo_address object from an OSC URL. matthiasmauch@114: * matthiasmauch@114: * example: \c "osc.udp://localhost:4444/my/path/" matthiasmauch@114: */ matthiasmauch@114: lo_address lo_address_new_from_url(const char *url); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Free the memory used by the lo_address object matthiasmauch@114: */ matthiasmauch@114: void lo_address_free(lo_address t); 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 Send a OSC formatted message to the address specified. matthiasmauch@114: * matthiasmauch@114: * \param targ The target OSC address matthiasmauch@114: * \param path The OSC path the message will be delivered to matthiasmauch@114: * \param type The types of the data items in the message, types are defined in matthiasmauch@114: * lo_osc_types.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: * example: matthiasmauch@114: * \code matthiasmauch@114: * lo_send(t, "/foo/bar", "ff", 0.1f, 23.0f); matthiasmauch@114: * \endcode matthiasmauch@114: * matthiasmauch@114: * \return -1 on failure. matthiasmauch@114: */ matthiasmauch@114: int lo_send(lo_address targ, const char *path, const char *type, ...); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Send a OSC formatted message to the address specified, matthiasmauch@114: * from the same socket as the specificied server. matthiasmauch@114: * matthiasmauch@114: * \param targ The target OSC address matthiasmauch@114: * \param from The server to send message from (can be NULL to use new socket) matthiasmauch@114: * \param ts The OSC timetag timestamp at which the message will be processed matthiasmauch@114: * (can be LO_TT_IMMEDIATE if you don't want to attach a timetag) matthiasmauch@114: * \param path The OSC path the message will be delivered to matthiasmauch@114: * \param type The types of the data items in the message, types are defined in matthiasmauch@114: * lo_osc_types.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: * example: matthiasmauch@114: * \code matthiasmauch@114: * serv = lo_server_new(NULL, err); matthiasmauch@114: * lo_server_add_method(serv, "/reply", "ss", reply_handler, NULL); matthiasmauch@114: * lo_send_from(t, serv, LO_TT_IMMEDIATE, "/foo/bar", "ff", 0.1f, 23.0f); matthiasmauch@114: * \endcode matthiasmauch@114: * matthiasmauch@114: * \return on success, the number of bytes sent, or -1 on failure. matthiasmauch@114: */ matthiasmauch@114: int lo_send_from(lo_address targ, lo_server from, lo_timetag ts, matthiasmauch@114: const char *path, const char *type, ...); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Send a OSC formatted message to the address specified, scheduled to matthiasmauch@114: * be dispatch at some time in the future. matthiasmauch@114: * matthiasmauch@114: * \param targ The target OSC address matthiasmauch@114: * \param ts The OSC timetag timestamp at which the message will be processed matthiasmauch@114: * \param path The OSC path the message will be delivered to matthiasmauch@114: * \param type The types of the data items in the message, types are defined in matthiasmauch@114: * lo_osc_types.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: * example: matthiasmauch@114: * \code matthiasmauch@114: * lo_timetag now;
matthiasmauch@114: * lo_timetag_now(&now);
matthiasmauch@114: * lo_send_timestamped(t, now, "/foo/bar", "ff", 0.1f, 23.0f); matthiasmauch@114: * \endcode matthiasmauch@114: * matthiasmauch@114: * \return on success, the number of bytes sent, or -1 on failure. matthiasmauch@114: */ matthiasmauch@114: int lo_send_timestamped(lo_address targ, lo_timetag ts, const char *path, matthiasmauch@114: const char *type, ...); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the error number from the last failed lo_send() or matthiasmauch@114: * lo_address_new() call matthiasmauch@114: */ matthiasmauch@114: int lo_address_errno(lo_address a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the error string from the last failed lo_send() or matthiasmauch@114: * lo_address_new() call matthiasmauch@114: */ matthiasmauch@114: const char *lo_address_errstr(lo_address a); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new server thread to handle incoming OSC matthiasmauch@114: * messages. matthiasmauch@114: * matthiasmauch@114: * Server threads take care of the message reception and dispatch by matthiasmauch@114: * transparently creating a system thread to handle incoming messages. matthiasmauch@114: * Use this if you do not want to handle the threading yourself. matthiasmauch@114: * matthiasmauch@114: * \param port If NULL is passed then an unused 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 A function that will be called in the event of an error being matthiasmauch@114: * raised. The function prototype is defined in lo_types.h matthiasmauch@114: */ matthiasmauch@114: lo_server_thread lo_server_thread_new(const char *port, lo_err_handler err_h); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new server thread to handle incoming OSC matthiasmauch@114: * messages, and join a UDP multicast group. matthiasmauch@114: * matthiasmauch@114: * Server threads take care of the message reception and dispatch by matthiasmauch@114: * transparently creating a system thread to handle incoming messages. matthiasmauch@114: * Use this if you do not want to handle the threading yourself. 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 NULL is passed then an unused 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 A function that will be called in the event of an error being matthiasmauch@114: * raised. The function prototype is defined in lo_types.h matthiasmauch@114: */ matthiasmauch@114: lo_server_thread lo_server_thread_new_multicast(const char *group, const char *port, matthiasmauch@114: lo_err_handler err_h); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new server thread to handle incoming OSC matthiasmauch@114: * messages, specifying protocol. matthiasmauch@114: * matthiasmauch@114: * Server threads take care of the message reception and dispatch by matthiasmauch@114: * transparently creating a system thread to handle incoming messages. matthiasmauch@114: * Use this if you do not want to handle the threading yourself. matthiasmauch@114: * matthiasmauch@114: * \param port If NULL is passed then an unused 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 proto The protocol to use, should be one of LO_UDP, LO_TCP or LO_UNIX. matthiasmauch@114: * \param err_h A function that will be called in the event of an error being matthiasmauch@114: * raised. The function prototype is defined in lo_types.h matthiasmauch@114: */ matthiasmauch@114: lo_server_thread lo_server_thread_new_with_proto(const char *port, int proto, matthiasmauch@114: lo_err_handler err_h); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Free memory taken by a server thread matthiasmauch@114: * matthiasmauch@114: * Frees the memory, and, if currently running will stop the associated thread. matthiasmauch@114: */ matthiasmauch@114: void lo_server_thread_free(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Add an OSC method to the specifed server thread. matthiasmauch@114: * matthiasmauch@114: * \param st The server thread 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 it 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_thread_add_method(lo_server_thread st, const char *path, matthiasmauch@114: const char *typespec, lo_method_handler h, matthiasmauch@114: void *user_data); matthiasmauch@114: /** matthiasmauch@114: * \brief Delete an OSC method from the specifed server thread. matthiasmauch@114: * matthiasmauch@114: * \param st The server thread 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_thread_del_method(lo_server_thread st, const char *path, matthiasmauch@114: const char *typespec); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Start the server thread matthiasmauch@114: * matthiasmauch@114: * \param st the server thread to start. matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_server_thread_start(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Stop the server thread matthiasmauch@114: * matthiasmauch@114: * \param st the server thread to start. matthiasmauch@114: * \return Less than 0 on failure, 0 on success. matthiasmauch@114: */ matthiasmauch@114: int lo_server_thread_stop(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the port number that the server thread has bound to. matthiasmauch@114: */ matthiasmauch@114: int lo_server_thread_get_port(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return a URL describing the address of the server thread. matthiasmauch@114: * matthiasmauch@114: * Return value must be free()'d to reclaim memory. matthiasmauch@114: */ matthiasmauch@114: char *lo_server_thread_get_url(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the lo_server for a lo_server_thread matthiasmauch@114: * matthiasmauch@114: * This function is useful for passing a thread's lo_server matthiasmauch@114: * to lo_send_from(). matthiasmauch@114: */ matthiasmauch@114: lo_server lo_server_thread_get_server(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** \brief Return true if there are scheduled events (eg. from bundles) waiting matthiasmauch@114: * to be dispatched by the thread */ matthiasmauch@114: int lo_server_thread_events_pending(lo_server_thread st); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Create a new OSC blob type. matthiasmauch@114: * matthiasmauch@114: * \param size The amount of space to allocate in the blob structure. matthiasmauch@114: * \param data The data that will be used to initialise the blob, should be matthiasmauch@114: * size bytes long. matthiasmauch@114: */ matthiasmauch@114: lo_blob lo_blob_new(int32_t size, const void *data); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Free the memory taken by a blob matthiasmauch@114: */ matthiasmauch@114: void lo_blob_free(lo_blob b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return the amount of valid data in a lo_blob object. matthiasmauch@114: * matthiasmauch@114: * If you want to know the storage size, use lo_arg_size(). matthiasmauch@114: */ matthiasmauch@114: uint32_t lo_blob_datasize(lo_blob b); matthiasmauch@114: matthiasmauch@114: /** matthiasmauch@114: * \brief Return a pointer to the start of the blob data to allow contents to matthiasmauch@114: * be changed. matthiasmauch@114: */ matthiasmauch@114: void *lo_blob_dataptr(lo_blob b); matthiasmauch@114: matthiasmauch@114: /** @} */ matthiasmauch@114: matthiasmauch@114: #include "lo/lo_macros.h" matthiasmauch@114: matthiasmauch@114: #ifdef __cplusplus matthiasmauch@114: } matthiasmauch@114: #endif matthiasmauch@114: matthiasmauch@114: #endif