root/trunk/libffado/src/libosc/OscServer.cpp

Revision 462, 5.0 kB (checked in by ppalmers, 16 years ago)

- Rework the OSC space to something more usable

Line 
1 /*
2  * Copyright (C) 2005-2007 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include <lo/lo.h>
25
26 #include "OscServer.h"
27 #include "OscMessage.h"
28 #include "OscResponse.h"
29 #include "OscNode.h"
30
31 #include <assert.h>
32
33 namespace OSC {
34
35 IMPL_DEBUG_MODULE( OscServer, OscServer, DEBUG_LEVEL_VERBOSE );
36
37 OscServer::OscServer(string port)
38     : m_port(port)
39     , m_server(NULL)
40     , m_rootNode(new OscNode("/root"))
41 {
42
43 }
44
45 OscServer::~OscServer() {
46     lo_server_thread_free(m_server);
47     if (m_rootNode) delete m_rootNode;
48 }
49
50 void
51 OscServer::setVerboseLevel(int l) {
52     setDebugLevel(l);
53     if (m_rootNode) m_rootNode->setVerboseLevel(l);
54 }
55
56 bool
57 OscServer::start()
58 {
59     if (!m_server) {
60         debugWarning("no server thread\n");
61         return false;
62     }
63     lo_server_thread_start(m_server);
64     return true;
65 }
66
67 bool
68 OscServer::stop()
69 {
70     if (!m_server) {
71         debugWarning("no server thread\n");
72         return false;
73     }
74     lo_server_thread_stop(m_server);
75     return true;
76 }
77
78 bool
79 OscServer::init()
80 {
81     if (m_rootNode == NULL) { // should be done at creation
82         debugError("Could not initialize root node\n");
83         return false;
84     }
85
86     m_server = lo_server_thread_new(m_port.c_str(), error_cb);
87
88     if (m_server == NULL) {
89         debugWarning("Could not start OSC server on port %s, trying other port...\n", m_port.c_str());
90         m_server = lo_server_thread_new(NULL, error_cb);
91         if (!m_server) {
92             debugError("Could not start OSC server.\n");
93             return false;
94         }
95         debugWarning("Started OSC server at %s\n",
96                     lo_server_get_url(lo_server_thread_get_server(m_server)));
97     } else {
98         debugOutput(DEBUG_LEVEL_VERBOSE,
99                     "Started OSC server at %s\n",
100                     lo_server_get_url(lo_server_thread_get_server(m_server)));
101     }
102
103     // For debugging, print all incoming OSC messages
104     lo_server_thread_add_method(m_server, NULL, NULL, generic_cb, this);
105
106     return true;
107 }
108
109 bool
110 OscServer::registerAtRootNode(OscNode *n) {
111     return m_rootNode->addChildOscNode(n);
112 }
113
114 bool
115 OscServer::unregisterAtRootNode(OscNode * n) {
116     return m_rootNode->removeChildOscNode(n);
117 }
118
119 // callbacks
120
121 void
122 OscServer::error_cb(int num, const char* msg, const char* path)
123 {
124     debugError("liblo server error %d in path %s, message: %s\n", num, path, msg);
125 }
126
127 // Display incoming OSC messages (for debugging purposes)
128 int
129 OscServer::generic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data)
130 {
131     OscServer *server=reinterpret_cast<OscServer *>(user_data);
132     assert(server);
133
134     debugOutput(DEBUG_LEVEL_VERBOSE, "Message on: %s\n", path);
135
136     if(!server->m_rootNode) {
137         debugError("No root node registered");
138         return 1;
139     }
140
141     // construct the message
142     OscMessage m = OscMessage(path, types, argv, argc);
143
144 #ifdef DEBUG
145     if (getDebugLevel()>=DEBUG_LEVEL_VERY_VERBOSE) {
146         for (int i=0; i < argc; ++i) {
147             printf("arg %d '%c' ", i, types[i]);
148             lo_arg_pp(lo_type(types[i]), argv[i]);
149             printf("\n");
150         }
151         m.print();
152     }
153 #endif
154
155     // process it
156     OscResponse r=server->m_rootNode->processOscMessage(string("/root")+string(path), &m);
157     if(r.isHandled()) {
158         if(r.hasMessage()) {
159             // send response
160             lo_address addr = lo_message_get_source(msg);
161
162             lo_message lo_msg;
163             lo_msg=r.getMessage().makeLoMessage();
164
165             debugOutput(DEBUG_LEVEL_VERBOSE, " Sending response to %s\n",lo_address_get_url(addr));
166
167             #ifdef DEBUG
168                 if(getDebugLevel()>=DEBUG_LEVEL_VERY_VERBOSE) r.getMessage().print();
169             #endif
170
171             if (lo_send_message(addr, "/response", lo_msg) < 0) {
172                 debugError("Failed to send response\n");
173             }
174             lo_message_free(lo_msg);
175         } else {
176             debugOutput(DEBUG_LEVEL_VERBOSE, " No response...\n");
177         }
178         return 0;
179     } else {
180         if (r.isError()) {
181             debugOutput(DEBUG_LEVEL_VERBOSE, " Error in message...\n");
182         } else {
183             debugOutput(DEBUG_LEVEL_VERBOSE, " Not handled...\n");
184         }
185         m.print();
186         return 1;  // not handled
187     }
188 }
189
190
191 } // end of namespace OSC
Note: See TracBrowser for help on using the browser.