Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1371 lines
36KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2010 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #include <lo/lo.h>
  19. #include "debug.h"
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. #include "Endpoint.H"
  25. #include "Thread.H"
  26. #pragma GCC diagnostic ignored "-Wunused-parameter"
  27. namespace OSC
  28. {
  29. /**********/
  30. /* Method */
  31. /**********/
  32. Method::Method ( )
  33. {
  34. _path = _typespec = _documentation = 0;
  35. }
  36. Method::~Method ( )
  37. {
  38. if ( _path )
  39. free( _path );
  40. if ( _typespec )
  41. free( _typespec );
  42. }
  43. /**********/
  44. /* Signal */
  45. /**********/
  46. int Signal::next_id = 0;
  47. Signal::Signal ( const char *path, Direction dir )
  48. {
  49. _direction = dir;
  50. _path = strdup( path );
  51. _id = ++next_id;
  52. _value = 0.0f;
  53. _endpoint = NULL;
  54. _peer = NULL;
  55. _documentation = 0;
  56. _user_data = 0;
  57. _connection_state_callback = 0;
  58. _connection_state_userdata = 0;
  59. }
  60. Signal::~Signal ( )
  61. {
  62. if ( _endpoint )
  63. {
  64. _endpoint->del_signal( this );
  65. }
  66. free( _path );
  67. _path = NULL;
  68. _endpoint = NULL;
  69. }
  70. void
  71. Signal::rename ( const char *path )
  72. {
  73. DMESSAGE( "Renaming signal %s to %s", this->path(), path );
  74. free( _path );
  75. _path = strdup( path );
  76. _endpoint->send_signal_rename_notifications( this );
  77. }
  78. bool
  79. Signal::is_connected_to ( const OSC::Signal *s ) const
  80. {
  81. for ( std::list<Signal*>::const_iterator i = _outgoing.begin();
  82. i != _outgoing.end();
  83. ++i )
  84. {
  85. if ( (*i)->_peer == s->_peer &&
  86. (*i)->id() == s->id() )
  87. return true;
  88. }
  89. return false;
  90. }
  91. void
  92. Signal::value ( float f )
  93. {
  94. for ( std::list<Signal*>::const_iterator i = _outgoing.begin();
  95. i != _outgoing.end();
  96. ++i )
  97. {
  98. /* FIXME: won't work for loopback */
  99. if ( (*i)->_value != f )
  100. {
  101. (*i)->_value = f;
  102. _endpoint->send( (*i)->_peer->addr,
  103. "/signal/change",
  104. id(),
  105. (*i)->id(),
  106. f );
  107. }
  108. }
  109. }
  110. char *
  111. Signal::get_output_connection_peer_name_and_path ( int n )
  112. {
  113. Signal *t;
  114. int j = 0;
  115. for ( std::list<Signal*>::const_iterator i = _outgoing.begin();
  116. i != _outgoing.end();
  117. ++i, ++j )
  118. {
  119. if ( j == n )
  120. {
  121. t = *i;
  122. break;
  123. }
  124. }
  125. // Signal *s = get_peer_signal_by_id( t->_peer, t->signal_id );
  126. char *r;
  127. asprintf( &r, "%s:%s", t->_peer->name, t->path() );
  128. return r;
  129. }
  130. void
  131. Endpoint::error_handler(int num, const char *msg, const char *path)
  132. {
  133. WARNING( "LibLO server error %d in path %s: %s\n", num, path, msg);
  134. }
  135. Endpoint::Endpoint ( )
  136. {
  137. _peer_scan_complete_callback = 0;
  138. _peer_scan_complete_userdata = 0;
  139. _server = 0;
  140. _name = 0;
  141. owner = 0;
  142. }
  143. int
  144. Endpoint::init ( int proto, const char *port )
  145. {
  146. DMESSAGE( "Creating OSC server" );
  147. _server = lo_server_new_with_proto( port, proto, error_handler );
  148. if ( ! _server )
  149. {
  150. WARNING( "Error creating OSC server" );
  151. return -1;
  152. }
  153. add_method( "/signal/hello", "ss", &Endpoint::osc_sig_hello, this, "" );
  154. add_method( "/signal/connect", "ii", &Endpoint::osc_sig_connect, this, "" );
  155. add_method( "/signal/disconnect", "ii", &Endpoint::osc_sig_disconnect, this, "" );
  156. add_method( "/signal/renamed", "is", &Endpoint::osc_sig_renamed, this, "" );
  157. add_method( "/signal/removed", "i", &Endpoint::osc_sig_removed, this, "" );
  158. add_method( "/signal/created", "ssifff", &Endpoint::osc_sig_created, this, "" );
  159. add_method( "/signal/change", "iif", &Endpoint::osc_sig_handler, this, "" );
  160. add_method( "/signal/list", NULL, &Endpoint::osc_signal_lister, this, "" );
  161. add_method( NULL, "", &Endpoint::osc_generic, this, "" );
  162. add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" );
  163. return 0;
  164. }
  165. Endpoint::~Endpoint ( )
  166. {
  167. // lo_server_thread_free( _st );
  168. if ( _server )
  169. {
  170. lo_server_free( _server );
  171. _server = 0;
  172. }
  173. }
  174. OSC::Signal *
  175. Endpoint::find_target_by_peer_address ( std::list<Signal*> *l, lo_address addr )
  176. {
  177. for ( std::list<Signal*>::iterator i = l->begin();
  178. i != l->end();
  179. ++i )
  180. {
  181. if ( address_matches( addr, (*i)->_peer->addr ) )
  182. {
  183. return *i;
  184. }
  185. }
  186. return NULL;
  187. }
  188. OSC::Signal *
  189. Endpoint::find_signal_by_id ( int id )
  190. {
  191. for ( std::list<Signal*>::iterator i = _signals.begin();
  192. i != _signals.end();
  193. ++i )
  194. {
  195. if ( (*i)->id() == id )
  196. return *i;
  197. }
  198. return NULL;
  199. }
  200. OSC::Signal *
  201. Endpoint::find_peer_signal_by_path ( Peer *p, const char *path )
  202. {
  203. for ( std::list<Signal*>::iterator i = p->_signals.begin();
  204. i != p->_signals.end();
  205. ++i )
  206. {
  207. if ( !strcmp( (*i)->path(), path ) )
  208. return *i;
  209. }
  210. return NULL;
  211. }
  212. OSC::Signal *
  213. Endpoint::find_peer_signal_by_id ( Peer *p, int id )
  214. {
  215. for ( std::list<Signal*>::iterator i = p->_signals.begin();
  216. i != p->_signals.end();
  217. ++i )
  218. {
  219. if ( id == (*i)->id() )
  220. return *i;
  221. }
  222. return NULL;
  223. }
  224. void
  225. Endpoint::hello ( const char *url )
  226. {
  227. assert( name() );
  228. lo_address addr = lo_address_new_from_url ( url );
  229. char *our_url = this->url();
  230. send( addr, "/signal/hello", name(), our_url );
  231. free( our_url );
  232. lo_address_free( addr );
  233. }
  234. int
  235. Endpoint::osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  236. {
  237. Endpoint *ep = (Endpoint*)user_data;
  238. const char *peer_name = &argv[0]->s;
  239. const char *peer_url = &argv[1]->s;
  240. DMESSAGE( "Got hello from %s", peer_name );
  241. if ( ! ep->find_peer_by_name( peer_name ) )
  242. {
  243. ep->scan_peer( peer_name, peer_url );
  244. if ( ep->name() )
  245. {
  246. ep->hello( peer_url );
  247. }
  248. else
  249. {
  250. DMESSAGE( "Not sending hello because we don't have a name yet!" );
  251. }
  252. }
  253. return 0;
  254. }
  255. int
  256. Endpoint::osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  257. {
  258. int their_id = argv[0]->i;
  259. int our_id = argv[1]->i;
  260. Endpoint *ep = (Endpoint*)user_data;
  261. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  262. if ( ! p )
  263. return 0;
  264. Signal *ps = ep->find_peer_signal_by_id( p, their_id );
  265. if ( ! ps )
  266. return 0;
  267. Signal *s = ep->find_signal_by_id( our_id );
  268. if ( ! s )
  269. return 0;
  270. if ( s->_direction == Signal::Input )
  271. {
  272. s->_incoming.remove( ps );
  273. DMESSAGE( "Peer %s has disconnected from signal %s", p->name, ps->path() );
  274. if ( s->_connection_state_callback )
  275. s->_connection_state_callback( s, s->_connection_state_userdata );
  276. return 0;
  277. }
  278. return 0;
  279. }
  280. int
  281. Endpoint::osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  282. {
  283. int their_id = argv[0]->i;
  284. int our_id = argv[1]->i;
  285. Endpoint *ep = (Endpoint*)user_data;
  286. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  287. if ( ! p )
  288. {
  289. WARNING( "Got connection signal from unknown peer" );
  290. return 0;
  291. }
  292. Signal *ps = ep->find_peer_signal_by_id( p, their_id );
  293. if ( ! ps )
  294. {
  295. WARNING( "Unknown source signal" );
  296. return 0;
  297. }
  298. Signal *s = ep->find_signal_by_id( our_id );
  299. if ( ! s )
  300. {
  301. WARNING( "Unknown destination signal" );
  302. return 0;
  303. }
  304. DMESSAGE( "Peer %s has connected to signal %s", p->name, s->path() );
  305. /* if ( s->_direction == Signal::Input ) */
  306. /* { */
  307. s->_incoming.push_back( ps );
  308. /* make a record of it ourselves */
  309. ps->_outgoing.push_back( s );
  310. if ( s->_connection_state_callback )
  311. s->_connection_state_callback( s, s->_connection_state_userdata );
  312. /* return 0; */
  313. /* } */
  314. return 0;
  315. }
  316. int
  317. Endpoint::osc_sig_removed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  318. {
  319. int id = argv[0]->i;
  320. Endpoint *ep = (Endpoint*)user_data;
  321. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  322. if ( ! p )
  323. {
  324. WARNING( "Got signal remove notification from unknown peer." );
  325. return 0;
  326. }
  327. Signal *o = ep->find_peer_signal_by_id( p, id );
  328. if ( ! o )
  329. {
  330. WARNING( "Unknown signal id %i", id );
  331. return 0;
  332. }
  333. DMESSAGE( "Signal %s:%s was removed", o->_peer->name, o->path() );
  334. /* disconnect it */
  335. for ( std::list<Signal*>::iterator i = o->_outgoing.begin();
  336. i != o->_outgoing.end();
  337. ++i )
  338. {
  339. ep->disconnect_signal( o, *i );
  340. }
  341. for ( std::list<Signal*>::iterator i = o->_incoming.begin();
  342. i != o->_incoming.end();
  343. ++i )
  344. {
  345. ep->disconnect_signal( *i, o );
  346. }
  347. p->_signals.remove( o );
  348. delete o;
  349. return 0;
  350. }
  351. int
  352. Endpoint::osc_sig_created ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  353. {
  354. Endpoint *ep = (Endpoint*)user_data;
  355. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  356. if ( ! p )
  357. {
  358. WARNING( "Got signal creation from unknown peer." );
  359. return 0;
  360. }
  361. const char *name = &argv[0]->s;
  362. const char *direction = &argv[1]->s;
  363. const int id = argv[2]->i;
  364. const float min = argv[3]->f;
  365. const float max = argv[4]->f;
  366. const float default_value = argv[5]->f;
  367. DMESSAGE( "Peer %s has created signal %s with id %i (%s %f %f %f)", p->name,
  368. name, id, direction, min, max, default_value );
  369. Signal::Direction dir = Signal::Input;
  370. if ( !strcmp( direction, "in" ) )
  371. dir = Signal::Input;
  372. else if ( !strcmp( direction, "out" ) )
  373. dir = Signal::Output;
  374. Signal *s = new Signal( name, dir );
  375. s->_peer = p;
  376. s->_id = id;
  377. s->parameter_limits( min, max, default_value );
  378. p->_signals.push_back( s );
  379. return 0;
  380. }
  381. int
  382. Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  383. {
  384. DMESSAGE( "Got renamed message." );
  385. int id = argv[0]->i;
  386. char *new_name = &argv[1]->s;
  387. Endpoint *ep = (Endpoint*)user_data;
  388. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  389. if ( ! p )
  390. {
  391. WARNING( "Got signal rename notification from unknown peer." );
  392. return 0;
  393. }
  394. Signal *o = ep->find_peer_signal_by_id( p, id );
  395. if ( ! o )
  396. {
  397. WARNING( "Unknown signal id %i", id );
  398. return 0;
  399. }
  400. DMESSAGE( "Signal %s:%s was renamed to %s", o->_peer->name, o->_path, path );
  401. free( o->_path );
  402. o->_path = strdup( new_name );
  403. return 0;
  404. }
  405. int
  406. Endpoint::osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  407. {
  408. Signal *o;
  409. float f = 0.0;
  410. Endpoint *ep = NULL;
  411. if ( !strcmp( path, "/signal/change" ) && !strcmp( types, "iif" ) )
  412. {
  413. /* accept a value for numbered signal */
  414. int id = argv[1]->i;
  415. f = argv[2]->f;
  416. ep = (Endpoint*)user_data;
  417. o = ep->find_signal_by_id( id );
  418. if ( ! o )
  419. {
  420. WARNING( "Unknown signal id %i", id );
  421. return 0;
  422. }
  423. }
  424. else if ( ! strcmp( types, "f" ) )
  425. {
  426. /* accept a value for signal named in path */
  427. o = (Signal*)user_data;
  428. f = argv[0]->f;
  429. }
  430. else if ( ! types || 0 == types[0] )
  431. {
  432. /* reply with current value */
  433. o = (Signal*)user_data;
  434. o->_endpoint->send( lo_message_get_source( msg ), "/reply", path, o->value() );
  435. return 0;
  436. }
  437. else
  438. {
  439. return -1;
  440. }
  441. Peer *p = NULL;
  442. if ( ep )
  443. p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  444. if ( !p )
  445. {
  446. DMESSAGE( "Signal change initiated by an unknown peer" );
  447. /* message came from an unconnected peer, just set the value exactly */
  448. }
  449. else
  450. {
  451. /* message is from a connected source, do mixing. */
  452. /* remote signal */
  453. /* if ( t->_peer ) */
  454. /* if ( 0 == o->_incoming.size() ) */
  455. /* return 0; */
  456. for ( std::list<Signal*>::const_iterator i = o->_incoming.begin();
  457. i != o->_incoming.end();
  458. ++i )
  459. {
  460. if ( (*i)->id() == argv[0]->i )
  461. {
  462. (*i)->_value = f;
  463. break;
  464. }
  465. }
  466. f = 0.0;
  467. for ( std::list<Signal*>::const_iterator i = o->_incoming.begin();
  468. i != o->_incoming.end();
  469. ++i )
  470. {
  471. f += (*i)->_value;
  472. }
  473. }
  474. o->_value = f;
  475. o->_handler( f, o->_user_data );
  476. return 0;
  477. }
  478. int
  479. Endpoint::osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  480. {
  481. // OSC_DMSG();
  482. if ( argc || path[ strlen(path) - 1 ] != '/' )
  483. return -1;
  484. Endpoint *ep = (Endpoint*)user_data;
  485. for ( std::list<Method*>::const_iterator i = ep->_methods.begin(); i != ep->_methods.end(); ++i )
  486. {
  487. if ( ! (*i)->path() )
  488. continue;
  489. if (! strncmp( (*i)->path(), path, strlen(path) ) )
  490. {
  491. /* asprintf( &stored_path, "%s (%s); %s", path, typespec, argument_description ); */
  492. ((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path, (*i)->path() );
  493. }
  494. }
  495. ((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path );
  496. return 0;
  497. }
  498. int
  499. Endpoint::osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  500. {
  501. // OSC_DMSG();
  502. const char *prefix = NULL;
  503. if ( argc )
  504. prefix = &argv[0]->s;
  505. Endpoint *ep = (Endpoint*)user_data;
  506. for ( std::list<Signal*>::const_iterator i = ep->_signals.begin(); i != ep->_signals.end(); ++i )
  507. {
  508. Signal *o = *i;
  509. if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) )
  510. {
  511. ep->send( lo_message_get_source( msg ),
  512. "/reply",
  513. path,
  514. o->path(),
  515. o->_direction == Signal::Input ? "in" : "out",
  516. o->id(),
  517. o->parameter_limits().min,
  518. o->parameter_limits().max,
  519. o->parameter_limits().default_value
  520. );
  521. }
  522. }
  523. ep->send( lo_message_get_source( msg ), "/reply", path );
  524. return 0;
  525. }
  526. bool
  527. Endpoint::address_matches ( lo_address addr1, lo_address addr2 )
  528. {
  529. char *purl = strdup( lo_address_get_port( addr1 ) );
  530. char *url = strdup( lo_address_get_port( addr2 ) );
  531. bool r = !strcmp( purl, url );
  532. free( purl );
  533. free( url );
  534. return r;
  535. }
  536. void
  537. Endpoint::list_peer_signals ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v )
  538. {
  539. for ( std::list<Peer*>::iterator i = _peers.begin();
  540. i != _peers.end();
  541. ++i )
  542. {
  543. for ( std::list<Signal*>::iterator j = (*i)->_signals.begin();
  544. j != (*i)->_signals.end();
  545. ++j )
  546. {
  547. // DMESSAGE( "Running callback" );
  548. callback( (*i)->name, *j, v );
  549. }
  550. }
  551. }
  552. Peer *
  553. Endpoint::find_peer_by_address ( lo_address addr )
  554. {
  555. char *url = strdup( lo_address_get_port( addr ) );
  556. Peer *p = NULL;
  557. for ( std::list<Peer*>::iterator i = _peers.begin();
  558. i != _peers.end();
  559. ++i )
  560. {
  561. char *purl = strdup( lo_address_get_port( (*i)->addr ) );
  562. if ( !strcmp( purl, url ) )
  563. {
  564. free( purl );
  565. p = *i;
  566. break;
  567. }
  568. free(purl);
  569. }
  570. free( url );
  571. return p;
  572. }
  573. Peer *
  574. Endpoint::find_peer_by_name ( const char *name )
  575. {
  576. for ( std::list<Peer*>::iterator i = _peers.begin();
  577. i != _peers.end();
  578. ++i )
  579. {
  580. if ( !strcmp( name, (*i)->name ) )
  581. {
  582. return *i;
  583. }
  584. }
  585. return NULL;
  586. }
  587. bool
  588. Endpoint::disconnect_signal ( OSC::Signal *s, OSC::Signal *d )
  589. {
  590. if ( ! s->is_connected_to( d ) )
  591. return false;
  592. MESSAGE( "Disconnecting signal output \"%s\" to %s:%i", s->path(), d->_peer->name, d->_id );
  593. send( d->_peer->addr, "/signal/disconnect",
  594. s->_id, /* our signal id */
  595. d->_id /* their signal id */ );
  596. s->_outgoing.remove( d );
  597. s->_incoming.remove( d );
  598. return true;
  599. }
  600. bool
  601. Endpoint::disconnect_signal ( OSC::Signal *s, const char *peer_name, const char *signal_path )
  602. {
  603. if ( s->_direction == Signal::Output )
  604. {
  605. Peer *p = find_peer_by_name( peer_name );
  606. if ( ! p )
  607. return false;
  608. Signal *ps = find_peer_signal_by_path( p, signal_path );
  609. if ( ! ps )
  610. return false;
  611. if ( ! s->is_connected_to( ps ) )
  612. return false;
  613. return disconnect_signal( s, ps );
  614. }
  615. return false;
  616. }
  617. bool
  618. Endpoint::connect_signal( OSC::Signal *s, const char *peer_and_path )
  619. {
  620. char peer[512];
  621. char path[1024];
  622. /* FIXME: use %a */
  623. if ( 2 == sscanf( peer_and_path, "%[^:]:%s", peer, path ) )
  624. {
  625. return connect_signal( s, peer, path );
  626. }
  627. else
  628. return false;
  629. }
  630. bool
  631. Endpoint::connect_signal ( OSC::Signal *s, OSC::Signal *d )
  632. {
  633. if ( s->is_connected_to( d ) )
  634. {
  635. return false;
  636. }
  637. MESSAGE( "Connecting signal output \"%s\" to %s:%s", s->path(), d->_peer->name, d->path() );
  638. s->_outgoing.push_back( d );
  639. /* make a record of it ourselves */
  640. d->_incoming.push_back( s );
  641. send( d->_peer->addr, "/signal/connect",
  642. s->_id, /* our signal id */
  643. d->_id /* their signal id */ );
  644. return true;
  645. }
  646. bool
  647. Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path )
  648. {
  649. if ( s->_direction == Signal::Output )
  650. {
  651. Peer *p = find_peer_by_name( peer_name );
  652. if ( ! p )
  653. return false;
  654. Signal *ps = find_peer_signal_by_path( p, signal_path );
  655. if ( ! ps )
  656. return false;
  657. return connect_signal( s, ps );
  658. }
  659. return false;
  660. }
  661. bool
  662. Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, int signal_id )
  663. {
  664. if ( s->_direction == Signal::Output )
  665. {
  666. Peer *p = find_peer_by_name( peer_name );
  667. if ( !p )
  668. return false;
  669. Signal *ps = find_peer_signal_by_id( p, signal_id );
  670. if ( !ps )
  671. return false;
  672. return connect_signal( s, ps );
  673. }
  674. return false;
  675. }
  676. Signal *
  677. Signal::get_peer_signal_by_id ( Peer *p, int signal_id )
  678. {
  679. for ( std::list<Signal *>::iterator i = p->_signals.begin();
  680. i != p->_signals.end();
  681. ++i )
  682. {
  683. if ( (*i)->_id == signal_id )
  684. return *i;
  685. }
  686. return NULL;
  687. }
  688. int
  689. Endpoint::osc_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  690. {
  691. Endpoint *ep = (Endpoint*)user_data;
  692. if ( argc && !strcmp( &argv[0]->s, "/signal/list" ) )
  693. {
  694. Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
  695. if ( ! p )
  696. {
  697. WARNING( "Got input list reply from unknown peer." );
  698. return 0;
  699. }
  700. if ( argc == 1 )
  701. {
  702. p->_scanning = false;
  703. DMESSAGE( "Done scanning %s", p->name );
  704. if ( ep->_peer_scan_complete_callback )
  705. ep->_peer_scan_complete_callback(ep->_peer_scan_complete_userdata);
  706. }
  707. else if ( argc == 7 && p->_scanning )
  708. {
  709. DMESSAGE( "Peer %s has signal %s (%s)", p->name, &argv[1]->s, &argv[2]->s );
  710. int dir = 0;
  711. if ( !strcmp( &argv[2]->s, "in" ) )
  712. dir = Signal::Input;
  713. else if ( !strcmp( &argv[2]->s, "out" ) )
  714. dir = Signal::Output;
  715. Signal *s = new Signal( &argv[1]->s, (Signal::Direction)dir );
  716. s->_peer = p;
  717. s->_id = argv[3]->i;
  718. s->parameter_limits( argv[4]->f, argv[5]->f, argv[6]->f );
  719. p->_signals.push_back( s );
  720. }
  721. return 0;
  722. }
  723. else
  724. return -1;
  725. }
  726. Method *
  727. Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description )
  728. {
  729. // DMESSAGE( "Added OSC method %s (%s)", path, typespec );
  730. lo_server_add_method( _server, path, typespec, handler, user_data );
  731. Method *md = new Method;
  732. if ( path )
  733. md->_path = strdup( path );
  734. if ( typespec )
  735. md->_typespec = strdup( typespec );
  736. if ( argument_description )
  737. md->_documentation = strdup( argument_description );
  738. _methods.push_back( md );
  739. return md;
  740. }
  741. Signal *
  742. Endpoint::add_signal ( const char *path, Signal::Direction dir, float min, float max, float default_value, signal_handler handler, void *user_data )
  743. {
  744. Signal *o = new Signal( path, dir );
  745. if ( path )
  746. o->_path = strdup( path );
  747. o->_handler = handler;
  748. o->_user_data = user_data;
  749. o->_endpoint = this;
  750. _signals.push_back( o );
  751. if ( dir == Signal::Input )
  752. {
  753. lo_server_add_method( _server, path, NULL, osc_sig_handler, o );
  754. }
  755. o->parameter_limits( min, max, default_value );
  756. /* tell our peers about it */
  757. for ( std::list<Peer*>::iterator i = _peers.begin();
  758. i != _peers.end();
  759. ++i )
  760. {
  761. send( (*i)->addr,
  762. "/signal/created",
  763. o->path(),
  764. o->_direction == Signal::Input ? "in" : "out",
  765. o->id(),
  766. min,
  767. max,
  768. default_value
  769. );
  770. }
  771. return o;
  772. }
  773. void
  774. Endpoint::del_method ( const char *path, const char *typespec )
  775. {
  776. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  777. lo_server_del_method( _server, path, typespec );
  778. for ( std::list<Method *>::iterator i = _methods.begin(); i != _methods.end(); ++i )
  779. {
  780. if ( ! (*i)->path() )
  781. continue;
  782. if ( ! strcmp( path, (*i)->path() ) &&
  783. ! strcmp( typespec, (*i)->typespec() ) )
  784. {
  785. delete *i;
  786. i = _methods.erase( i );
  787. break;
  788. }
  789. }
  790. }
  791. void
  792. Endpoint::del_method ( Method *meth )
  793. {
  794. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  795. lo_server_del_method( _server, meth->path(), meth->typespec() );
  796. delete meth;
  797. _methods.remove( meth );
  798. }
  799. void
  800. Endpoint::send_signal_rename_notifications ( Signal *s )
  801. {
  802. for ( std::list<Peer*>::const_iterator i = _peers.begin();
  803. i != _peers.end();
  804. ++i )
  805. {
  806. send( (*i)->addr,
  807. "/signal/renamed",
  808. s->id(),
  809. s->path() );
  810. }
  811. }
  812. void
  813. Endpoint::del_signal ( Signal *o )
  814. {
  815. // DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
  816. lo_server_del_method( _server, o->path(), "f" );
  817. /* tell our peers about it */
  818. for ( std::list<Peer*>::iterator i = _peers.begin();
  819. i != _peers.end();
  820. ++i )
  821. {
  822. send( (*i)->addr,
  823. "/signal/removed",
  824. o->id() );
  825. }
  826. /* FIXME: clear loopback connections first! */
  827. // delete o;
  828. _signals.remove( o );
  829. }
  830. void
  831. Endpoint::scan_peer ( const char *name, const char *url )
  832. {
  833. Peer *p = new Peer;
  834. DMESSAGE( "Scanning peer %s @ %s...", name, url );
  835. p->name = strdup( name );
  836. p->addr = lo_address_new_from_url( url );
  837. p->_scanning = true;
  838. _peers.push_back( p );
  839. send( p->addr, "/signal/list" );
  840. }
  841. void *
  842. Endpoint::osc_thread ( void * arg )
  843. {
  844. ((Endpoint*)arg)->osc_thread();
  845. return NULL;
  846. }
  847. void
  848. Endpoint::osc_thread ( void )
  849. {
  850. _thread.name( "OSC" );
  851. DMESSAGE( "OSC Thread running" );
  852. run();
  853. }
  854. void
  855. Endpoint::start ( void )
  856. {
  857. if ( !_thread.clone( &Endpoint::osc_thread, this ) )
  858. FATAL( "Could not create OSC thread" );
  859. /* lo_server_thread_start( _st ); */
  860. }
  861. void
  862. Endpoint::stop ( void )
  863. {
  864. _thread.join();
  865. // lo_server_thread_stop( _st );
  866. }
  867. int
  868. Endpoint::port ( void ) const
  869. {
  870. return lo_server_get_port( _server );
  871. }
  872. char *
  873. Endpoint::url ( void ) const
  874. {
  875. return lo_server_get_url( _server );
  876. }
  877. /** Process any waiting events and return immediately */
  878. void
  879. Endpoint::check ( void ) const
  880. {
  881. wait( 0 );
  882. }
  883. /** Process any waiting events and return after timeout */
  884. void
  885. Endpoint::wait ( int timeout ) const
  886. {
  887. if ( lo_server_wait( _server, timeout ) )
  888. while ( lo_server_recv_noblock( _server, 0 ) ) { }
  889. }
  890. /** Process events forever */
  891. void
  892. Endpoint::run ( void ) const
  893. {
  894. for ( ;; )
  895. {
  896. lo_server_recv( _server );
  897. }
  898. }
  899. int
  900. Endpoint::send ( lo_address to, const char *path, std::list< OSC_Value > values )
  901. {
  902. lo_message m = lo_message_new();
  903. for ( std::list< OSC_Value >::const_iterator i = values.begin();
  904. i != values.end();
  905. ++i )
  906. {
  907. const OSC_Value *ov = &(*i);
  908. switch ( ov->type() )
  909. {
  910. case 'f':
  911. DMESSAGE( "Adding float %f", ((OSC_Float*)ov)->value() );
  912. lo_message_add_float( m, ((OSC_Float*)ov)->value() );
  913. break;
  914. case 'i':
  915. DMESSAGE( "Adding int %i", ((OSC_Int*)ov)->value() );
  916. lo_message_add_int32( m, ((OSC_Int*)ov)->value() );
  917. break;
  918. case 's':
  919. DMESSAGE( "Adding string %s", ((OSC_String*)ov)->value() );
  920. lo_message_add_string( m, ((OSC_String*)ov)->value() );
  921. break;
  922. default:
  923. FATAL( "Unknown format: %c", ov->type() );
  924. break;
  925. }
  926. }
  927. DMESSAGE( "Path: %s", path );
  928. lo_bundle b = lo_bundle_new( LO_TT_IMMEDIATE );
  929. lo_bundle_add_message(b, path, m );
  930. int r = lo_send_bundle_from( to, _server, b );
  931. // int r = lo_send_message_from( to, _server, path, m );
  932. // lo_message_free( m );
  933. return r;
  934. }
  935. int
  936. Endpoint::send ( lo_address to, const char *path )
  937. {
  938. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "" );
  939. }
  940. int
  941. Endpoint::send ( lo_address to, const char *path, int v )
  942. {
  943. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "i", v );
  944. }
  945. int
  946. Endpoint::send ( lo_address to, const char *path, float v )
  947. {
  948. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "f", v );
  949. }
  950. int
  951. Endpoint::send ( lo_address to, const char *path, double v )
  952. {
  953. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "d", v );
  954. }
  955. int
  956. Endpoint::send ( lo_address to, const char *path, const char * v )
  957. {
  958. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "s", v );
  959. }
  960. int
  961. Endpoint::send ( lo_address to, const char *path, const char * v1, float v2 )
  962. {
  963. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sf", v1, v2 );
  964. }
  965. int
  966. Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2 )
  967. {
  968. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ss", v1, v2 );
  969. }
  970. int
  971. Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2, const char *v3 )
  972. {
  973. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sss", v1, v2, v3 );
  974. }
  975. int
  976. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3, int v4 )
  977. {
  978. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "siii", v1, v2, v3, v4 );
  979. }
  980. int
  981. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, int v4, int v5 )
  982. {
  983. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssiii", v1, v2, v3, v4, v5 );
  984. }
  985. int
  986. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, int v5, int v6 )
  987. {
  988. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssiii", v1, v2, v3, v4, v5, v6 );
  989. }
  990. int
  991. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2 )
  992. {
  993. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "si", v1, v2 );
  994. }
  995. int
  996. Endpoint::send ( lo_address to, const char *path, int v1, const char *v2 )
  997. {
  998. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "is", v1, v2 );
  999. }
  1000. int
  1001. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3 )
  1002. {
  1003. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sis", v1, v2, v3 );
  1004. }
  1005. int
  1006. Endpoint::send ( lo_address to, const char *path, int v1, const char *v2, const char *v3, const char *v4 )
  1007. {
  1008. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "isss", v1, v2, v3, v4 );
  1009. }
  1010. int
  1011. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3, const char *v4, const char *v5 )
  1012. {
  1013. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sisss", v1, v2, v3, v4, v5 );
  1014. }
  1015. int
  1016. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4, const char *v5 )
  1017. {
  1018. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssss", v1, v2, v3, v4, v5 );
  1019. }
  1020. int
  1021. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4 )
  1022. {
  1023. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssss", v1, v2, v3, v4 );
  1024. }
  1025. int
  1026. Endpoint::send ( lo_address to, const char *path, lo_message msg )
  1027. {
  1028. return lo_send_message_from( to, _server, path, msg );
  1029. }
  1030. int
  1031. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 )
  1032. {
  1033. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 );
  1034. }
  1035. int
  1036. Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 )
  1037. {
  1038. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssifff", v1, v2, v3, v4, v5, v6, v7 );
  1039. }
  1040. int
  1041. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 )
  1042. {
  1043. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sii", v1, v2, v3 );
  1044. }
  1045. int
  1046. Endpoint::send ( lo_address to, const char *path, int v1, int v2 )
  1047. {
  1048. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ii", v1, v2 );
  1049. }
  1050. int
  1051. Endpoint::send ( lo_address to, const char *path, int v1, float v2 )
  1052. {
  1053. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "if", v1, v2 );
  1054. }
  1055. int
  1056. Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3, float v4 )
  1057. {
  1058. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "siif", v1, v2, v3, v4 );
  1059. }
  1060. int
  1061. Endpoint::send ( lo_address to, const char *path, int v1, int v2, float v3 )
  1062. {
  1063. return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "iif", v1, v2, v3 );
  1064. }
  1065. }