git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2840 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -36,6 +36,9 @@ namespace Jack | |||||
| jack_error ( "Can't init Socket API, exiting..." ); | jack_error ( "Can't init Socket API, exiting..." ); | ||||
| //global parametering | //global parametering | ||||
| //we can't call JackNetSlaveInterface constructor with some parameters before | |||||
| //because we don't have full parametering right now | |||||
| //parameters will be parsed from the param list, and then JackNetSlaveInterface will be filled with proper values | |||||
| fMulticastIP = new char[16]; | fMulticastIP = new char[16]; | ||||
| strcpy ( fMulticastIP, DEFAULT_MULTICAST_IP ); | strcpy ( fMulticastIP, DEFAULT_MULTICAST_IP ); | ||||
| uint port = DEFAULT_PORT; | uint port = DEFAULT_PORT; | ||||
| @@ -101,12 +104,15 @@ namespace Jack | |||||
| } | } | ||||
| } | } | ||||
| //set the socket parameters | |||||
| fSocket.SetPort ( port ); | fSocket.SetPort ( port ); | ||||
| fSocket.SetAddress ( fMulticastIP, port ); | fSocket.SetAddress ( fMulticastIP, port ); | ||||
| //set the audio adapter interface channel values | |||||
| SetInputs ( fParams.fSendAudioChannels ); | SetInputs ( fParams.fSendAudioChannels ); | ||||
| SetOutputs ( fParams.fReturnAudioChannels ); | SetOutputs ( fParams.fReturnAudioChannels ); | ||||
| //soft buffers will be allocated later (once network initialization done) | |||||
| fSoftCaptureBuffer = NULL; | fSoftCaptureBuffer = NULL; | ||||
| fSoftPlaybackBuffer = NULL; | fSoftPlaybackBuffer = NULL; | ||||
| } | } | ||||
| @@ -355,6 +361,8 @@ namespace Jack | |||||
| //read/write operations--------------------------------------------------------------- | //read/write operations--------------------------------------------------------------- | ||||
| int JackNetAdapter::Read() | int JackNetAdapter::Read() | ||||
| { | { | ||||
| //don't return -1 in case of sync recv failure | |||||
| //we need the process to continue for network error detection | |||||
| if ( SyncRecv() == SOCKET_ERROR ) | if ( SyncRecv() == SOCKET_ERROR ) | ||||
| return 0; | return 0; | ||||
| @@ -115,7 +115,7 @@ namespace Jack | |||||
| //init network | //init network | ||||
| if ( !JackNetSlaveInterface::Init() ) | if ( !JackNetSlaveInterface::Init() ) | ||||
| return false;; | |||||
| return false; | |||||
| //set global paramaters | //set global paramaters | ||||
| SetParams(); | SetParams(); | ||||
| @@ -488,6 +488,7 @@ namespace Jack | |||||
| JackDriver::CycleTakeBeginTime(); | JackDriver::CycleTakeBeginTime(); | ||||
| //decode sync | //decode sync | ||||
| //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified | |||||
| if ( DecodeSyncPacket() < 0 ) | if ( DecodeSyncPacket() < 0 ) | ||||
| return 0; | return 0; | ||||
| @@ -67,6 +67,7 @@ namespace Jack | |||||
| JackNetInterface::~JackNetInterface() | JackNetInterface::~JackNetInterface() | ||||
| { | { | ||||
| jack_log ( "JackNetInterface::~JackNetInterface" ); | jack_log ( "JackNetInterface::~JackNetInterface" ); | ||||
| fSocket.Close(); | fSocket.Close(); | ||||
| delete[] fTxBuffer; | delete[] fTxBuffer; | ||||
| delete[] fRxBuffer; | delete[] fRxBuffer; | ||||
| @@ -247,14 +248,13 @@ namespace Jack | |||||
| int JackNetMasterInterface::SetRxTimeout() | int JackNetMasterInterface::SetRxTimeout() | ||||
| { | { | ||||
| jack_log ( "JackNetMasterInterface::SetRxTimeout" ); | |||||
| float time = 0; | float time = 0; | ||||
| //slow mode, very short timeout on recv | |||||
| if ( fParams.fNetworkMode == 's' ) | |||||
| //slow or normal mode, short timeout on recv (2 audio subcycles) | |||||
| if ( ( fParams.fNetworkMode == 's' ) || ( fParams.fNetworkMode == 'n' ) ) | |||||
| time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) ); | time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) ); | ||||
| //normal mode, short timeout on recv | |||||
| else if ( fParams.fNetworkMode == 'n' ) | |||||
| time = 4000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) ); | |||||
| //fast mode, wait for the entire cycle duration | |||||
| //fast mode, wait for 75% of the entire cycle duration | |||||
| else if ( fParams.fNetworkMode == 'f' ) | else if ( fParams.fNetworkMode == 'f' ) | ||||
| time = 750000.f * ( static_cast<float> ( fParams.fPeriodSize ) / static_cast<float> ( fParams.fSampleRate ) ); | time = 750000.f * ( static_cast<float> ( fParams.fPeriodSize ) / static_cast<float> ( fParams.fSampleRate ) ); | ||||
| return fSocket.SetTimeOut ( static_cast<int> ( time ) ); | return fSocket.SetTimeOut ( static_cast<int> ( time ) ); | ||||
| @@ -302,16 +302,16 @@ namespace Jack | |||||
| int JackNetMasterInterface::Send ( size_t size, int flags ) | int JackNetMasterInterface::Send ( size_t size, int flags ) | ||||
| { | { | ||||
| int tx_bytes; | int tx_bytes; | ||||
| if ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) | |||||
| if ( ( ( tx_bytes = fSocket.Send ( fTxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) | |||||
| { | { | ||||
| net_error_t error = fSocket.GetError(); | net_error_t error = fSocket.GetError(); | ||||
| if ( fRunning && ( error == NET_CONN_ERROR ) ) | |||||
| if ( error == NET_CONN_ERROR ) | |||||
| { | { | ||||
| //fatal connection issue, exit | //fatal connection issue, exit | ||||
| jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); | jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); | ||||
| Exit(); | Exit(); | ||||
| } | } | ||||
| else if ( fRunning ) | |||||
| else | |||||
| jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) ); | jack_error ( "Error in send : %s", StrError ( NET_ERROR_CODE ) ); | ||||
| } | } | ||||
| return tx_bytes; | return tx_bytes; | ||||
| @@ -320,20 +320,20 @@ namespace Jack | |||||
| int JackNetMasterInterface::Recv ( size_t size, int flags ) | int JackNetMasterInterface::Recv ( size_t size, int flags ) | ||||
| { | { | ||||
| int rx_bytes; | int rx_bytes; | ||||
| if ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR ) | |||||
| if ( ( ( rx_bytes = fSocket.Recv ( fRxBuffer, size, flags ) ) == SOCKET_ERROR ) && fRunning ) | |||||
| { | { | ||||
| net_error_t error = fSocket.GetError(); | net_error_t error = fSocket.GetError(); | ||||
| //no data isn't really a network error, so just return 0 avalaible read bytes | //no data isn't really a network error, so just return 0 avalaible read bytes | ||||
| if ( error == NET_NO_DATA ) | if ( error == NET_NO_DATA ) | ||||
| return 0; | return 0; | ||||
| else if ( fRunning && ( error == NET_CONN_ERROR ) ) | |||||
| else if ( error == NET_CONN_ERROR ) | |||||
| { | { | ||||
| //fatal connection issue, exit | //fatal connection issue, exit | ||||
| jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); | jack_error ( "'%s' : %s, exiting.", fParams.fName, StrError ( NET_ERROR_CODE ) ); | ||||
| //ask to the manager to properly remove the master | //ask to the manager to properly remove the master | ||||
| Exit(); | Exit(); | ||||
| } | } | ||||
| else if ( fRunning ) | |||||
| else | |||||
| jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) ); | jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) ); | ||||
| } | } | ||||
| return rx_bytes; | return rx_bytes; | ||||
| @@ -494,6 +494,8 @@ namespace Jack | |||||
| // JackNetSlaveInterface ************************************************************************************************ | // JackNetSlaveInterface ************************************************************************************************ | ||||
| uint JackNetSlaveInterface::fSlaveCounter = 0; | |||||
| bool JackNetSlaveInterface::Init() | bool JackNetSlaveInterface::Init() | ||||
| { | { | ||||
| jack_log ( "JackNetSlaveInterface::Init()" ); | jack_log ( "JackNetSlaveInterface::Init()" ); | ||||
| @@ -533,7 +535,6 @@ namespace Jack | |||||
| //utility | //utility | ||||
| session_params_t params; | session_params_t params; | ||||
| int rx_bytes = 0; | int rx_bytes = 0; | ||||
| unsigned char loop = 0; | |||||
| //socket | //socket | ||||
| if ( fSocket.NewSocket() == SOCKET_ERROR ) | if ( fSocket.NewSocket() == SOCKET_ERROR ) | ||||
| @@ -551,7 +552,7 @@ namespace Jack | |||||
| jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); | jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); | ||||
| //disable local loop | //disable local loop | ||||
| if ( fSocket.SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof ( loop ) ) == SOCKET_ERROR ) | |||||
| if ( fSocket.SetLocalLoop() == SOCKET_ERROR ) | |||||
| jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) ); | jack_error ( "Can't disable multicast loop : %s", StrError ( NET_ERROR_CODE ) ); | ||||
| //send 'AVAILABLE' until 'SLAVE_SETUP' received | //send 'AVAILABLE' until 'SLAVE_SETUP' received | ||||
| @@ -130,6 +130,8 @@ namespace Jack | |||||
| class EXPORT JackNetSlaveInterface : public JackNetInterface | class EXPORT JackNetSlaveInterface : public JackNetInterface | ||||
| { | { | ||||
| protected: | protected: | ||||
| static uint fSlaveCounter; | |||||
| bool Init(); | bool Init(); | ||||
| net_status_t GetNetMaster(); | net_status_t GetNetMaster(); | ||||
| net_status_t SendStartToMaster(); | net_status_t SendStartToMaster(); | ||||
| @@ -144,12 +146,18 @@ namespace Jack | |||||
| public: | public: | ||||
| JackNetSlaveInterface() : JackNetInterface() | JackNetSlaveInterface() : JackNetInterface() | ||||
| {} | |||||
| { | |||||
| fSlaveCounter++; | |||||
| } | |||||
| JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port ) | JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port ) | ||||
| {} | |||||
| { | |||||
| fSlaveCounter++; | |||||
| } | |||||
| ~JackNetSlaveInterface() | ~JackNetSlaveInterface() | ||||
| { | { | ||||
| SocketAPIEnd(); | |||||
| //close Socket API with the last slave | |||||
| if ( --fSlaveCounter == 0 ) | |||||
| SocketAPIEnd(); | |||||
| } | } | ||||
| }; | }; | ||||
| } | } | ||||
| @@ -322,6 +322,7 @@ namespace Jack | |||||
| break; | break; | ||||
| case JackTransportNetStarting : | case JackTransportNetStarting : | ||||
| jack_info ( "'%s' is ready to roll..", fParams.fName ); | jack_info ( "'%s' is ready to roll..", fParams.fName ); | ||||
| break; | |||||
| case JackTransportRolling : | case JackTransportRolling : | ||||
| jack_info ( "'%s' is rolling.", fParams.fName ); | jack_info ( "'%s' is rolling.", fParams.fName ); | ||||
| break; | break; | ||||
| @@ -362,7 +363,7 @@ namespace Jack | |||||
| //copy to TxBuffer | //copy to TxBuffer | ||||
| memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) ); | memcpy ( fTxData, &fSendTransportData, sizeof ( net_transport_data_t ) ); | ||||
| } | } | ||||
| //then others | |||||
| //then others (freewheel etc.) | |||||
| //... | //... | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -571,7 +572,7 @@ namespace Jack | |||||
| } | } | ||||
| //bind the socket to the local port | //bind the socket to the local port | ||||
| if ( fSocket.Bind () == SOCKET_ERROR ) | |||||
| if ( fSocket.Bind() == SOCKET_ERROR ) | |||||
| { | { | ||||
| jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) ); | jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) ); | ||||
| fSocket.Close(); | fSocket.Close(); | ||||
| @@ -200,13 +200,6 @@ namespace Jack | |||||
| return SetOption ( IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof ( multicast_req ) ); | return SetOption ( IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof ( multicast_req ) ); | ||||
| } | } | ||||
| void JackNetUnixSocket::CopyParams ( JackNetUnixSocket* socket ) | |||||
| { | |||||
| fPort = socket->fPort; | |||||
| fSendAddr = socket->fSendAddr; | |||||
| fRecvAddr = socket->fRecvAddr; | |||||
| } | |||||
| //options************************************************************************************************************ | //options************************************************************************************************************ | ||||
| int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen ) | int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen ) | ||||
| { | { | ||||
| @@ -227,6 +220,7 @@ namespace Jack | |||||
| if ( ( us < 0 ) || ( us > 10000000 ) ) | if ( ( us < 0 ) || ( us > 10000000 ) ) | ||||
| return SOCKET_ERROR; | return SOCKET_ERROR; | ||||
| struct timeval timeout; | struct timeval timeout; | ||||
| //less than 1sec | //less than 1sec | ||||
| if ( us < 1000000 ) | if ( us < 1000000 ) | ||||
| { | { | ||||
| @@ -76,7 +76,6 @@ namespace Jack | |||||
| //utility | //utility | ||||
| int GetName ( char* name ); | int GetName ( char* name ); | ||||
| int JoinMCastGroup ( const char* mcast_ip ); | int JoinMCastGroup ( const char* mcast_ip ); | ||||
| void CopyParams ( JackNetUnixSocket* socket ); | |||||
| //options management | //options management | ||||
| int SetOption ( int level, int optname, const void* optval, socklen_t optlen ); | int SetOption ( int level, int optname, const void* optval, socklen_t optlen ); | ||||
| @@ -85,7 +84,7 @@ namespace Jack | |||||
| //timeout | //timeout | ||||
| int SetTimeOut ( int us ); | int SetTimeOut ( int us ); | ||||
| //local loop | |||||
| //disable local loop | |||||
| int SetLocalLoop(); | int SetLocalLoop(); | ||||
| //network operations | //network operations | ||||
| @@ -290,8 +290,8 @@ namespace Jack | |||||
| //local loop********************************************************************************************************* | //local loop********************************************************************************************************* | ||||
| int JackNetWinSocket::SetLocalLoop() | int JackNetWinSocket::SetLocalLoop() | ||||
| { | { | ||||
| char enable = 1; | |||||
| return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &enable, sizeof ( enable ) ); | |||||
| char disable = 0; | |||||
| return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); | |||||
| } | } | ||||
| //network operations************************************************************************************************* | //network operations************************************************************************************************* | ||||
| @@ -85,7 +85,7 @@ namespace Jack | |||||
| //timeout | //timeout | ||||
| int SetTimeOut ( int usec ); | int SetTimeOut ( int usec ); | ||||
| //local loop | |||||
| //disable local loop | |||||
| int SetLocalLoop(); | int SetLocalLoop(); | ||||
| //network operations | //network operations | ||||
| @@ -153,7 +153,7 @@ | |||||
| <Unit filename="..\common\JackAudioPort.cpp" /> | <Unit filename="..\common\JackAudioPort.cpp" /> | ||||
| <Unit filename="..\common\JackClient.cpp" /> | <Unit filename="..\common\JackClient.cpp" /> | ||||
| <Unit filename="..\common\JackConnectionManager.cpp" /> | <Unit filename="..\common\JackConnectionManager.cpp" /> | ||||
| <Unit filename="..\common\JackControl.cpp" /> | |||||
| <Unit filename="..\common\JackControlAPI.cpp" /> | |||||
| <Unit filename="..\common\JackDriver.cpp" /> | <Unit filename="..\common\JackDriver.cpp" /> | ||||
| <Unit filename="..\common\JackDriverLoader.cpp" /> | <Unit filename="..\common\JackDriverLoader.cpp" /> | ||||
| <Unit filename="..\common\JackEngine.cpp" /> | <Unit filename="..\common\JackEngine.cpp" /> | ||||