2 Copyright (C) 2008-2011 Romain Moret at Grame
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.
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.
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.
19 #include "JackNetInterface.h"
20 #include "JackException.h"
21 #include "JackError.h"
28 TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
29 probably also use BUFFER_SIZE_MAX in everything related to MIDI events
30 handling (see MidiBufferInit in JackMidiPort.cpp)
35 // JackNetInterface*******************************************
37 JackNetInterface::JackNetInterface() : fSocket()
42 JackNetInterface::JackNetInterface(const char* multicast_ip
, int port
) : fSocket(multicast_ip
, port
)
44 strcpy(fMulticastIP
, multicast_ip
);
48 JackNetInterface::JackNetInterface(session_params_t
& params
, JackNetSocket
& socket
, const char* multicast_ip
) : fSocket(socket
)
51 strcpy(fMulticastIP
, multicast_ip
);
55 void JackNetInterface::Initialize()
60 fNetAudioCaptureBuffer
= NULL
;
61 fNetAudioPlaybackBuffer
= NULL
;
62 fNetMidiCaptureBuffer
= NULL
;
63 fNetMidiPlaybackBuffer
= NULL
;
64 memset(&fSendTransportData
, 0, sizeof(net_transport_data_t
));
65 memset(&fReturnTransportData
, 0, sizeof(net_transport_data_t
));
68 void JackNetInterface::FreeNetworkBuffers()
70 delete fNetMidiCaptureBuffer
;
71 delete fNetMidiPlaybackBuffer
;
72 delete fNetAudioCaptureBuffer
;
73 delete fNetAudioPlaybackBuffer
;
74 fNetMidiCaptureBuffer
= NULL
;
75 fNetMidiPlaybackBuffer
= NULL
;
76 fNetAudioCaptureBuffer
= NULL
;
77 fNetAudioPlaybackBuffer
= NULL
;
80 JackNetInterface::~JackNetInterface()
82 jack_log("JackNetInterface::~JackNetInterface");
87 delete fNetAudioCaptureBuffer
;
88 delete fNetAudioPlaybackBuffer
;
89 delete fNetMidiCaptureBuffer
;
90 delete fNetMidiPlaybackBuffer
;
93 int JackNetInterface::SetNetBufferSize()
96 float audio_size
= (fNetAudioCaptureBuffer
)
97 ? fNetAudioCaptureBuffer
->GetCycleSize()
98 : (fNetAudioPlaybackBuffer
) ? fNetAudioPlaybackBuffer
->GetCycleSize() : 0;
99 jack_log("audio_size %f", audio_size
);
102 float midi_size
= (fNetMidiCaptureBuffer
)
103 ? fNetMidiCaptureBuffer
->GetCycleSize()
104 : (fNetMidiPlaybackBuffer
) ? fNetMidiPlaybackBuffer
->GetCycleSize() : 0;
105 jack_log("midi_size %f", midi_size
);
107 // bufsize = sync + audio + midi
108 int bufsize
= NETWORK_MAX_LATENCY
* (fParams
.fMtu
+ (int)audio_size
+ (int)midi_size
);
109 jack_log("SetNetBufferSize bufsize = %d", bufsize
);
112 if (fSocket
.SetOption(SOL_SOCKET
, SO_SNDBUF
, &bufsize
, sizeof(bufsize
)) == SOCKET_ERROR
) {
117 if (fSocket
.SetOption(SOL_SOCKET
, SO_RCVBUF
, &bufsize
, sizeof(bufsize
)) == SOCKET_ERROR
) {
124 bool JackNetInterface::SetParams()
127 strcpy(fTxHeader
.fPacketType
, "header");
128 fTxHeader
.fID
= fParams
.fID
;
129 fTxHeader
.fCycle
= 0;
130 fTxHeader
.fSubCycle
= 0;
131 fTxHeader
.fIsLastPckt
= 0;
134 strcpy(fRxHeader
.fPacketType
, "header");
135 fRxHeader
.fID
= fParams
.fID
;
136 fRxHeader
.fCycle
= 0;
137 fRxHeader
.fSubCycle
= 0;
138 fRxHeader
.fIsLastPckt
= 0;
141 fTxBuffer
= new char[fParams
.fMtu
];
142 fRxBuffer
= new char[fParams
.fMtu
];
146 // net audio/midi buffers'addresses
147 fTxData
= fTxBuffer
+ HEADER_SIZE
;
148 fRxData
= fRxBuffer
+ HEADER_SIZE
;
153 int JackNetInterface::MidiSend(NetMidiBuffer
* buffer
, int midi_channnels
, int audio_channels
)
155 if (midi_channnels
> 0) {
156 // set global header fields and get the number of midi packets
157 fTxHeader
.fDataType
= 'm';
158 uint data_size
= buffer
->RenderFromJackPorts();
159 fTxHeader
.fNumPacket
= buffer
->GetNumPackets(data_size
, PACKET_AVAILABLE_SIZE(&fParams
));
161 for (uint subproc
= 0; subproc
< fTxHeader
.fNumPacket
; subproc
++) {
162 fTxHeader
.fSubCycle
= subproc
;
163 fTxHeader
.fIsLastPckt
= ((subproc
== (fTxHeader
.fNumPacket
- 1)) && audio_channels
== 0) ? 1 : 0;
164 fTxHeader
.fPacketSize
= HEADER_SIZE
+ buffer
->RenderToNetwork(subproc
, data_size
);
165 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
166 if (Send(fTxHeader
.fPacketSize
, 0) == SOCKET_ERROR
) {
174 int JackNetInterface::AudioSend(NetAudioBuffer
* buffer
, int audio_channels
)
177 if (audio_channels
> 0) {
178 fTxHeader
.fDataType
= 'a';
179 fTxHeader
.fActivePorts
= buffer
->RenderFromJackPorts();
180 fTxHeader
.fNumPacket
= buffer
->GetNumPackets(fTxHeader
.fActivePorts
);
182 for (uint subproc
= 0; subproc
< fTxHeader
.fNumPacket
; subproc
++) {
183 fTxHeader
.fSubCycle
= subproc
;
184 fTxHeader
.fIsLastPckt
= (subproc
== (fTxHeader
.fNumPacket
- 1)) ? 1 : 0;
185 fTxHeader
.fPacketSize
= HEADER_SIZE
+ buffer
->RenderToNetwork(subproc
, fTxHeader
.fActivePorts
);
186 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
187 // PacketHeaderDisplay(&fTxHeader);
188 if (Send(fTxHeader
.fPacketSize
, 0) == SOCKET_ERROR
) {
196 int JackNetInterface::MidiRecv(packet_header_t
* rx_head
, NetMidiBuffer
* buffer
, uint
& recvd_midi_pckt
)
198 int rx_bytes
= Recv(rx_head
->fPacketSize
, 0);
199 fRxHeader
.fCycle
= rx_head
->fCycle
;
200 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
201 buffer
->RenderFromNetwork(rx_head
->fSubCycle
, rx_bytes
- HEADER_SIZE
);
203 // Last midi packet is received, so finish rendering...
204 if (++recvd_midi_pckt
== rx_head
->fNumPacket
) {
205 buffer
->RenderToJackPorts();
210 int JackNetInterface::AudioRecv(packet_header_t
* rx_head
, NetAudioBuffer
* buffer
)
212 int rx_bytes
= Recv(rx_head
->fPacketSize
, 0);
213 fRxHeader
.fCycle
= rx_head
->fCycle
;
214 fRxHeader
.fSubCycle
= rx_head
->fSubCycle
;
215 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
216 fRxHeader
.fActivePorts
= rx_head
->fActivePorts
;
217 rx_bytes
= buffer
->RenderFromNetwork(rx_head
->fCycle
, rx_head
->fSubCycle
, fRxHeader
.fActivePorts
);
219 // Last audio packet is received, so finish rendering...
220 if (fRxHeader
.fIsLastPckt
) {
221 buffer
->RenderToJackPorts();
226 int JackNetInterface::FinishRecv(NetAudioBuffer
* buffer
)
228 buffer
->RenderToJackPorts();
229 return NET_PACKET_ERROR
;
232 NetAudioBuffer
* JackNetInterface::AudioBufferFactory(int nports
, char* buffer
)
234 switch (fParams
.fSampleEncoder
) {
236 case JackFloatEncoder
:
237 return new NetFloatAudioBuffer(&fParams
, nports
, buffer
);
240 return new NetIntAudioBuffer(&fParams
, nports
, buffer
);
243 case JackCeltEncoder
:
244 return new NetCeltAudioBuffer(&fParams
, nports
, buffer
, fParams
.fKBps
);
250 void JackNetInterface::SetRcvTimeOut()
253 if (fSocket
.SetTimeOut(PACKET_TIMEOUT
) == SOCKET_ERROR
) {
254 jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE
));
261 // JackNetMasterInterface ************************************************************************************
263 bool JackNetMasterInterface::Init()
265 jack_log("JackNetMasterInterface::Init : ID %u", fParams
.fID
);
267 session_params_t host_params
;
272 if (fSocket
.NewSocket() == SOCKET_ERROR
) {
273 jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE
));
277 // timeout on receive (for init)
278 if (fSocket
.SetTimeOut(MASTER_INIT_TIMEOUT
) < 0) {
279 jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE
));
283 if (fSocket
.Connect() == SOCKET_ERROR
) {
284 jack_error("Can't connect : %s", StrError(NET_ERROR_CODE
));
288 // send 'SLAVE_SETUP' until 'START_MASTER' received
289 jack_info("Sending parameters to %s...", fParams
.fSlaveNetName
);
292 session_params_t net_params
;
293 memset(&net_params
, 0, sizeof(session_params_t
));
294 SetPacketType(&fParams
, SLAVE_SETUP
);
295 SessionParamsHToN(&fParams
, &net_params
);
297 if (fSocket
.Send(&net_params
, sizeof(session_params_t
), 0) == SOCKET_ERROR
) {
298 jack_error("Error in send : %s", StrError(NET_ERROR_CODE
));
301 memset(&net_params
, 0, sizeof(session_params_t
));
302 if (((rx_bytes
= fSocket
.Recv(&net_params
, sizeof(session_params_t
), 0)) == SOCKET_ERROR
) && (fSocket
.GetError() != NET_NO_DATA
)) {
303 jack_error("Problem with network");
307 SessionParamsNToH(&net_params
, &host_params
);
309 while ((GetPacketType(&host_params
) != START_MASTER
) && (++attempt
< SLAVE_SETUP_RETRY
));
311 if (attempt
== SLAVE_SETUP_RETRY
) {
312 jack_error("Slave doesn't respond, exiting");
319 bool JackNetMasterInterface::SetParams()
321 jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
322 fParams
.fSendAudioChannels
, fParams
.fReturnAudioChannels
,
323 fParams
.fSendMidiChannels
, fParams
.fReturnMidiChannels
);
325 JackNetInterface::SetParams();
327 fTxHeader
.fDataStream
= 's';
328 fRxHeader
.fDataStream
= 'r';
330 fMaxCycleOffset
= fParams
.fNetworkLatency
;
333 if (fParams
.fSendMidiChannels
> 0) {
334 fNetMidiCaptureBuffer
= new NetMidiBuffer(&fParams
, fParams
.fSendMidiChannels
, fTxData
);
337 if (fParams
.fReturnMidiChannels
> 0) {
338 fNetMidiPlaybackBuffer
= new NetMidiBuffer(&fParams
, fParams
.fReturnMidiChannels
, fRxData
);
344 if (fParams
.fSendAudioChannels
> 0) {
345 fNetAudioCaptureBuffer
= AudioBufferFactory(fParams
.fSendAudioChannels
, fTxData
);
346 assert(fNetAudioCaptureBuffer
);
349 if (fParams
.fReturnAudioChannels
> 0) {
350 fNetAudioPlaybackBuffer
= AudioBufferFactory(fParams
.fReturnAudioChannels
, fRxData
);
351 assert(fNetAudioPlaybackBuffer
);
354 } catch (exception
&) {
355 jack_error("NetAudioBuffer allocation error...");
359 // set the new rx buffer size
360 if (SetNetBufferSize() == SOCKET_ERROR
) {
361 jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE
));
368 FreeNetworkBuffers();
372 void JackNetMasterInterface::Exit()
374 jack_log("JackNetMasterInterface::Exit, ID %u", fParams
.fID
);
379 // send a 'multicast euthanasia request' - new socket is required on macosx
380 jack_info("Exiting '%s'", fParams
.fName
);
381 SetPacketType(&fParams
, KILL_MASTER
);
382 JackNetSocket
mcast_socket(fMulticastIP
, fSocket
.GetPort());
384 session_params_t net_params
;
385 memset(&net_params
, 0, sizeof(session_params_t
));
386 SessionParamsHToN(&fParams
, &net_params
);
388 if (mcast_socket
.NewSocket() == SOCKET_ERROR
) {
389 jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE
));
391 if (mcast_socket
.SendTo(&net_params
, sizeof(session_params_t
), 0, fMulticastIP
) == SOCKET_ERROR
) {
392 jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE
));
395 mcast_socket
.Close();
398 void JackNetMasterInterface::FatalRecvError()
400 // fatal connection issue, exit
401 jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE
), fParams
.fName
);
402 // ask to the manager to properly remove the master
404 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
408 void JackNetMasterInterface::FatalSendError()
410 // fatal connection issue, exit
411 jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE
), fParams
.fName
);
412 // ask to the manager to properly remove the master
414 // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
418 int JackNetMasterInterface::Recv(size_t size
, int flags
)
422 if (((rx_bytes
= fSocket
.Recv(fRxBuffer
, size
, flags
)) == SOCKET_ERROR
) && fRunning
) {
426 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
427 PacketHeaderNToH(header
, header
);
431 int JackNetMasterInterface::Send(size_t size
, int flags
)
434 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fTxBuffer
);
435 PacketHeaderHToN(header
, header
);
437 if (((tx_bytes
= fSocket
.Send(fTxBuffer
, size
, flags
)) == SOCKET_ERROR
) && fRunning
) {
443 bool JackNetMasterInterface::IsSynched()
445 return (fCurrentCycleOffset
<= fMaxCycleOffset
);
448 int JackNetMasterInterface::SyncSend()
453 fTxHeader
.fSubCycle
= 0;
454 fTxHeader
.fDataType
= 's';
455 fTxHeader
.fIsLastPckt
= (fParams
.fSendMidiChannels
== 0 && fParams
.fSendAudioChannels
== 0) ? 1 : 0;
456 fTxHeader
.fPacketSize
= fParams
.fMtu
;
458 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
459 // PacketHeaderDisplay(&fTxHeader);
460 return Send(fTxHeader
.fPacketSize
, 0);
463 int JackNetMasterInterface::DataSend()
465 if (MidiSend(fNetMidiCaptureBuffer
, fParams
.fSendMidiChannels
, fParams
.fSendAudioChannels
) == SOCKET_ERROR
) {
468 return AudioSend(fNetAudioCaptureBuffer
, fParams
.fSendAudioChannels
);
471 int JackNetMasterInterface::SyncRecv()
474 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
476 // receive sync (launch the cycle)
478 rx_bytes
= Recv(fParams
.fMtu
, MSG_PEEK
);
479 // connection issue, send will detect it, so don't skip the cycle (return 0)
480 if (rx_bytes
== SOCKET_ERROR
) {
484 while ((strcmp(rx_head
->fPacketType
, "header") != 0) && (rx_head
->fDataType
!= 's'));
486 fCurrentCycleOffset
= fTxHeader
.fCycle
- rx_head
->fCycle
;
488 if (fCurrentCycleOffset
< fMaxCycleOffset
) {
489 jack_info("Synching with latency = %d", fCurrentCycleOffset
);
492 rx_bytes
= Recv(rx_head
->fPacketSize
, 0);
493 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
498 int JackNetMasterInterface::DataRecv()
501 uint recvd_midi_pckt
= 0;
502 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
504 while (!fRxHeader
.fIsLastPckt
) {
505 // how much data is queued on the rx buffer ?
506 rx_bytes
= Recv(fParams
.fMtu
, MSG_PEEK
);
508 // error here, problem with recv, just skip the cycle (return -1)
509 if (rx_bytes
== SOCKET_ERROR
) {
513 if (rx_bytes
&& (rx_head
->fDataStream
== 'r') && (rx_head
->fID
== fParams
.fID
)) {
515 switch (rx_head
->fDataType
) {
518 rx_bytes
= MidiRecv(rx_head
, fNetMidiPlaybackBuffer
, recvd_midi_pckt
);
522 rx_bytes
= AudioRecv(rx_head
, fNetAudioPlaybackBuffer
);
526 jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams
.fName
);
527 return FinishRecv(fNetAudioPlaybackBuffer
);
535 void JackNetMasterInterface::EncodeSyncPacket()
537 // This method contains every step of sync packet informations coding
538 // first of all, clear sync packet
539 memset(fTxData
, 0, PACKET_AVAILABLE_SIZE(&fParams
));
541 // then, first step : transport
542 if (fParams
.fTransportSync
) {
543 EncodeTransportData();
544 TransportDataHToN(&fSendTransportData
, &fSendTransportData
);
546 memcpy(fTxData
, &fSendTransportData
, sizeof(net_transport_data_t
));
548 // then others (freewheel etc.)
551 // Transport not used for now...
553 // Write active ports list
554 fTxHeader
.fActivePorts
= (fNetAudioPlaybackBuffer
) ? fNetAudioPlaybackBuffer
->ActivePortsToNetwork(fTxData
) : 0;
557 void JackNetMasterInterface::DecodeSyncPacket()
559 // This method contains every step of sync packet informations decoding process
561 if (fParams
.fTransportSync
) {
562 // copy received transport data to transport data structure
563 memcpy(&fReturnTransportData
, fRxData
, sizeof(net_transport_data_t
));
564 TransportDataNToH(&fReturnTransportData
, &fReturnTransportData
);
565 DecodeTransportData();
570 // Transport not used for now...
571 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
573 // Read active ports list
574 if (fNetAudioCaptureBuffer
) {
575 fNetAudioCaptureBuffer
->ActivePortsFromNetwork(fRxData
, rx_head
->fActivePorts
);
579 // JackNetSlaveInterface ************************************************************************************************
581 uint
JackNetSlaveInterface::fSlaveCounter
= 0;
583 void JackNetSlaveInterface::InitAPI()
585 // open Socket API with the first slave
586 if (fSlaveCounter
++ == 0) {
587 if (SocketAPIInit() < 0) {
588 jack_error("Can't init Socket API, exiting...");
589 throw std::bad_alloc();
594 bool JackNetSlaveInterface::Init()
596 jack_log("JackNetSlaveInterface::Init()");
598 // set the parameters to send
599 strcpy(fParams
.fPacketType
, "params");
600 fParams
.fProtocolVersion
= SLAVE_PROTOCOL
;
601 SetPacketType(&fParams
, SLAVE_AVAILABLE
);
603 // init loop : get a master and start, do it until connection is ok
606 // first, get a master, do it until a valid connection is running
608 status
= SendAvailableToMaster();
609 if (status
== NET_SOCKET_ERROR
) {
613 while (status
!= NET_CONNECTED
);
615 // then tell the master we are ready
616 jack_info("Initializing connection with %s...", fParams
.fMasterNetName
);
617 status
= SendStartToMaster();
618 if (status
== NET_ERROR
) {
622 while (status
!= NET_ROLLING
);
627 // Separate the connection protocol into two separated step
628 bool JackNetSlaveInterface::InitConnection(int time_out_sec
)
630 jack_log("JackNetSlaveInterface::InitConnection()");
631 uint try_count
= (time_out_sec
> 0) ? ((1000000 * time_out_sec
) / SLAVE_INIT_TIMEOUT
) : LONG_MAX
;
633 // set the parameters to send
634 strcpy(fParams
.fPacketType
, "params");
635 fParams
.fProtocolVersion
= SLAVE_PROTOCOL
;
636 SetPacketType(&fParams
, SLAVE_AVAILABLE
);
641 status
= SendAvailableToMaster(try_count
);
642 if (status
== NET_SOCKET_ERROR
) {
646 while (status
!= NET_CONNECTED
&& --try_count
> 0);
648 return (try_count
!= 0);
651 bool JackNetSlaveInterface::InitRendering()
653 jack_log("JackNetSlaveInterface::InitRendering()");
657 // then tell the master we are ready
658 jack_info("Initializing connection with %s...", fParams
.fMasterNetName
);
659 status
= SendStartToMaster();
660 if (status
== NET_ERROR
) {
664 while (status
!= NET_ROLLING
);
669 net_status_t
JackNetSlaveInterface::SendAvailableToMaster(long try_count
)
671 jack_log("JackNetSlaveInterface::SendAvailableToMaster()");
673 session_params_t host_params
;
677 if (fSocket
.NewSocket() == SOCKET_ERROR
) {
678 jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE
));
679 return NET_SOCKET_ERROR
;
682 if (fSocket
.IsLocal(fMulticastIP
)) {
683 jack_info("Local IP is used...");
686 if (fSocket
.Bind() == SOCKET_ERROR
) {
687 jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE
));
688 return NET_SOCKET_ERROR
;
692 // timeout on receive (for init)
693 if (fSocket
.SetTimeOut(SLAVE_INIT_TIMEOUT
) == SOCKET_ERROR
) {
694 jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE
));
697 // disable local loop
698 if (fSocket
.SetLocalLoop() == SOCKET_ERROR
) {
699 jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE
));
702 // send 'AVAILABLE' until 'SLAVE_SETUP' received
703 jack_info("Waiting for a master...");
706 session_params_t net_params
;
707 memset(&net_params
, 0, sizeof(session_params_t
));
708 SessionParamsHToN(&fParams
, &net_params
);
709 if (fSocket
.SendTo(&net_params
, sizeof(session_params_t
), 0, fMulticastIP
) == SOCKET_ERROR
) {
710 jack_error("Error in data send : %s", StrError(NET_ERROR_CODE
));
713 // filter incoming packets : don't exit while no error is detected
714 memset(&net_params
, 0, sizeof(session_params_t
));
715 rx_bytes
= fSocket
.CatchHost(&net_params
, sizeof(session_params_t
), 0);
716 SessionParamsNToH(&net_params
, &host_params
);
717 if ((rx_bytes
== SOCKET_ERROR
) && (fSocket
.GetError() != NET_NO_DATA
)) {
718 jack_error("Can't receive : %s", StrError(NET_ERROR_CODE
));
719 return NET_RECV_ERROR
;
722 while (strcmp(host_params
.fPacketType
, fParams
.fPacketType
) && (GetPacketType(&host_params
) != SLAVE_SETUP
) && (--try_count
> 0));
724 // Time out failure..
725 if (try_count
== 0) {
726 jack_error("Time out error in connect");
727 return NET_CONNECT_ERROR
;
730 // everything is OK, copy parameters
731 fParams
= host_params
;
733 // connect the socket
734 if (fSocket
.Connect() == SOCKET_ERROR
) {
735 jack_error("Error in connect : %s", StrError(NET_ERROR_CODE
));
736 return NET_CONNECT_ERROR
;
738 return NET_CONNECTED
;
741 net_status_t
JackNetSlaveInterface::SendStartToMaster()
743 jack_log("JackNetSlaveInterface::SendStartToMaster");
745 // tell the master to start
746 session_params_t net_params
;
747 memset(&net_params
, 0, sizeof(session_params_t
));
748 SetPacketType(&fParams
, START_MASTER
);
749 SessionParamsHToN(&fParams
, &net_params
);
750 if (fSocket
.Send(&net_params
, sizeof(session_params_t
), 0) == SOCKET_ERROR
) {
751 jack_error("Error in send : %s", StrError(NET_ERROR_CODE
));
752 return (fSocket
.GetError() == NET_CONN_ERROR
) ? NET_ERROR
: NET_SEND_ERROR
;
757 bool JackNetSlaveInterface::SetParams()
759 jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
760 fParams
.fSendAudioChannels
, fParams
.fReturnAudioChannels
,
761 fParams
.fSendMidiChannels
, fParams
.fReturnMidiChannels
);
763 JackNetInterface::SetParams();
765 fTxHeader
.fDataStream
= 'r';
766 fRxHeader
.fDataStream
= 's';
769 if (fParams
.fSendMidiChannels
> 0) {
770 fNetMidiCaptureBuffer
= new NetMidiBuffer(&fParams
, fParams
.fSendMidiChannels
, fRxData
);
773 if (fParams
.fReturnMidiChannels
> 0) {
774 fNetMidiPlaybackBuffer
= new NetMidiBuffer(&fParams
, fParams
.fReturnMidiChannels
, fTxData
);
780 if (fParams
.fSendAudioChannels
> 0) {
781 fNetAudioCaptureBuffer
= AudioBufferFactory(fParams
.fSendAudioChannels
, fRxData
);
782 assert(fNetAudioCaptureBuffer
);
785 if (fParams
.fReturnAudioChannels
> 0) {
786 fNetAudioPlaybackBuffer
= AudioBufferFactory(fParams
.fReturnAudioChannels
, fTxData
);
787 assert(fNetAudioPlaybackBuffer
);
790 } catch (exception
&) {
791 jack_error("NetAudioBuffer allocation error...");
795 // set the new buffer sizes
796 if (SetNetBufferSize() == SOCKET_ERROR
) {
797 jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE
));
804 FreeNetworkBuffers();
808 void JackNetSlaveInterface::FatalRecvError()
810 jack_error("Recv connection lost error = %s", StrError(NET_ERROR_CODE
));
811 throw JackNetException();
814 void JackNetSlaveInterface::FatalSendError()
816 jack_error("Send connection lost error = %s", StrError(NET_ERROR_CODE
));
817 throw JackNetException();
820 int JackNetSlaveInterface::Recv(size_t size
, int flags
)
822 int rx_bytes
= fSocket
.Recv(fRxBuffer
, size
, flags
);
825 if (rx_bytes
== SOCKET_ERROR
) {
829 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
830 PacketHeaderNToH(header
, header
);
834 int JackNetSlaveInterface::Send(size_t size
, int flags
)
836 packet_header_t
* header
= reinterpret_cast<packet_header_t
*>(fTxBuffer
);
837 PacketHeaderHToN(header
, header
);
838 int tx_bytes
= fSocket
.Send(fTxBuffer
, size
, flags
);
841 if (tx_bytes
== SOCKET_ERROR
) {
848 int JackNetSlaveInterface::SyncRecv()
851 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
853 // receive sync (launch the cycle)
855 rx_bytes
= Recv(fParams
.fMtu
, 0);
856 // connection issue, send will detect it, so don't skip the cycle (return 0)
857 if (rx_bytes
== SOCKET_ERROR
) {
861 while ((strcmp(rx_head
->fPacketType
, "header") != 0) && (rx_head
->fDataType
!= 's'));
863 fRxHeader
.fIsLastPckt
= rx_head
->fIsLastPckt
;
869 int JackNetSlaveInterface::DataRecv()
872 uint recvd_midi_pckt
= 0;
873 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
875 while (!fRxHeader
.fIsLastPckt
) {
876 // how much data is queued on the rx buffer ?
877 rx_bytes
= Recv(fParams
.fMtu
, MSG_PEEK
);
879 // error here, problem with recv, just skip the cycle (return -1)
880 if (rx_bytes
== SOCKET_ERROR
) {
884 if (rx_bytes
&& (rx_head
->fDataStream
== 's') && (rx_head
->fID
== fParams
.fID
)) {
886 switch (rx_head
->fDataType
) {
889 rx_bytes
= MidiRecv(rx_head
, fNetMidiCaptureBuffer
, recvd_midi_pckt
);
893 rx_bytes
= AudioRecv(rx_head
, fNetAudioCaptureBuffer
);
897 jack_info("NetSlave : overloaded, skipping receive");
898 return FinishRecv(fNetAudioCaptureBuffer
);
903 fRxHeader
.fCycle
= rx_head
->fCycle
;
907 int JackNetSlaveInterface::SyncSend()
910 if (fParams
.fSlaveSyncMode
) {
911 fTxHeader
.fCycle
= fRxHeader
.fCycle
;
915 fTxHeader
.fSubCycle
= 0;
916 fTxHeader
.fDataType
= 's';
917 fTxHeader
.fIsLastPckt
= (fParams
.fReturnMidiChannels
== 0 && fParams
.fReturnAudioChannels
== 0) ? 1 : 0;
918 fTxHeader
.fPacketSize
= fParams
.fMtu
;
920 memcpy(fTxBuffer
, &fTxHeader
, HEADER_SIZE
);
921 // PacketHeaderDisplay(&fTxHeader);
922 return Send(fTxHeader
.fPacketSize
, 0);
925 int JackNetSlaveInterface::DataSend()
927 if (MidiSend(fNetMidiPlaybackBuffer
, fParams
.fReturnMidiChannels
, fParams
.fReturnAudioChannels
) == SOCKET_ERROR
) {
930 return AudioSend(fNetAudioPlaybackBuffer
, fParams
.fReturnAudioChannels
);
933 // network sync------------------------------------------------------------------------
934 void JackNetSlaveInterface::EncodeSyncPacket()
936 // This method contains every step of sync packet informations coding
937 // first of all, clear sync packet
938 memset(fTxData
, 0, PACKET_AVAILABLE_SIZE(&fParams
));
940 // then first step : transport
941 if (fParams
.fTransportSync
) {
942 EncodeTransportData();
943 TransportDataHToN(&fReturnTransportData
, &fReturnTransportData
);
945 memcpy(fTxData
, &fReturnTransportData
, sizeof(net_transport_data_t
));
950 // Transport is not used for now...
952 // Write active ports list
953 fTxHeader
.fActivePorts
= (fNetAudioCaptureBuffer
) ? fNetAudioCaptureBuffer
->ActivePortsToNetwork(fTxData
) : 0;
956 void JackNetSlaveInterface::DecodeSyncPacket()
958 // This method contains every step of sync packet informations decoding process
960 if (fParams
.fTransportSync
) {
961 // copy received transport data to transport data structure
962 memcpy(&fSendTransportData
, fRxData
, sizeof(net_transport_data_t
));
963 TransportDataNToH(&fSendTransportData
, &fSendTransportData
);
964 DecodeTransportData();
969 // Transport not used for now...
970 packet_header_t
* rx_head
= reinterpret_cast<packet_header_t
*>(fRxBuffer
);
972 // Read active ports list
973 if (fNetAudioPlaybackBuffer
) {
974 fNetAudioPlaybackBuffer
->ActivePortsFromNetwork(fRxData
, rx_head
->fActivePorts
);