예제 #1
0
static int _applemidi_idle_timeout( void * drv, struct timespec * ts ) {
  struct MIDIDriverAppleMIDI * driver = drv;
  struct sockaddr * addr;
  socklen_t size;

  _applemidi_update_runloop_source( driver );

  RTPSessionNextPeer( driver->rtp_session, &(driver->peer) );
  if( driver->peer != NULL ) {
    /* check if receiver feedback needs to be sent */
    if( driver->sync == 0 ) {
      /* no sync packets active. start new sync */
      RTPPeerGetAddress( driver->peer, &size, &addr );
      return _applemidi_start_sync( driver, driver->rtp_socket, size, addr );
    }
  }

  /* check for messages in dispatch (incoming) queue:
   *   if message needs to be dispatched (timestamp >= now+latency)
   *   call MIDIDriverAppleMIDIReceiveMessage
   * send receiver feedback
   * if the last synchronization happened a certain time ago, synchronize again */

  return 0;
}
예제 #2
0
void _applemidi_idle_timeout(unsigned long data)
{
	struct sockaddr_in *addr;
	int size;

	struct MIDIDriverAppleMIDI *driver = (struct MIDIDriverAppleMIDI *)data;
	mod_timer(&driver->timer, jiffies + msecs_to_jiffies(1500));

	pr_debug("====called timeout (%ld) dat: %lx ====\n", jiffies, data);

	if (spin_trylock(&(driver->lock))) {
		RTPSessionNextPeer(driver->rtp_session, &(driver->peer));
		if (driver->peer != NULL) {
			/* check if receiver feedback needs to be sent */
			if (driver->sync == 0) {
				/* no sync packets active. start new sync */
				RTPPeerGetAddress(driver->peer, &size, &addr);

				pr_debug("start sync with client: %pI4\n",
					 &addr->sin_addr.s_addr);
				_applemidi_start_sync(
				    driver, driver->rtp_socket->sk, size, addr);
				// no return
			}
		}
		spin_unlock(&(driver->lock));
	} else {
		pr_warn("could not so sync timeout because of midi event\n");
	}
	//
	// /* check for messages in dispatch (incoming) queue:
	//  *   if message needs to be dispatched (timestamp >= now+latency)
	//  *   call MIDIDriverAppleMIDIReceiveMessage
	//  * send receiver feedback
	//  * if the last synchronization happened a certain time ago,
	// synchronize again */
	//
	// return 0;
}
예제 #3
0
/**
 * @brief Respond to a given AppleMIDI command.
 * Use the command as response and - if neccessary - send it back to the peer.
 * @private @memberof MIDIDriverAppleMIDI
 * @param driver The driver.
 * @param fd The file descriptor to be used for communication.
 * @param command The command.
 * @retval 0 On success.
 * @retval >0 If the packet could not be sent.
 */
static int _applemidi_respond( struct MIDIDriverAppleMIDI * driver, int fd, struct AppleMIDICommand * command ) {
  struct RTPPeer * peer = NULL;
  struct MIDIEvent * event = NULL;

  switch( command->type ) {
    case APPLEMIDI_COMMAND_INVITATION:
      if( fd == driver->control_socket ) {
        event = MIDIEventCreate( MIDI_APPLEMIDI_PEER_DID_SEND_INVITATION, NULL, "%s", &(command->data.session.name[0]) );
        MIDIDriverTriggerEvent( &(driver->base), event );
        MIDIEventRelease( event );
      }
      if( driver->accept ) {
        command->type = APPLEMIDI_COMMAND_INVITATION_ACCEPTED;
        if( fd == driver->rtp_socket ) {
          peer = RTPPeerCreate( command->data.session.ssrc, command->size, (struct sockaddr *) &(command->addr) );
          RTPSessionAddPeer( driver->rtp_session, peer );
          RTPPeerRelease( peer );
        }
      } else {
        command->type = APPLEMIDI_COMMAND_INVITATION_REJECTED;
      }
      RTPSessionGetSSRC( driver->rtp_session, &(command->data.session.ssrc) );
      return _applemidi_send_command( driver, fd, command );
    case APPLEMIDI_COMMAND_INVITATION_ACCEPTED:
      if( command->data.session.token == driver->token ) {
        if( fd == driver->control_socket ) {
          _applemidi_rtp_addr( command->size, (struct sockaddr *) &command->addr, (struct sockaddr *) &command->addr );
          return _applemidi_invite( driver, driver->rtp_socket, command->size, (struct sockaddr *) &(command->addr) );
        } else {
          peer = RTPPeerCreate( command->data.session.ssrc, command->size, (struct sockaddr *) &(command->addr) );
          RTPSessionAddPeer( driver->rtp_session, peer );
          event = MIDIEventCreate( MIDI_APPLEMIDI_PEER_DID_ACCEPT_INVITATION, NULL, "%s", &(command->data.session.name[0]) );
          MIDIDriverTriggerEvent( &(driver->base), event );
          MIDIEventRelease( event );
          RTPPeerRelease( peer );
          return _applemidi_start_sync( driver, driver->rtp_socket, command->size, (struct sockaddr *) &(command->addr) );
        }
      }
      break;
    case APPLEMIDI_COMMAND_INVITATION_REJECTED:
      event = MIDIEventCreate( MIDI_APPLEMIDI_PEER_DID_REJECT_INVITATION, NULL, "%s", &(command->data.session.name[0]) );
      MIDIDriverTriggerEvent( &(driver->base), event );
      MIDIEventRelease( event );
      break;
    case APPLEMIDI_COMMAND_ENDSESSION:
      RTPSessionFindPeerBySSRC( driver->rtp_session, &peer, command->data.session.ssrc );
      event = MIDIEventCreate( MIDI_APPLEMIDI_PEER_DID_END_SESSION, NULL, "%s", &(command->data.session.name[0]) );
      MIDIDriverTriggerEvent( &(driver->base), event );
      MIDIEventRelease( event );
      if( peer != NULL ) {
        RTPSessionRemovePeer( driver->rtp_session, peer );
      }
      break;
    case APPLEMIDI_COMMAND_SYNCHRONIZATION:
      return _applemidi_sync( driver, fd, command );
    case APPLEMIDI_COMMAND_RECEIVER_FEEDBACK:
      RTPSessionFindPeerBySSRC( driver->rtp_session, &peer, command->data.feedback.ssrc );
      RTPMIDISessionJournalTrunkate( driver->rtpmidi_session, peer, command->data.feedback.seqnum );
      break;
    default:
      return 1;
  }
  return 0;
}