Jack2  1.9.8
JackNetInterface.cpp
1 /*
2 Copyright (C) 2008-2011 Romain Moret at Grame
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 
19 #include "JackNetInterface.h"
20 #include "JackException.h"
21 #include <assert.h>
22 
23 using namespace std;
24 
25 /*
26  TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
27  probably also use BUFFER_SIZE_MAX in everything related to MIDI events
28  handling (see MidiBufferInit in JackMidiPort.cpp)
29 */
30 
31 namespace Jack
32 {
33  // JackNetInterface*******************************************
34 
35  JackNetInterface::JackNetInterface() : fSocket()
36  {
37  Initialize();
38  }
39 
40  JackNetInterface::JackNetInterface(const char* multicast_ip, int port) : fSocket(multicast_ip, port)
41  {
42  strcpy(fMulticastIP, multicast_ip);
43  Initialize();
44  }
45 
46  JackNetInterface::JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip) : fSocket(socket)
47  {
48  fParams = params;
49  strcpy(fMulticastIP, multicast_ip);
50  Initialize();
51  }
52 
53  void JackNetInterface::Initialize()
54  {
55  fTxBuffer = NULL;
56  fRxBuffer = NULL;
57  fNetAudioCaptureBuffer = NULL;
58  fNetAudioPlaybackBuffer = NULL;
59  fNetMidiCaptureBuffer = NULL;
60  fNetMidiPlaybackBuffer = NULL;
61  memset(&fSendTransportData, 0, sizeof(net_transport_data_t));
62  memset(&fReturnTransportData, 0, sizeof(net_transport_data_t));
63  }
64 
65  void JackNetInterface::FreeNetworkBuffers()
66  {
67  delete fNetMidiCaptureBuffer;
68  delete fNetMidiPlaybackBuffer;
69  delete fNetAudioCaptureBuffer;
70  delete fNetAudioPlaybackBuffer;
71  fNetMidiCaptureBuffer = NULL;
72  fNetMidiPlaybackBuffer = NULL;
73  fNetAudioCaptureBuffer = NULL;
74  fNetAudioPlaybackBuffer = NULL;
75  }
76 
77  JackNetInterface::~JackNetInterface()
78  {
79  jack_log("JackNetInterface::~JackNetInterface");
80 
81  fSocket.Close();
82  delete[] fTxBuffer;
83  delete[] fRxBuffer;
84  delete fNetAudioCaptureBuffer;
85  delete fNetAudioPlaybackBuffer;
86  delete fNetMidiCaptureBuffer;
87  delete fNetMidiPlaybackBuffer;
88  }
89 
90  int JackNetInterface::SetNetBufferSize()
91  {
92  // audio
93  float audio_size = (fNetAudioCaptureBuffer)
94  ? fNetAudioCaptureBuffer->GetCycleSize()
95  : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
96  jack_log("audio_size %f", audio_size);
97 
98  // midi
99  float midi_size = (fNetMidiCaptureBuffer)
100  ? fNetMidiCaptureBuffer->GetCycleSize()
101  : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
102  jack_log("midi_size %f", midi_size);
103 
104  // bufsize = sync + audio + midi
105  int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size);
106  jack_log("SetNetBufferSize bufsize = %d", bufsize);
107 
108  // tx buffer
109  if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
110  return SOCKET_ERROR;
111  }
112 
113  // rx buffer
114  if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
115  return SOCKET_ERROR;
116  }
117 
118  return 0;
119  }
120 
121  bool JackNetInterface::SetParams()
122  {
123  // TX header init
124  strcpy(fTxHeader.fPacketType, "header");
125  fTxHeader.fID = fParams.fID;
126  fTxHeader.fCycle = 0;
127  fTxHeader.fSubCycle = 0;
128  fTxHeader.fIsLastPckt = 0;
129 
130  // RX header init
131  strcpy(fRxHeader.fPacketType, "header");
132  fRxHeader.fID = fParams.fID;
133  fRxHeader.fCycle = 0;
134  fRxHeader.fSubCycle = 0;
135  fRxHeader.fIsLastPckt = 0;
136 
137  // network buffers
138  fTxBuffer = new char[fParams.fMtu];
139  fRxBuffer = new char[fParams.fMtu];
140  assert(fTxBuffer);
141  assert(fRxBuffer);
142 
143  // net audio/midi buffers'addresses
144  fTxData = fTxBuffer + HEADER_SIZE;
145  fRxData = fRxBuffer + HEADER_SIZE;
146 
147  return true;
148  }
149 
150  int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels)
151  {
152  if (midi_channnels > 0) {
153  // set global header fields and get the number of midi packets
154  fTxHeader.fDataType = 'm';
155  uint data_size = buffer->RenderFromJackPorts();
156  fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE(&fParams));
157 
158  for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
159  fTxHeader.fSubCycle = subproc;
160  fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0;
161  fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size);
162  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
163  if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
164  return SOCKET_ERROR;
165  }
166  }
167  }
168  return 0;
169  }
170 
171  int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels)
172  {
173  // audio
174  if (audio_channels > 0) {
175  fTxHeader.fDataType = 'a';
176  fTxHeader.fActivePorts = buffer->RenderFromJackPorts();
177  fTxHeader.fNumPacket = buffer->GetNumPackets(fTxHeader.fActivePorts);
178 
179  for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
180  fTxHeader.fSubCycle = subproc;
181  fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
182  fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
183  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
184  // PacketHeaderDisplay(&fTxHeader);
185  if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
186  return SOCKET_ERROR;
187  }
188  }
189  }
190  return 0;
191  }
192 
193  int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt)
194  {
195  int rx_bytes = Recv(rx_head->fPacketSize, 0);
196  fRxHeader.fCycle = rx_head->fCycle;
197  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
198  buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
199  // Last midi packet is received, so finish rendering...
200  if (++recvd_midi_pckt == rx_head->fNumPacket) {
201  buffer->RenderToJackPorts();
202  }
203  return rx_bytes;
204  }
205 
206  int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer)
207  {
208  int rx_bytes = Recv(rx_head->fPacketSize, 0);
209  fRxHeader.fCycle = rx_head->fCycle;
210  fRxHeader.fSubCycle = rx_head->fSubCycle;
211  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
212  fRxHeader.fActivePorts = rx_head->fActivePorts;
213  rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, fRxHeader.fActivePorts);
214  // Last audio packet is received, so finish rendering...
215  if (fRxHeader.fIsLastPckt) {
216  buffer->RenderToJackPorts();
217  }
218  return rx_bytes;
219  }
220 
221  int JackNetInterface::FinishRecv(NetAudioBuffer* buffer)
222  {
223  // TODO : finish midi and audio rendering ?
224  buffer->RenderToJackPorts();
225  return NET_PACKET_ERROR;
226  }
227 
228  NetAudioBuffer* JackNetInterface::AudioBufferFactory(int nports, char* buffer)
229  {
230  switch (fParams.fSampleEncoder) {
231 
232  case JackFloatEncoder:
233  return new NetFloatAudioBuffer(&fParams, nports, buffer);
234 
235  case JackIntEncoder:
236  return new NetIntAudioBuffer(&fParams, nports, buffer);
237 
238  #if HAVE_CELT
239  case JackCeltEncoder:
240  return new NetCeltAudioBuffer(&fParams, nports, buffer, fParams.fKBps);
241  #endif
242  }
243  return NULL;
244  }
245 
246  // JackNetMasterInterface ************************************************************************************
247 
248  bool JackNetMasterInterface::Init()
249  {
250  jack_log("JackNetMasterInterface::Init, ID %u", fParams.fID);
251 
252  session_params_t host_params;
253  uint attempt = 0;
254  int rx_bytes = 0;
255 
256  // socket
257  if (fSocket.NewSocket() == SOCKET_ERROR) {
258  jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
259  return false;
260  }
261 
262  // timeout on receive (for init)
263  if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0)
264  jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
265 
266  // connect
267  if (fSocket.Connect() == SOCKET_ERROR) {
268  jack_error("Can't connect : %s", StrError(NET_ERROR_CODE));
269  return false;
270  }
271 
272  // send 'SLAVE_SETUP' until 'START_MASTER' received
273  jack_info("Sending parameters to %s...", fParams.fSlaveNetName);
274  do
275  {
276  session_params_t net_params;
277  memset(&net_params, 0, sizeof(session_params_t));
278  SetPacketType(&fParams, SLAVE_SETUP);
279  SessionParamsHToN(&fParams, &net_params);
280 
281  if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
282  jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
283  }
284 
285  memset(&net_params, 0, sizeof(session_params_t));
286  if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
287  jack_error("Problem with network");
288  return false;
289  }
290 
291  SessionParamsNToH(&net_params, &host_params);
292  }
293  while ((GetPacketType(&host_params) != START_MASTER) && (++attempt < SLAVE_SETUP_RETRY));
294  if (attempt == SLAVE_SETUP_RETRY) {
295  jack_error("Slave doesn't respond, exiting");
296  return false;
297  }
298 
299  return true;
300  }
301 
302  int JackNetMasterInterface::SetRxTimeout()
303  {
304  jack_log("JackNetMasterInterface::SetRxTimeout");
305  float time = 3 * 1000000.f * (static_cast<float>(fParams.fPeriodSize) / static_cast<float>(fParams.fSampleRate));
306  return fSocket.SetTimeOut(static_cast<int>(time));
307  }
308 
309  bool JackNetMasterInterface::SetParams()
310  {
311  jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
312  fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
313  fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
314 
315  JackNetInterface::SetParams();
316 
317  fTxHeader.fDataStream = 's';
318  fRxHeader.fDataStream = 'r';
319 
320  fMaxCycleOffset = fParams.fNetworkLatency;
321 
322  // midi net buffers
323  if (fParams.fSendMidiChannels > 0) {
324  fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData);
325  }
326 
327  if (fParams.fReturnMidiChannels > 0) {
328  fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData);
329  }
330 
331  try {
332 
333  // audio net buffers
334  if (fParams.fSendAudioChannels > 0) {
335  fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fTxData);
336  assert(fNetAudioCaptureBuffer);
337  }
338 
339  if (fParams.fReturnAudioChannels > 0) {
340  fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fRxData);
341  assert(fNetAudioPlaybackBuffer);
342  }
343 
344  } catch (exception&) {
345  jack_error("NetAudioBuffer allocation error...");
346  return false;
347  }
348 
349  // set the new timeout for the socket
350  /*
351  if (SetRxTimeout() == SOCKET_ERROR) {
352  jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE));
353  goto error;
354  }
355  */
356 
357  // set the new rx buffer size
358  if (SetNetBufferSize() == SOCKET_ERROR) {
359  jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
360  goto error;
361  }
362 
363  return true;
364 
365  error:
366  FreeNetworkBuffers();
367  return false;
368  }
369 
370  void JackNetMasterInterface::Exit()
371  {
372  jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID);
373 
374  // stop process
375  fRunning = false;
376 
377  // send a 'multicast euthanasia request' - new socket is required on macosx
378  jack_info("Exiting '%s'", fParams.fName);
379  SetPacketType(&fParams, KILL_MASTER);
380  JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort());
381 
382  session_params_t net_params;
383  memset(&net_params, 0, sizeof(session_params_t));
384  SessionParamsHToN(&fParams, &net_params);
385 
386  if (mcast_socket.NewSocket() == SOCKET_ERROR) {
387  jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
388  }
389  if (mcast_socket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) {
390  jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE));
391  }
392 
393  mcast_socket.Close();
394  }
395 
396  void JackNetMasterInterface::FatalRecvError()
397  {
398  // fatal connection issue, exit
399  jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
400  // ask to the manager to properly remove the master
401  Exit();
402  // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
403  ThreadExit();
404  }
405 
406  void JackNetMasterInterface::FatalSendError()
407  {
408  // fatal connection issue, exit
409  jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
410  // ask to the manager to properly remove the master
411  Exit();
412  // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
413  ThreadExit();
414  }
415 
416  int JackNetMasterInterface::Recv(size_t size, int flags)
417  {
418  int rx_bytes;
419 
420  if (((rx_bytes = fSocket.Recv(fRxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
421 
422  /*
423  net_error_t error = fSocket.GetError();
424  // no data isn't really a network error, so just return 0 available read bytes
425  if (error == NET_NO_DATA) {
426  return 0;
427  } else if (error == NET_CONN_ERROR) {
428  FatalRecvError();
429  } else {
430  jack_error("Error in master receive : %s", StrError(NET_ERROR_CODE));
431  }
432  */
433 
434  FatalRecvError();
435  }
436 
437  packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
438  PacketHeaderNToH(header, header);
439  return rx_bytes;
440  }
441 
442  int JackNetMasterInterface::Send(size_t size, int flags)
443  {
444  int tx_bytes;
445  packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
446  PacketHeaderHToN(header, header);
447 
448  if (((tx_bytes = fSocket.Send(fTxBuffer, size, flags)) == SOCKET_ERROR) && fRunning) {
449  /*
450  net_error_t error = fSocket.GetError();
451  if (error == NET_CONN_ERROR) {
452  FatalSendError();
453  } else {
454  jack_error("Error in master send : %s", StrError(NET_ERROR_CODE));
455  }
456  */
457  FatalSendError();
458  }
459  return tx_bytes;
460  }
461 
462  bool JackNetMasterInterface::IsSynched()
463  {
464  return (fCurrentCycleOffset <= fMaxCycleOffset);
465  }
466 
467  int JackNetMasterInterface::SyncSend()
468  {
469  fTxHeader.fCycle++;
470  fTxHeader.fSubCycle = 0;
471  fTxHeader.fDataType = 's';
472  fTxHeader.fIsLastPckt = (fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
473  fTxHeader.fPacketSize = fParams.fMtu;
474 
475  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
476  // PacketHeaderDisplay(&fTxHeader);
477  return Send(fTxHeader.fPacketSize, 0);
478  }
479 
480  int JackNetMasterInterface::DataSend()
481  {
482  if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR) {
483  return SOCKET_ERROR;
484  }
485  return AudioSend(fNetAudioCaptureBuffer, fParams.fSendAudioChannels);
486  }
487 
488  int JackNetMasterInterface::SyncRecv()
489  {
490  int rx_bytes = 0;
491  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
492 
493  /*
494  int rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
495 
496  if ((rx_bytes == 0) || (rx_bytes == SOCKET_ERROR)) {
497  // 0 bytes considered an error (lost connection)
498  return SOCKET_ERROR;
499  }
500 
501  fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
502  */
503 
504  // receive sync (launch the cycle)
505  do {
506  rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
507  // connection issue, send will detect it, so don't skip the cycle (return 0)
508  if (rx_bytes == SOCKET_ERROR) {
509  return SOCKET_ERROR;
510  }
511  }
512  while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
513 
514  fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
515 
516  if (fCurrentCycleOffset < fMaxCycleOffset) {
517  jack_info("Synching with latency = %d", fCurrentCycleOffset);
518  return 0;
519  } else {
520  rx_bytes = Recv(rx_head->fPacketSize, 0);
521  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
522  return rx_bytes;
523  }
524  }
525 
526  int JackNetMasterInterface::DataRecv()
527  {
528  int rx_bytes = 0;
529  uint recvd_midi_pckt = 0;
530  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
531 
532  while (!fRxHeader.fIsLastPckt) {
533  // how much data is queued on the rx buffer ?
534  rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
535 
536  // error here, problem with recv, just skip the cycle (return -1)
537  if (rx_bytes == SOCKET_ERROR) {
538  return rx_bytes;
539  }
540 
541  if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) {
542  // read data
543  switch (rx_head->fDataType) {
544 
545  case 'm': // midi
546  rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt);
547  break;
548 
549  case 'a': // audio
550  rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer);
551  break;
552 
553  case 's': // sync
554  jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
555  return FinishRecv(fNetAudioPlaybackBuffer);
556  }
557  }
558  }
559 
560  return rx_bytes;
561  }
562 
563  void JackNetMasterInterface::EncodeSyncPacket()
564  {
565  // This method contains every step of sync packet informations coding
566  // first of all, clear sync packet
567  memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
568 
569  // then, first step : transport
570  if (fParams.fTransportSync) {
571  EncodeTransportData();
572  TransportDataHToN(&fSendTransportData, &fSendTransportData);
573  // copy to TxBuffer
574  memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t));
575  }
576  // then others (freewheel etc.)
577  // ...
578 
579  // Transport not used for now...
580 
581  // Write active ports list
582  fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0;
583  }
584 
585  void JackNetMasterInterface::DecodeSyncPacket()
586  {
587  // This method contains every step of sync packet informations decoding process
588  // first : transport
589  if (fParams.fTransportSync) {
590  // copy received transport data to transport data structure
591  memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t));
592  TransportDataNToH(&fReturnTransportData, &fReturnTransportData);
593  DecodeTransportData();
594  }
595  // then others
596  // ...
597 
598  // Transport not used for now...
599  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
600 
601  // Read active ports list
602  if (fNetAudioCaptureBuffer) {
603  fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
604  }
605  }
606 
607 // JackNetSlaveInterface ************************************************************************************************
608 
609  uint JackNetSlaveInterface::fSlaveCounter = 0;
610 
611  bool JackNetSlaveInterface::Init()
612  {
613  jack_log("JackNetSlaveInterface::Init()");
614 
615  // set the parameters to send
616  strcpy(fParams.fPacketType, "params");
617  fParams.fProtocolVersion = SLAVE_PROTOCOL;
618  SetPacketType(&fParams, SLAVE_AVAILABLE);
619 
620  // init loop : get a master and start, do it until connection is ok
621  net_status_t status;
622  do {
623  // first, get a master, do it until a valid connection is running
624  do {
625  status = SendAvailableToMaster();
626  if (status == NET_SOCKET_ERROR) {
627  return false;
628  }
629  }
630  while (status != NET_CONNECTED);
631 
632  // then tell the master we are ready
633  jack_info("Initializing connection with %s...", fParams.fMasterNetName);
634  status = SendStartToMaster();
635  if (status == NET_ERROR) {
636  return false;
637  }
638  }
639  while (status != NET_ROLLING);
640 
641  return true;
642  }
643 
644  // Separate the connection protocol into two separated step
645  bool JackNetSlaveInterface::InitConnection(int time_out_sec)
646  {
647  jack_log("JackNetSlaveInterface::InitConnection()");
648  uint try_count = (time_out_sec > 0) ? ((1000000 * time_out_sec) / SLAVE_INIT_TIMEOUT) : LONG_MAX;
649 
650  // set the parameters to send
651  strcpy(fParams.fPacketType, "params");
652  fParams.fProtocolVersion = SLAVE_PROTOCOL;
653  SetPacketType(&fParams, SLAVE_AVAILABLE);
654 
655  net_status_t status;
656  do {
657  // get a master
658  status = SendAvailableToMaster(try_count);
659  if (status == NET_SOCKET_ERROR) {
660  return false;
661  }
662  }
663  while (status != NET_CONNECTED && --try_count > 0);
664 
665  return (try_count != 0);
666  }
667 
668  bool JackNetSlaveInterface::InitRendering()
669  {
670  jack_log("JackNetSlaveInterface::InitRendering()");
671 
672  net_status_t status;
673  do {
674  // then tell the master we are ready
675  jack_info("Initializing connection with %s...", fParams.fMasterNetName);
676  status = SendStartToMaster();
677  if (status == NET_ERROR)
678  return false;
679  }
680  while (status != NET_ROLLING);
681 
682  return true;
683  }
684 
685  net_status_t JackNetSlaveInterface::SendAvailableToMaster(long try_count)
686  {
687  jack_log("JackNetSlaveInterface::SendAvailableToMaster()");
688  // utility
689  session_params_t host_params;
690  int rx_bytes = 0;
691 
692  // socket
693  if (fSocket.NewSocket() == SOCKET_ERROR) {
694  jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE));
695  return NET_SOCKET_ERROR;
696  }
697 
698  if (fSocket.IsLocal(fMulticastIP)) {
699  jack_info("Local IP is used...");
700  } else {
701  // bind the socket
702  if (fSocket.Bind() == SOCKET_ERROR) {
703  jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE));
704  return NET_SOCKET_ERROR;
705  }
706  }
707 
708  // timeout on receive
709  if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR)
710  jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
711 
712  // disable local loop
713  if (fSocket.SetLocalLoop() == SOCKET_ERROR)
714  jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE));
715 
716  // send 'AVAILABLE' until 'SLAVE_SETUP' received
717  jack_info("Waiting for a master...");
718  do {
719  // send 'available'
720  session_params_t net_params;
721  memset(&net_params, 0, sizeof(session_params_t));
722  SessionParamsHToN(&fParams, &net_params);
723  if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR)
724  jack_error("Error in data send : %s", StrError(NET_ERROR_CODE));
725 
726  // filter incoming packets : don't exit while no error is detected
727  memset(&net_params, 0, sizeof(session_params_t));
728  rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
729  SessionParamsNToH(&net_params, &host_params);
730  if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
731  jack_error("Can't receive : %s", StrError(NET_ERROR_CODE));
732  return NET_RECV_ERROR;
733  }
734  }
735  while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0));
736 
737  // Time out failure..
738  if (try_count == 0) {
739  jack_error("Time out error in connect");
740  return NET_CONNECT_ERROR;
741  }
742 
743  // everything is OK, copy parameters
744  fParams = host_params;
745 
746  // connect the socket
747  if (fSocket.Connect() == SOCKET_ERROR) {
748  jack_error("Error in connect : %s", StrError(NET_ERROR_CODE));
749  return NET_CONNECT_ERROR;
750  }
751  return NET_CONNECTED;
752  }
753 
754  net_status_t JackNetSlaveInterface::SendStartToMaster()
755  {
756  jack_log("JackNetSlaveInterface::SendStartToMaster");
757 
758  // tell the master to start
759  session_params_t net_params;
760  memset(&net_params, 0, sizeof(session_params_t));
761  SetPacketType(&fParams, START_MASTER);
762  SessionParamsHToN(&fParams, &net_params);
763  if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
764  jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
765  return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR;
766  }
767  return NET_ROLLING;
768  }
769 
770  bool JackNetSlaveInterface::SetParams()
771  {
772  jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
773  fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
774  fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
775 
776  JackNetInterface::SetParams();
777 
778  fTxHeader.fDataStream = 'r';
779  fRxHeader.fDataStream = 's';
780 
781  // midi net buffers
782  if (fParams.fSendMidiChannels > 0) {
783  fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData);
784  }
785 
786  if (fParams.fReturnMidiChannels > 0) {
787  fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fTxData);
788  }
789 
790  try {
791 
792  // audio net buffers
793  if (fParams.fSendAudioChannels > 0) {
794  fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fRxData);
795  assert(fNetAudioCaptureBuffer);
796  }
797 
798  if (fParams.fReturnAudioChannels > 0) {
799  fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fTxData);
800  assert(fNetAudioPlaybackBuffer);
801  }
802 
803  } catch (exception&) {
804  jack_error("NetAudioBuffer allocation error...");
805  return false;
806  }
807 
808  // set the new buffer sizes
809  if (SetNetBufferSize() == SOCKET_ERROR) {
810  jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
811  goto error;
812  }
813 
814  return true;
815 
816  error:
817  FreeNetworkBuffers();
818  return false;
819  }
820 
821  void JackNetSlaveInterface::FatalRecvError()
822  {
823  jack_error("Recv connection lost error = %s", StrError(NET_ERROR_CODE));
824  throw JackNetException();
825  }
826 
827  void JackNetSlaveInterface::FatalSendError()
828  {
829  jack_error("Send connection lost error = %s", StrError(NET_ERROR_CODE));
830  throw JackNetException();
831  }
832 
833  int JackNetSlaveInterface::Recv(size_t size, int flags)
834  {
835  int rx_bytes = fSocket.Recv(fRxBuffer, size, flags);
836  // handle errors
837  if (rx_bytes == SOCKET_ERROR) {
838  /*
839  net_error_t error = fSocket.GetError();
840  // no data isn't really an error in realtime processing, so just return 0
841  if (error == NET_NO_DATA) {
842  jack_error("No data, is the master still running ?");
843  // if a network error occurs, this exception will restart the driver
844  } else if (error == NET_CONN_ERROR) {
845  FatalRecvError();
846  } else {
847  jack_error("Fatal error in slave receive : %s", StrError(NET_ERROR_CODE));
848  }
849  */
850  FatalRecvError();
851  }
852 
853  packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
854  PacketHeaderNToH(header, header);
855  return rx_bytes;
856  }
857 
858  int JackNetSlaveInterface::Send(size_t size, int flags)
859  {
860  packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
861  PacketHeaderHToN(header, header);
862  int tx_bytes = fSocket.Send(fTxBuffer, size, flags);
863 
864  // handle errors
865  if (tx_bytes == SOCKET_ERROR) {
866  /*
867  net_error_t error = fSocket.GetError();
868  // if a network error occurs, this exception will restart the driver
869  if (error == NET_CONN_ERROR) {
870  FatalSendError();
871  } else {
872  jack_error("Fatal error in slave send : %s", StrError(NET_ERROR_CODE));
873  }
874  */
875  FatalSendError();
876  }
877  return tx_bytes;
878  }
879 
880  int JackNetSlaveInterface::SyncRecv()
881  {
882  int rx_bytes = 0;
883  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
884 
885  // receive sync (launch the cycle)
886  do {
887  rx_bytes = Recv(fParams.fMtu, 0);
888  // connection issue, send will detect it, so don't skip the cycle (return 0)
889  if (rx_bytes == SOCKET_ERROR) {
890  return rx_bytes;
891  }
892  }
893  while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
894 
895  fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
896  return rx_bytes;
897  }
898 
899  int JackNetSlaveInterface::DataRecv()
900  {
901  int rx_bytes = 0;
902  uint recvd_midi_pckt = 0;
903  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
904 
905  while (!fRxHeader.fIsLastPckt) {
906  // how much data is queued on the rx buffer ?
907  rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
908 
909  // error here, problem with recv, just skip the cycle (return -1)
910  if (rx_bytes == SOCKET_ERROR) {
911  return rx_bytes;
912  }
913 
914  if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) {
915  // read data
916  switch (rx_head->fDataType) {
917 
918  case 'm': // midi
919  rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt);
920  break;
921 
922  case 'a': // audio
923  rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer);
924  break;
925 
926  case 's': // sync
927  jack_info("NetSlave : overloaded, skipping receive");
928  return FinishRecv(fNetAudioCaptureBuffer);
929  }
930  }
931  }
932 
933  fRxHeader.fCycle = rx_head->fCycle;
934  return rx_bytes;
935  }
936 
937  int JackNetSlaveInterface::SyncSend()
938  {
939  // tx header
940  if (fParams.fSlaveSyncMode) {
941  fTxHeader.fCycle = fRxHeader.fCycle;
942  } else {
943  fTxHeader.fCycle++;
944  }
945  fTxHeader.fSubCycle = 0;
946  fTxHeader.fDataType = 's';
947  fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
948  fTxHeader.fPacketSize = fParams.fMtu;
949 
950  memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
951  // PacketHeaderDisplay(&fTxHeader);
952  return Send(fTxHeader.fPacketSize, 0);
953  }
954 
955  int JackNetSlaveInterface::DataSend()
956  {
957  if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR) {
958  return SOCKET_ERROR;
959  }
960  return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels);
961  }
962 
963  // network sync------------------------------------------------------------------------
964  void JackNetSlaveInterface::EncodeSyncPacket()
965  {
966  // This method contains every step of sync packet informations coding
967  // first of all, clear sync packet
968  memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
969 
970  // then first step : transport
971  if (fParams.fTransportSync) {
972  EncodeTransportData();
973  TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
974  // copy to TxBuffer
975  memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t));
976  }
977  // then others
978  // ...
979 
980  // Transport is not used for now...
981 
982  // Write active ports list
983  fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0;
984  }
985 
986  void JackNetSlaveInterface::DecodeSyncPacket()
987  {
988  // This method contains every step of sync packet informations decoding process
989  // first : transport
990  if (fParams.fTransportSync) {
991  // copy received transport data to transport data structure
992  memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t));
993  TransportDataNToH(&fSendTransportData, &fSendTransportData);
994  DecodeTransportData();
995  }
996  // then others
997  // ...
998 
999  // Transport not used for now...
1000  packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
1001 
1002  // Read active ports list
1003  if (fNetAudioPlaybackBuffer) {
1004  fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
1005  }
1006  }
1007 
1008 }