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.

1513 lines
40KB

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