git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2681 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -26,79 +26,79 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| class JackNetDriver : public JackAudioDriver | |||||
| { | |||||
| private: | |||||
| session_params_t fParams; | |||||
| char* fMulticastIP; | |||||
| JackNetSocket fSocket; | |||||
| uint fNSubProcess; | |||||
| jack_port_id_t* fMidiCapturePortList; | |||||
| jack_port_id_t* fMidiPlaybackPortList; | |||||
| packet_header_t fTxHeader; | |||||
| packet_header_t fRxHeader; | |||||
| char* fTxBuffer; | |||||
| char* fRxBuffer; | |||||
| char* fTxData; | |||||
| char* fRxData; | |||||
| NetMidiBuffer* fNetMidiCaptureBuffer; | |||||
| NetMidiBuffer* fNetMidiPlaybackBuffer; | |||||
| NetAudioBuffer* fNetAudioCaptureBuffer; | |||||
| NetAudioBuffer* fNetAudioPlaybackBuffer; | |||||
| int fAudioRxLen; | |||||
| int fAudioTxLen; | |||||
| bool Init(); | |||||
| net_status_t GetNetMaster(); | |||||
| net_status_t SendMasterStartSync(); | |||||
| void Restart(); | |||||
| int SetParams(); | |||||
| int AllocPorts(); | |||||
| int FreePorts(); | |||||
| JackMidiBuffer* GetMidiInputBuffer ( int port_index ); | |||||
| JackMidiBuffer* GetMidiOutputBuffer ( int port_index ); | |||||
| int Recv ( size_t size, int flags ); | |||||
| int Send ( size_t size, int flags ); | |||||
| public: | |||||
| JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, | |||||
| const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, const char* master_name ); | |||||
| ~JackNetDriver(); | |||||
| int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, | |||||
| int inchannels, int outchannels, bool monitor, const char* capture_driver_name, | |||||
| const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); | |||||
| int Attach(); | |||||
| int Detach(); | |||||
| int Read(); | |||||
| int Write(); | |||||
| // BufferSize can be changed | |||||
| bool IsFixedBufferSize() | |||||
| { | |||||
| return true; | |||||
| } | |||||
| int SetBufferSize(jack_nframes_t buffer_size) | |||||
| { | |||||
| return -1; | |||||
| } | |||||
| int SetSampleRate(jack_nframes_t sample_rate) | |||||
| { | |||||
| return -1; | |||||
| } | |||||
| }; | |||||
| class JackNetDriver : public JackAudioDriver | |||||
| { | |||||
| private: | |||||
| session_params_t fParams; | |||||
| char* fMulticastIP; | |||||
| JackNetSocket fSocket; | |||||
| uint fNSubProcess; | |||||
| jack_port_id_t* fMidiCapturePortList; | |||||
| jack_port_id_t* fMidiPlaybackPortList; | |||||
| packet_header_t fTxHeader; | |||||
| packet_header_t fRxHeader; | |||||
| char* fTxBuffer; | |||||
| char* fRxBuffer; | |||||
| char* fTxData; | |||||
| char* fRxData; | |||||
| NetMidiBuffer* fNetMidiCaptureBuffer; | |||||
| NetMidiBuffer* fNetMidiPlaybackBuffer; | |||||
| NetAudioBuffer* fNetAudioCaptureBuffer; | |||||
| NetAudioBuffer* fNetAudioPlaybackBuffer; | |||||
| int fAudioRxLen; | |||||
| int fAudioTxLen; | |||||
| bool Init(); | |||||
| net_status_t GetNetMaster(); | |||||
| net_status_t SendMasterStartSync(); | |||||
| void Restart(); | |||||
| int SetParams(); | |||||
| int AllocPorts(); | |||||
| int FreePorts(); | |||||
| JackMidiBuffer* GetMidiInputBuffer ( int port_index ); | |||||
| JackMidiBuffer* GetMidiOutputBuffer ( int port_index ); | |||||
| int Recv ( size_t size, int flags ); | |||||
| int Send ( size_t size, int flags ); | |||||
| public: | |||||
| JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, | |||||
| const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, const char* master_name ); | |||||
| ~JackNetDriver(); | |||||
| int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, | |||||
| int inchannels, int outchannels, bool monitor, const char* capture_driver_name, | |||||
| const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); | |||||
| int Attach(); | |||||
| int Detach(); | |||||
| int Read(); | |||||
| int Write(); | |||||
| // BufferSize can be changed | |||||
| bool IsFixedBufferSize() | |||||
| { | |||||
| return true; | |||||
| } | |||||
| int SetBufferSize(jack_nframes_t buffer_size) | |||||
| { | |||||
| return -1; | |||||
| } | |||||
| int SetSampleRate(jack_nframes_t sample_rate) | |||||
| { | |||||
| return -1; | |||||
| } | |||||
| }; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -21,95 +21,95 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #define __JACKNETMASTER_H__ | #define __JACKNETMASTER_H__ | ||||
| #include "JackNetTool.h" | #include "JackNetTool.h" | ||||
| #include "thread.h" | |||||
| #include "jack.h" | |||||
| #include "thread.h" | |||||
| #include "jack.h" | |||||
| #include "jslist.h" | #include "jslist.h" | ||||
| #include <list> | #include <list> | ||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| class JackNetMasterManager; | |||||
| class JackNetMaster | |||||
| { | |||||
| friend class JackNetMasterManager; | |||||
| private: | |||||
| static int SetProcess ( jack_nframes_t nframes, void* arg ); | |||||
| JackNetMasterManager* fMasterManager; | |||||
| session_params_t fParams; | |||||
| JackNetSocket fSocket; | |||||
| uint fNSubProcess; | |||||
| int fNetJumpCnt; | |||||
| bool fRunning; | |||||
| jack_client_t* fJackClient; | |||||
| const char* fClientName; | |||||
| jack_port_t** fAudioCapturePorts; | |||||
| jack_port_t** fAudioPlaybackPorts; | |||||
| jack_port_t** fMidiCapturePorts; | |||||
| jack_port_t** fMidiPlaybackPorts; | |||||
| packet_header_t fTxHeader; | |||||
| packet_header_t fRxHeader; | |||||
| char* fTxBuffer; | |||||
| char* fRxBuffer; | |||||
| char* fTxData; | |||||
| char* fRxData; | |||||
| NetAudioBuffer* fNetAudioCaptureBuffer; | |||||
| NetAudioBuffer* fNetAudioPlaybackBuffer; | |||||
| NetMidiBuffer* fNetMidiCaptureBuffer; | |||||
| NetMidiBuffer* fNetMidiPlaybackBuffer; | |||||
| int fAudioTxLen; | |||||
| int fAudioRxLen; | |||||
| bool Init(); | |||||
| void FreePorts(); | |||||
| void Exit(); | |||||
| int Send ( char* buffer, size_t size, int flags ); | |||||
| int Recv ( size_t size, int flags ); | |||||
| int Process(); | |||||
| public: | |||||
| JackNetMaster ( JackNetMasterManager* manager, session_params_t& params ); | |||||
| ~JackNetMaster (); | |||||
| }; | |||||
| typedef std::list<JackNetMaster*> master_list_t; | |||||
| typedef master_list_t::iterator master_list_it_t; | |||||
| class JackNetMasterManager | |||||
| { | |||||
| friend class JackNetMaster; | |||||
| private: | |||||
| static void* NetManagerThread ( void* arg ); | |||||
| static int SetProcess ( jack_nframes_t nframes, void* arg ); | |||||
| jack_client_t* fManagerClient; | |||||
| const char* fManagerName; | |||||
| const char* fMulticastIP; | |||||
| JackNetSocket fSocket; | |||||
| pthread_t fManagerThread; | |||||
| master_list_t fMasterList; | |||||
| uint32_t fGlobalID; | |||||
| bool fRunning; | |||||
| void Run(); | |||||
| JackNetMaster* MasterInit ( session_params_t& params ); | |||||
| master_list_it_t FindMaster ( uint32_t client_id ); | |||||
| void KillMaster ( session_params_t* params ); | |||||
| void SetSlaveName ( session_params_t& params ); | |||||
| int Process(); | |||||
| public: | |||||
| JackNetMasterManager ( jack_client_t* jack_client, const JSList* params ); | |||||
| ~JackNetMasterManager(); | |||||
| void Exit(); | |||||
| }; | |||||
| class JackNetMasterManager; | |||||
| class JackNetMaster | |||||
| { | |||||
| friend class JackNetMasterManager; | |||||
| private: | |||||
| static int SetProcess ( jack_nframes_t nframes, void* arg ); | |||||
| JackNetMasterManager* fMasterManager; | |||||
| session_params_t fParams; | |||||
| JackNetSocket fSocket; | |||||
| uint fNSubProcess; | |||||
| int fNetJumpCnt; | |||||
| bool fRunning; | |||||
| jack_client_t* fJackClient; | |||||
| const char* fClientName; | |||||
| jack_port_t** fAudioCapturePorts; | |||||
| jack_port_t** fAudioPlaybackPorts; | |||||
| jack_port_t** fMidiCapturePorts; | |||||
| jack_port_t** fMidiPlaybackPorts; | |||||
| packet_header_t fTxHeader; | |||||
| packet_header_t fRxHeader; | |||||
| char* fTxBuffer; | |||||
| char* fRxBuffer; | |||||
| char* fTxData; | |||||
| char* fRxData; | |||||
| NetAudioBuffer* fNetAudioCaptureBuffer; | |||||
| NetAudioBuffer* fNetAudioPlaybackBuffer; | |||||
| NetMidiBuffer* fNetMidiCaptureBuffer; | |||||
| NetMidiBuffer* fNetMidiPlaybackBuffer; | |||||
| int fAudioTxLen; | |||||
| int fAudioRxLen; | |||||
| bool Init(); | |||||
| void FreePorts(); | |||||
| void Exit(); | |||||
| int Send ( char* buffer, size_t size, int flags ); | |||||
| int Recv ( size_t size, int flags ); | |||||
| int Process(); | |||||
| public: | |||||
| JackNetMaster ( JackNetMasterManager* manager, session_params_t& params ); | |||||
| ~JackNetMaster (); | |||||
| }; | |||||
| typedef std::list<JackNetMaster*> master_list_t; | |||||
| typedef master_list_t::iterator master_list_it_t; | |||||
| class JackNetMasterManager | |||||
| { | |||||
| friend class JackNetMaster; | |||||
| private: | |||||
| static void* NetManagerThread ( void* arg ); | |||||
| static int SetProcess ( jack_nframes_t nframes, void* arg ); | |||||
| jack_client_t* fManagerClient; | |||||
| const char* fManagerName; | |||||
| const char* fMulticastIP; | |||||
| JackNetSocket fSocket; | |||||
| pthread_t fManagerThread; | |||||
| master_list_t fMasterList; | |||||
| uint32_t fGlobalID; | |||||
| bool fRunning; | |||||
| void Run(); | |||||
| JackNetMaster* MasterInit ( session_params_t& params ); | |||||
| master_list_it_t FindMaster ( uint32_t client_id ); | |||||
| void KillMaster ( session_params_t* params ); | |||||
| void SetSlaveName ( session_params_t& params ); | |||||
| int Process(); | |||||
| public: | |||||
| JackNetMasterManager ( jack_client_t* jack_client, const JSList* params ); | |||||
| ~JackNetMasterManager(); | |||||
| void Exit(); | |||||
| }; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -25,330 +25,330 @@ namespace Jack | |||||
| { | { | ||||
| // NetMidiBuffer********************************************************************************** | // NetMidiBuffer********************************************************************************** | ||||
| NetMidiBuffer::NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||||
| { | |||||
| fNPorts = nports; | |||||
| fMaxBufsize = fNPorts * sizeof ( sample_t ) * params->fPeriodSize ; | |||||
| fMaxPcktSize = params->fMtu - sizeof ( packet_header_t ); | |||||
| fBuffer = new char[fMaxBufsize]; | |||||
| fPortBuffer = new JackMidiBuffer* [fNPorts]; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| fPortBuffer[port_index] = NULL; | |||||
| fNetBuffer = net_buffer; | |||||
| } | |||||
| NetMidiBuffer::~NetMidiBuffer() | |||||
| { | |||||
| delete[] fBuffer; | |||||
| delete[] fPortBuffer; | |||||
| } | |||||
| size_t NetMidiBuffer::GetSize() | |||||
| { | |||||
| return fMaxBufsize; | |||||
| } | |||||
| void NetMidiBuffer::DisplayEvents() | |||||
| { | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| { | |||||
| for ( uint event = 0; event < fPortBuffer[port_index]->event_count; event++ ) | |||||
| if ( fPortBuffer[port_index]->IsValid() ) | |||||
| jack_info ( "port %d : midi event %u/%u -> time : %u, size : %u", | |||||
| port_index + 1, event + 1, fPortBuffer[port_index]->event_count, | |||||
| fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size ); | |||||
| } | |||||
| } | |||||
| int NetMidiBuffer::RenderFromJackPorts() | |||||
| { | |||||
| int pos = 0; | |||||
| size_t copy_size; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| { | |||||
| copy_size = sizeof ( JackMidiBuffer ) + fPortBuffer[port_index]->event_count * sizeof ( JackMidiEvent ); | |||||
| memcpy ( fBuffer + pos, fPortBuffer[port_index], copy_size ); | |||||
| pos += copy_size; | |||||
| memcpy ( fBuffer + pos, fPortBuffer[port_index] + ( fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos ), | |||||
| fPortBuffer[port_index]->write_pos ); | |||||
| pos += fPortBuffer[port_index]->write_pos; | |||||
| } | |||||
| return pos; | |||||
| } | |||||
| int NetMidiBuffer::RenderToJackPorts() | |||||
| { | |||||
| int pos = 0; | |||||
| int copy_size; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| { | |||||
| copy_size = sizeof ( JackMidiBuffer ) + reinterpret_cast<JackMidiBuffer*> ( fBuffer + pos )->event_count * sizeof ( JackMidiEvent ); | |||||
| memcpy ( fPortBuffer[port_index], fBuffer + pos, copy_size ); | |||||
| pos += copy_size; | |||||
| memcpy ( fPortBuffer[port_index] + ( fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos ), | |||||
| fBuffer + pos, fPortBuffer[port_index]->write_pos ); | |||||
| pos += fPortBuffer[port_index]->write_pos; | |||||
| } | |||||
| return pos; | |||||
| } | |||||
| int NetMidiBuffer::RenderFromNetwork ( int subcycle, size_t copy_size ) | |||||
| { | |||||
| memcpy ( fBuffer + subcycle * fMaxPcktSize, fNetBuffer, copy_size ); | |||||
| return copy_size; | |||||
| } | |||||
| int NetMidiBuffer::RenderToNetwork ( int subcycle, size_t total_size ) | |||||
| { | |||||
| int size = total_size - subcycle * fMaxPcktSize; | |||||
| int copy_size = ( size <= fMaxPcktSize ) ? size : fMaxPcktSize; | |||||
| memcpy ( fNetBuffer, fBuffer + subcycle * fMaxPcktSize, copy_size ); | |||||
| return copy_size; | |||||
| } | |||||
| NetMidiBuffer::NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||||
| { | |||||
| fNPorts = nports; | |||||
| fMaxBufsize = fNPorts * sizeof ( sample_t ) * params->fPeriodSize ; | |||||
| fMaxPcktSize = params->fMtu - sizeof ( packet_header_t ); | |||||
| fBuffer = new char[fMaxBufsize]; | |||||
| fPortBuffer = new JackMidiBuffer* [fNPorts]; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| fPortBuffer[port_index] = NULL; | |||||
| fNetBuffer = net_buffer; | |||||
| } | |||||
| NetMidiBuffer::~NetMidiBuffer() | |||||
| { | |||||
| delete[] fBuffer; | |||||
| delete[] fPortBuffer; | |||||
| } | |||||
| size_t NetMidiBuffer::GetSize() | |||||
| { | |||||
| return fMaxBufsize; | |||||
| } | |||||
| void NetMidiBuffer::DisplayEvents() | |||||
| { | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| { | |||||
| for ( uint event = 0; event < fPortBuffer[port_index]->event_count; event++ ) | |||||
| if ( fPortBuffer[port_index]->IsValid() ) | |||||
| jack_info ( "port %d : midi event %u/%u -> time : %u, size : %u", | |||||
| port_index + 1, event + 1, fPortBuffer[port_index]->event_count, | |||||
| fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size ); | |||||
| } | |||||
| } | |||||
| int NetMidiBuffer::RenderFromJackPorts() | |||||
| { | |||||
| int pos = 0; | |||||
| size_t copy_size; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| { | |||||
| copy_size = sizeof ( JackMidiBuffer ) + fPortBuffer[port_index]->event_count * sizeof ( JackMidiEvent ); | |||||
| memcpy ( fBuffer + pos, fPortBuffer[port_index], copy_size ); | |||||
| pos += copy_size; | |||||
| memcpy ( fBuffer + pos, fPortBuffer[port_index] + ( fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos ), | |||||
| fPortBuffer[port_index]->write_pos ); | |||||
| pos += fPortBuffer[port_index]->write_pos; | |||||
| } | |||||
| return pos; | |||||
| } | |||||
| int NetMidiBuffer::RenderToJackPorts() | |||||
| { | |||||
| int pos = 0; | |||||
| int copy_size; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| { | |||||
| copy_size = sizeof ( JackMidiBuffer ) + reinterpret_cast<JackMidiBuffer*> ( fBuffer + pos )->event_count * sizeof ( JackMidiEvent ); | |||||
| memcpy ( fPortBuffer[port_index], fBuffer + pos, copy_size ); | |||||
| pos += copy_size; | |||||
| memcpy ( fPortBuffer[port_index] + ( fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos ), | |||||
| fBuffer + pos, fPortBuffer[port_index]->write_pos ); | |||||
| pos += fPortBuffer[port_index]->write_pos; | |||||
| } | |||||
| return pos; | |||||
| } | |||||
| int NetMidiBuffer::RenderFromNetwork ( int subcycle, size_t copy_size ) | |||||
| { | |||||
| memcpy ( fBuffer + subcycle * fMaxPcktSize, fNetBuffer, copy_size ); | |||||
| return copy_size; | |||||
| } | |||||
| int NetMidiBuffer::RenderToNetwork ( int subcycle, size_t total_size ) | |||||
| { | |||||
| int size = total_size - subcycle * fMaxPcktSize; | |||||
| int copy_size = ( size <= fMaxPcktSize ) ? size : fMaxPcktSize; | |||||
| memcpy ( fNetBuffer, fBuffer + subcycle * fMaxPcktSize, copy_size ); | |||||
| return copy_size; | |||||
| } | |||||
| // net audio buffer ********************************************************************************* | // net audio buffer ********************************************************************************* | ||||
| NetAudioBuffer::NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||||
| { | |||||
| fNPorts = nports; | |||||
| fPeriodSize = params->fPeriodSize; | |||||
| fSubPeriodSize = params->fFramesPerPacket; | |||||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); | |||||
| fPortBuffer = new sample_t* [fNPorts]; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| fPortBuffer[port_index] = NULL; | |||||
| fNetBuffer = net_buffer; | |||||
| } | |||||
| NetAudioBuffer::~NetAudioBuffer() | |||||
| { | |||||
| delete[] fPortBuffer; | |||||
| } | |||||
| size_t NetAudioBuffer::GetSize() | |||||
| { | |||||
| return fNPorts * fSubPeriodBytesSize; | |||||
| } | |||||
| void NetAudioBuffer::RenderFromJackPorts ( int subcycle ) | |||||
| { | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| memcpy ( fNetBuffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); | |||||
| } | |||||
| void NetAudioBuffer::RenderToJackPorts ( int subcycle ) | |||||
| { | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); | |||||
| } | |||||
| NetAudioBuffer::NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||||
| { | |||||
| fNPorts = nports; | |||||
| fPeriodSize = params->fPeriodSize; | |||||
| fSubPeriodSize = params->fFramesPerPacket; | |||||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); | |||||
| fPortBuffer = new sample_t* [fNPorts]; | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| fPortBuffer[port_index] = NULL; | |||||
| fNetBuffer = net_buffer; | |||||
| } | |||||
| NetAudioBuffer::~NetAudioBuffer() | |||||
| { | |||||
| delete[] fPortBuffer; | |||||
| } | |||||
| size_t NetAudioBuffer::GetSize() | |||||
| { | |||||
| return fNPorts * fSubPeriodBytesSize; | |||||
| } | |||||
| void NetAudioBuffer::RenderFromJackPorts ( int subcycle ) | |||||
| { | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| memcpy ( fNetBuffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); | |||||
| } | |||||
| void NetAudioBuffer::RenderToJackPorts ( int subcycle ) | |||||
| { | |||||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||||
| memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); | |||||
| } | |||||
| // SessionParams ************************************************************************************ | // SessionParams ************************************************************************************ | ||||
| EXPORT void SessionParamsHToN ( session_params_t* params ) | |||||
| { | |||||
| params->fPacketID = htonl ( params->fPacketID ); | |||||
| params->fMtu = htonl ( params->fMtu ); | |||||
| params->fID = htonl ( params->fID ); | |||||
| params->fSendAudioChannels = htonl ( params->fSendAudioChannels ); | |||||
| params->fReturnAudioChannels = htonl ( params->fReturnAudioChannels ); | |||||
| params->fSendMidiChannels = htonl ( params->fSendMidiChannels ); | |||||
| params->fReturnMidiChannels = htonl ( params->fReturnMidiChannels ); | |||||
| params->fSampleRate = htonl ( params->fSampleRate ); | |||||
| params->fPeriodSize = htonl ( params->fPeriodSize ); | |||||
| params->fFramesPerPacket = htonl ( params->fFramesPerPacket ); | |||||
| params->fBitdepth = htonl ( params->fBitdepth ); | |||||
| } | |||||
| EXPORT void SessionParamsNToH ( session_params_t* params ) | |||||
| { | |||||
| params->fPacketID = ntohl ( params->fPacketID ); | |||||
| params->fMtu = ntohl ( params->fMtu ); | |||||
| params->fID = ntohl ( params->fID ); | |||||
| params->fSendAudioChannels = ntohl ( params->fSendAudioChannels ); | |||||
| params->fReturnAudioChannels = ntohl ( params->fReturnAudioChannels ); | |||||
| params->fSendMidiChannels = ntohl ( params->fSendMidiChannels ); | |||||
| params->fReturnMidiChannels = ntohl ( params->fReturnMidiChannels ); | |||||
| params->fSampleRate = ntohl ( params->fSampleRate ); | |||||
| params->fPeriodSize = ntohl ( params->fPeriodSize ); | |||||
| params->fFramesPerPacket = ntohl ( params->fFramesPerPacket ); | |||||
| params->fBitdepth = ntohl ( params->fBitdepth ); | |||||
| } | |||||
| EXPORT void SessionParamsDisplay ( session_params_t* params ) | |||||
| { | |||||
| jack_info ( "---->Network parameters of '%s'<----", params->fName ); | |||||
| jack_info ( "Protocol revision : %c", params->fProtocolVersion ); | |||||
| jack_info ( "MTU : %u", params->fMtu ); | |||||
| jack_info ( "Master name : %s", params->fMasterNetName ); | |||||
| jack_info ( "Slave name : %s", params->fSlaveNetName ); | |||||
| jack_info ( "ID : %u", params->fID ); | |||||
| jack_info ( "Send channels (audio - midi) : %d - %d", params->fSendAudioChannels, params->fSendMidiChannels ); | |||||
| jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); | |||||
| jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); | |||||
| jack_info ( "Period size : %u frames per period", params->fPeriodSize ); | |||||
| jack_info ( "Frames per packet : %u", params->fFramesPerPacket ); | |||||
| jack_info ( "Packet per period : %u", params->fPeriodSize / params->fFramesPerPacket ); | |||||
| jack_info ( "Bitdepth (0 for float) : %u", params->fBitdepth ); | |||||
| jack_info ( "Name : %s", params->fName ); | |||||
| jack_info ( "---------------------------------------------" ); | |||||
| } | |||||
| EXPORT sync_packet_type_t GetPacketType ( session_params_t* params ) | |||||
| { | |||||
| switch ( params->fPacketID ) | |||||
| { | |||||
| case 0: | |||||
| return SLAVE_AVAILABLE; | |||||
| case 1: | |||||
| return SLAVE_SETUP; | |||||
| case 2: | |||||
| return START_MASTER; | |||||
| case 3: | |||||
| return START_SLAVE; | |||||
| case 4: | |||||
| return KILL_MASTER; | |||||
| } | |||||
| return INVALID; | |||||
| } | |||||
| EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type ) | |||||
| { | |||||
| switch ( packet_type ) | |||||
| { | |||||
| case INVALID: | |||||
| return -1; | |||||
| case SLAVE_AVAILABLE: | |||||
| params->fPacketID = 0; | |||||
| break; | |||||
| case SLAVE_SETUP: | |||||
| params->fPacketID = 1; | |||||
| break; | |||||
| case START_MASTER: | |||||
| params->fPacketID = 2; | |||||
| break; | |||||
| case START_SLAVE: | |||||
| params->fPacketID = 3; | |||||
| break; | |||||
| case KILL_MASTER: | |||||
| params->fPacketID = 4; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| EXPORT void SessionParamsHToN ( session_params_t* params ) | |||||
| { | |||||
| params->fPacketID = htonl ( params->fPacketID ); | |||||
| params->fMtu = htonl ( params->fMtu ); | |||||
| params->fID = htonl ( params->fID ); | |||||
| params->fSendAudioChannels = htonl ( params->fSendAudioChannels ); | |||||
| params->fReturnAudioChannels = htonl ( params->fReturnAudioChannels ); | |||||
| params->fSendMidiChannels = htonl ( params->fSendMidiChannels ); | |||||
| params->fReturnMidiChannels = htonl ( params->fReturnMidiChannels ); | |||||
| params->fSampleRate = htonl ( params->fSampleRate ); | |||||
| params->fPeriodSize = htonl ( params->fPeriodSize ); | |||||
| params->fFramesPerPacket = htonl ( params->fFramesPerPacket ); | |||||
| params->fBitdepth = htonl ( params->fBitdepth ); | |||||
| } | |||||
| EXPORT void SessionParamsNToH ( session_params_t* params ) | |||||
| { | |||||
| params->fPacketID = ntohl ( params->fPacketID ); | |||||
| params->fMtu = ntohl ( params->fMtu ); | |||||
| params->fID = ntohl ( params->fID ); | |||||
| params->fSendAudioChannels = ntohl ( params->fSendAudioChannels ); | |||||
| params->fReturnAudioChannels = ntohl ( params->fReturnAudioChannels ); | |||||
| params->fSendMidiChannels = ntohl ( params->fSendMidiChannels ); | |||||
| params->fReturnMidiChannels = ntohl ( params->fReturnMidiChannels ); | |||||
| params->fSampleRate = ntohl ( params->fSampleRate ); | |||||
| params->fPeriodSize = ntohl ( params->fPeriodSize ); | |||||
| params->fFramesPerPacket = ntohl ( params->fFramesPerPacket ); | |||||
| params->fBitdepth = ntohl ( params->fBitdepth ); | |||||
| } | |||||
| EXPORT void SessionParamsDisplay ( session_params_t* params ) | |||||
| { | |||||
| jack_info ( "---->Network parameters of '%s'<----", params->fName ); | |||||
| jack_info ( "Protocol revision : %c", params->fProtocolVersion ); | |||||
| jack_info ( "MTU : %u", params->fMtu ); | |||||
| jack_info ( "Master name : %s", params->fMasterNetName ); | |||||
| jack_info ( "Slave name : %s", params->fSlaveNetName ); | |||||
| jack_info ( "ID : %u", params->fID ); | |||||
| jack_info ( "Send channels (audio - midi) : %d - %d", params->fSendAudioChannels, params->fSendMidiChannels ); | |||||
| jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); | |||||
| jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); | |||||
| jack_info ( "Period size : %u frames per period", params->fPeriodSize ); | |||||
| jack_info ( "Frames per packet : %u", params->fFramesPerPacket ); | |||||
| jack_info ( "Packet per period : %u", params->fPeriodSize / params->fFramesPerPacket ); | |||||
| jack_info ( "Bitdepth (0 for float) : %u", params->fBitdepth ); | |||||
| jack_info ( "Name : %s", params->fName ); | |||||
| jack_info ( "---------------------------------------------" ); | |||||
| } | |||||
| EXPORT sync_packet_type_t GetPacketType ( session_params_t* params ) | |||||
| { | |||||
| switch ( params->fPacketID ) | |||||
| { | |||||
| case 0: | |||||
| return SLAVE_AVAILABLE; | |||||
| case 1: | |||||
| return SLAVE_SETUP; | |||||
| case 2: | |||||
| return START_MASTER; | |||||
| case 3: | |||||
| return START_SLAVE; | |||||
| case 4: | |||||
| return KILL_MASTER; | |||||
| } | |||||
| return INVALID; | |||||
| } | |||||
| EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type ) | |||||
| { | |||||
| switch ( packet_type ) | |||||
| { | |||||
| case INVALID: | |||||
| return -1; | |||||
| case SLAVE_AVAILABLE: | |||||
| params->fPacketID = 0; | |||||
| break; | |||||
| case SLAVE_SETUP: | |||||
| params->fPacketID = 1; | |||||
| break; | |||||
| case START_MASTER: | |||||
| params->fPacketID = 2; | |||||
| break; | |||||
| case START_SLAVE: | |||||
| params->fPacketID = 3; | |||||
| break; | |||||
| case KILL_MASTER: | |||||
| params->fPacketID = 4; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| // Packet header ********************************************************************************** | // Packet header ********************************************************************************** | ||||
| EXPORT void PacketHeaderHToN ( packet_header_t* header ) | |||||
| { | |||||
| header->fID = htonl ( header->fID ); | |||||
| header->fMidiDataSize = htonl ( header->fMidiDataSize ); | |||||
| header->fBitdepth = htonl ( header->fBitdepth ); | |||||
| header->fNMidiPckt = htonl ( header->fNMidiPckt ); | |||||
| header->fCycle = ntohl ( header->fCycle ); | |||||
| header->fSubCycle = htonl ( header->fSubCycle ); | |||||
| } | |||||
| EXPORT void PacketHeaderNToH ( packet_header_t* header ) | |||||
| { | |||||
| header->fID = ntohl ( header->fID ); | |||||
| header->fMidiDataSize = ntohl ( header->fMidiDataSize ); | |||||
| header->fBitdepth = ntohl ( header->fBitdepth ); | |||||
| header->fNMidiPckt = ntohl ( header->fNMidiPckt ); | |||||
| header->fCycle = ntohl ( header->fCycle ); | |||||
| header->fSubCycle = ntohl ( header->fSubCycle ); | |||||
| } | |||||
| EXPORT void PacketHeaderDisplay ( packet_header_t* header ) | |||||
| { | |||||
| jack_info ( "********************Header********************" ); | |||||
| jack_info ( "Data type : %c", header->fDataType ); | |||||
| jack_info ( "Data stream : %c", header->fDataStream ); | |||||
| jack_info ( "ID : %u", header->fID ); | |||||
| jack_info ( "Cycle : %u", header->fCycle ); | |||||
| jack_info ( "SubCycle : %u", header->fSubCycle ); | |||||
| jack_info ( "Midi packets : %u", header->fNMidiPckt ); | |||||
| jack_info ( "Midi data size : %u", header->fMidiDataSize ); | |||||
| jack_info ( "Last packet : '%c'", header->fIsLastPckt ); | |||||
| jack_info ( "Bitdepth : %u (0 for float)", header->fBitdepth ); | |||||
| jack_info ( "**********************************************" ); | |||||
| } | |||||
| EXPORT void PacketHeaderHToN ( packet_header_t* header ) | |||||
| { | |||||
| header->fID = htonl ( header->fID ); | |||||
| header->fMidiDataSize = htonl ( header->fMidiDataSize ); | |||||
| header->fBitdepth = htonl ( header->fBitdepth ); | |||||
| header->fNMidiPckt = htonl ( header->fNMidiPckt ); | |||||
| header->fCycle = ntohl ( header->fCycle ); | |||||
| header->fSubCycle = htonl ( header->fSubCycle ); | |||||
| } | |||||
| EXPORT void PacketHeaderNToH ( packet_header_t* header ) | |||||
| { | |||||
| header->fID = ntohl ( header->fID ); | |||||
| header->fMidiDataSize = ntohl ( header->fMidiDataSize ); | |||||
| header->fBitdepth = ntohl ( header->fBitdepth ); | |||||
| header->fNMidiPckt = ntohl ( header->fNMidiPckt ); | |||||
| header->fCycle = ntohl ( header->fCycle ); | |||||
| header->fSubCycle = ntohl ( header->fSubCycle ); | |||||
| } | |||||
| EXPORT void PacketHeaderDisplay ( packet_header_t* header ) | |||||
| { | |||||
| jack_info ( "********************Header********************" ); | |||||
| jack_info ( "Data type : %c", header->fDataType ); | |||||
| jack_info ( "Data stream : %c", header->fDataStream ); | |||||
| jack_info ( "ID : %u", header->fID ); | |||||
| jack_info ( "Cycle : %u", header->fCycle ); | |||||
| jack_info ( "SubCycle : %u", header->fSubCycle ); | |||||
| jack_info ( "Midi packets : %u", header->fNMidiPckt ); | |||||
| jack_info ( "Midi data size : %u", header->fMidiDataSize ); | |||||
| jack_info ( "Last packet : '%c'", header->fIsLastPckt ); | |||||
| jack_info ( "Bitdepth : %u (0 for float)", header->fBitdepth ); | |||||
| jack_info ( "**********************************************" ); | |||||
| } | |||||
| // Utility ******************************************************************************************************* | // Utility ******************************************************************************************************* | ||||
| EXPORT int SocketAPIInit() | |||||
| { | |||||
| #ifdef WIN32 | |||||
| WORD wVersionRequested = MAKEWORD ( 2, 2 ); | |||||
| WSADATA wsaData; | |||||
| if ( WSAStartup(wVersionRequested, &wsaData) != 0 ) | |||||
| { | |||||
| jack_error ( "WSAStartup error : %s", strerror ( NET_ERROR_CODE ) ); | |||||
| return -1; | |||||
| } | |||||
| if ( LOBYTE ( wsaData.wVersion ) != 2 || HIBYTE ( wsaData.wVersion ) != 2 ) | |||||
| { | |||||
| jack_error ( "Could not find a useable version of Winsock.dll\n" ); | |||||
| WSACleanup(); | |||||
| return -1; | |||||
| } | |||||
| #endif | |||||
| return 0; | |||||
| } | |||||
| EXPORT int SocketAPIEnd() | |||||
| { | |||||
| #ifdef WIN32 | |||||
| return WSACleanup(); | |||||
| #endif | |||||
| return 0; | |||||
| } | |||||
| EXPORT jack_nframes_t SetFramesPerPacket ( session_params_t* params ) | |||||
| { | |||||
| if ( !params->fSendAudioChannels && !params->fReturnAudioChannels ) | |||||
| return ( params->fFramesPerPacket = params->fPeriodSize ); | |||||
| size_t period = ( int ) powf ( 2.f, ( int ) ( log ( ( params->fMtu - sizeof ( packet_header_t ) ) | |||||
| / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2 ) ) ); | |||||
| ( period > params->fPeriodSize ) ? params->fFramesPerPacket = params->fPeriodSize : params->fFramesPerPacket = period; | |||||
| return params->fFramesPerPacket; | |||||
| } | |||||
| EXPORT int GetNMidiPckt ( session_params_t* params, size_t data_size ) | |||||
| { | |||||
| //even if there is no midi data, jack need an empty buffer to know there is no event to read | |||||
| //99% of the cases : all data in one packet | |||||
| if ( data_size <= ( params->fMtu - sizeof ( packet_header_t ) ) ) | |||||
| return 1; | |||||
| //else, get the number of needed packets (simply slice the biiig buffer) | |||||
| int npckt = data_size / ( params->fMtu - sizeof ( packet_header_t ) ); | |||||
| if ( data_size % ( params->fMtu - sizeof ( packet_header_t ) ) ) | |||||
| return ++npckt; | |||||
| return npckt; | |||||
| } | |||||
| EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params ) | |||||
| { | |||||
| //time in ms : 1,25 * 'one packet time' | |||||
| float time = 1250 * ( static_cast<float> ( params->fFramesPerPacket ) / static_cast<float> ( params->fSampleRate ) ); | |||||
| int ms = ( int ) time; | |||||
| return ( socket->SetTimeOut ( ms ) == SOCKET_ERROR ) ? SOCKET_ERROR : ms; | |||||
| } | |||||
| EXPORT int SocketAPIInit() | |||||
| { | |||||
| #ifdef WIN32 | |||||
| WORD wVersionRequested = MAKEWORD ( 2, 2 ); | |||||
| WSADATA wsaData; | |||||
| if ( WSAStartup(wVersionRequested, &wsaData) != 0 ) | |||||
| { | |||||
| jack_error ( "WSAStartup error : %s", strerror ( NET_ERROR_CODE ) ); | |||||
| return -1; | |||||
| } | |||||
| if ( LOBYTE ( wsaData.wVersion ) != 2 || HIBYTE ( wsaData.wVersion ) != 2 ) | |||||
| { | |||||
| jack_error ( "Could not find a useable version of Winsock.dll\n" ); | |||||
| WSACleanup(); | |||||
| return -1; | |||||
| } | |||||
| #endif | |||||
| return 0; | |||||
| } | |||||
| EXPORT int SocketAPIEnd() | |||||
| { | |||||
| #ifdef WIN32 | |||||
| return WSACleanup(); | |||||
| #endif | |||||
| return 0; | |||||
| } | |||||
| EXPORT jack_nframes_t SetFramesPerPacket ( session_params_t* params ) | |||||
| { | |||||
| if ( !params->fSendAudioChannels && !params->fReturnAudioChannels ) | |||||
| return ( params->fFramesPerPacket = params->fPeriodSize ); | |||||
| size_t period = ( int ) powf ( 2.f, ( int ) ( log ( ( params->fMtu - sizeof ( packet_header_t ) ) | |||||
| / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2 ) ) ); | |||||
| ( period > params->fPeriodSize ) ? params->fFramesPerPacket = params->fPeriodSize : params->fFramesPerPacket = period; | |||||
| return params->fFramesPerPacket; | |||||
| } | |||||
| EXPORT int GetNMidiPckt ( session_params_t* params, size_t data_size ) | |||||
| { | |||||
| //even if there is no midi data, jack need an empty buffer to know there is no event to read | |||||
| //99% of the cases : all data in one packet | |||||
| if ( data_size <= ( params->fMtu - sizeof ( packet_header_t ) ) ) | |||||
| return 1; | |||||
| //else, get the number of needed packets (simply slice the biiig buffer) | |||||
| int npckt = data_size / ( params->fMtu - sizeof ( packet_header_t ) ); | |||||
| if ( data_size % ( params->fMtu - sizeof ( packet_header_t ) ) ) | |||||
| return ++npckt; | |||||
| return npckt; | |||||
| } | |||||
| EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params ) | |||||
| { | |||||
| //time in ms : 1,25 * 'one packet time' | |||||
| float time = 1250 * ( static_cast<float> ( params->fFramesPerPacket ) / static_cast<float> ( params->fSampleRate ) ); | |||||
| int ms = ( int ) time; | |||||
| return ( socket->SetTimeOut ( ms ) == SOCKET_ERROR ) ? SOCKET_ERROR : ms; | |||||
| } | |||||
| // Packet ******************************************************************************************************* | // Packet ******************************************************************************************************* | ||||
| EXPORT bool IsNextPacket ( packet_header_t* previous, packet_header_t* next, uint subcycles ) | |||||
| { | |||||
| //ignore first cycle | |||||
| if ( previous->fCycle <= 1 ) | |||||
| return true; | |||||
| //same PcktID (cycle), next SubPcktID (subcycle) | |||||
| if ( ( previous->fSubCycle < ( subcycles - 1 ) ) && ( next->fCycle == previous->fCycle ) && ( next->fSubCycle == ( previous->fSubCycle + 1 ) ) ) | |||||
| return true; | |||||
| //next PcktID (cycle), SubPcktID reset to 1 (first subcyle) | |||||
| if ( ( next->fCycle == ( previous->fCycle + 1 ) ) && ( previous->fSubCycle == ( subcycles - 1 ) ) && ( next->fSubCycle == 0 ) ) | |||||
| return true; | |||||
| //else, next is'nt next, return false | |||||
| return false; | |||||
| } | |||||
| EXPORT bool IsNextPacket ( packet_header_t* previous, packet_header_t* next, uint subcycles ) | |||||
| { | |||||
| //ignore first cycle | |||||
| if ( previous->fCycle <= 1 ) | |||||
| return true; | |||||
| //same PcktID (cycle), next SubPcktID (subcycle) | |||||
| if ( ( previous->fSubCycle < ( subcycles - 1 ) ) && ( next->fCycle == previous->fCycle ) && ( next->fSubCycle == ( previous->fSubCycle + 1 ) ) ) | |||||
| return true; | |||||
| //next PcktID (cycle), SubPcktID reset to 1 (first subcyle) | |||||
| if ( ( next->fCycle == ( previous->fCycle + 1 ) ) && ( previous->fSubCycle == ( subcycles - 1 ) ) && ( next->fSubCycle == 0 ) ) | |||||
| return true; | |||||
| //else, next is'nt next, return false | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| @@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackConstants.h" | #include "JackConstants.h" | ||||
| #include "JackMidiPort.h" | #include "JackMidiPort.h" | ||||
| #include "JackExports.h" | #include "JackExports.h" | ||||
| #include "JackError.h" | |||||
| #include "JackError.h" | |||||
| #include "JackTools.h" | #include "JackTools.h" | ||||
| #include "JackPlatformNetSocket.h" | #include "JackPlatformNetSocket.h" | ||||
| @@ -31,157 +31,157 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| typedef struct _session_params session_params_t; | |||||
| typedef struct _packet_header packet_header_t; | |||||
| typedef struct sockaddr socket_address_t; | |||||
| typedef struct in_addr address_t; | |||||
| typedef jack_default_audio_sample_t sample_t; | |||||
| typedef struct _session_params session_params_t; | |||||
| typedef struct _packet_header packet_header_t; | |||||
| typedef struct sockaddr socket_address_t; | |||||
| typedef struct in_addr address_t; | |||||
| typedef jack_default_audio_sample_t sample_t; | |||||
| //session params ****************************************************************************** | //session params ****************************************************************************** | ||||
| struct _session_params | |||||
| { | |||||
| char fPacketType[7]; //packet type ('param') | |||||
| char fProtocolVersion; //version | |||||
| uint32_t fPacketID; //indicates the packet type | |||||
| char fMasterNetName[256]; //master hostname (network) | |||||
| char fSlaveNetName[256]; //slave hostname (network) | |||||
| uint32_t fMtu; //connection mtu | |||||
| uint32_t fID; //slave's ID | |||||
| uint32_t fSendAudioChannels; //number of master->slave channels | |||||
| uint32_t fReturnAudioChannels; //number of slave->master channels | |||||
| uint32_t fSendMidiChannels; //number of master->slave midi channels | |||||
| uint32_t fReturnMidiChannels; //number of slave->master midi channels | |||||
| uint32_t fSampleRate; //session sample rate | |||||
| uint32_t fPeriodSize; //period size | |||||
| uint32_t fFramesPerPacket; //complete frames per packet | |||||
| uint32_t fBitdepth; //samples bitdepth (unused) | |||||
| char fName[JACK_CLIENT_NAME_SIZE]; //slave's name | |||||
| }; | |||||
| struct _session_params | |||||
| { | |||||
| char fPacketType[7]; //packet type ('param') | |||||
| char fProtocolVersion; //version | |||||
| uint32_t fPacketID; //indicates the packet type | |||||
| char fMasterNetName[256]; //master hostname (network) | |||||
| char fSlaveNetName[256]; //slave hostname (network) | |||||
| uint32_t fMtu; //connection mtu | |||||
| uint32_t fID; //slave's ID | |||||
| uint32_t fSendAudioChannels; //number of master->slave channels | |||||
| uint32_t fReturnAudioChannels; //number of slave->master channels | |||||
| uint32_t fSendMidiChannels; //number of master->slave midi channels | |||||
| uint32_t fReturnMidiChannels; //number of slave->master midi channels | |||||
| uint32_t fSampleRate; //session sample rate | |||||
| uint32_t fPeriodSize; //period size | |||||
| uint32_t fFramesPerPacket; //complete frames per packet | |||||
| uint32_t fBitdepth; //samples bitdepth (unused) | |||||
| char fName[JACK_CLIENT_NAME_SIZE]; //slave's name | |||||
| }; | |||||
| //net status ********************************************************************************** | //net status ********************************************************************************** | ||||
| enum _net_status | |||||
| { | |||||
| NET_SOCKET_ERROR = 0, | |||||
| NET_CONNECT_ERROR, | |||||
| NET_ERROR, | |||||
| NET_SEND_ERROR, | |||||
| NET_RECV_ERROR, | |||||
| NET_CONNECTED, | |||||
| NET_ROLLING | |||||
| }; | |||||
| enum _net_status | |||||
| { | |||||
| NET_SOCKET_ERROR = 0, | |||||
| NET_CONNECT_ERROR, | |||||
| NET_ERROR, | |||||
| NET_SEND_ERROR, | |||||
| NET_RECV_ERROR, | |||||
| NET_CONNECTED, | |||||
| NET_ROLLING | |||||
| }; | |||||
| typedef enum _net_status net_status_t; | |||||
| typedef enum _net_status net_status_t; | |||||
| //sync packet type **************************************************************************** | //sync packet type **************************************************************************** | ||||
| enum _sync_packet_type | |||||
| { | |||||
| INVALID = 0, //... | |||||
| SLAVE_AVAILABLE, //a slave is available | |||||
| SLAVE_SETUP, //slave configuration | |||||
| START_MASTER, //slave is ready, start master | |||||
| START_SLAVE, //master is ready, activate slave | |||||
| KILL_MASTER //master must stop | |||||
| }; | |||||
| enum _sync_packet_type | |||||
| { | |||||
| INVALID = 0, //... | |||||
| SLAVE_AVAILABLE, //a slave is available | |||||
| SLAVE_SETUP, //slave configuration | |||||
| START_MASTER, //slave is ready, start master | |||||
| START_SLAVE, //master is ready, activate slave | |||||
| KILL_MASTER //master must stop | |||||
| }; | |||||
| typedef enum _sync_packet_type sync_packet_type_t; | |||||
| typedef enum _sync_packet_type sync_packet_type_t; | |||||
| //packet header ******************************************************************************* | //packet header ******************************************************************************* | ||||
| struct _packet_header | |||||
| { | |||||
| char fPacketType[7]; //packet type ( 'headr' ) | |||||
| char fDataType; //a for audio, m for midi | |||||
| char fDataStream; //s for send, r for return | |||||
| uint32_t fID; //to identify the slave | |||||
| uint32_t fBitdepth; //bitdepth of the data samples | |||||
| uint32_t fMidiDataSize; //size of midi data (if packet is 'midi typed') in bytes | |||||
| uint32_t fNMidiPckt; //number of midi packets of the cycle | |||||
| uint32_t fCycle; //process cycle counter | |||||
| uint32_t fSubCycle; //midi/audio subcycle counter | |||||
| char fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') | |||||
| char fFree[13]; //unused | |||||
| }; | |||||
| struct _packet_header | |||||
| { | |||||
| char fPacketType[7]; //packet type ( 'headr' ) | |||||
| char fDataType; //a for audio, m for midi | |||||
| char fDataStream; //s for send, r for return | |||||
| uint32_t fID; //to identify the slave | |||||
| uint32_t fBitdepth; //bitdepth of the data samples | |||||
| uint32_t fMidiDataSize; //size of midi data (if packet is 'midi typed') in bytes | |||||
| uint32_t fNMidiPckt; //number of midi packets of the cycle | |||||
| uint32_t fCycle; //process cycle counter | |||||
| uint32_t fSubCycle; //midi/audio subcycle counter | |||||
| char fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') | |||||
| char fFree[13]; //unused | |||||
| }; | |||||
| //midi data *********************************************************************************** | //midi data *********************************************************************************** | ||||
| class EXPORT NetMidiBuffer | |||||
| { | |||||
| private: | |||||
| int fNPorts; | |||||
| size_t fMaxBufsize; | |||||
| int fMaxPcktSize; | |||||
| //data | |||||
| char* fBuffer; | |||||
| char* fNetBuffer; | |||||
| public: | |||||
| NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||||
| ~NetMidiBuffer(); | |||||
| JackMidiBuffer** fPortBuffer; | |||||
| void Reset(); | |||||
| size_t GetSize(); | |||||
| //utility | |||||
| void DisplayEvents(); | |||||
| //jack<->buffer | |||||
| int RenderFromJackPorts(); | |||||
| int RenderToJackPorts(); | |||||
| //network<->buffer | |||||
| int RenderFromNetwork ( int subcycle, size_t copy_size ); | |||||
| int RenderToNetwork ( int subcycle, size_t total_size ); | |||||
| }; | |||||
| class EXPORT NetMidiBuffer | |||||
| { | |||||
| private: | |||||
| int fNPorts; | |||||
| size_t fMaxBufsize; | |||||
| int fMaxPcktSize; | |||||
| //data | |||||
| char* fBuffer; | |||||
| char* fNetBuffer; | |||||
| public: | |||||
| NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||||
| ~NetMidiBuffer(); | |||||
| JackMidiBuffer** fPortBuffer; | |||||
| void Reset(); | |||||
| size_t GetSize(); | |||||
| //utility | |||||
| void DisplayEvents(); | |||||
| //jack<->buffer | |||||
| int RenderFromJackPorts(); | |||||
| int RenderToJackPorts(); | |||||
| //network<->buffer | |||||
| int RenderFromNetwork ( int subcycle, size_t copy_size ); | |||||
| int RenderToNetwork ( int subcycle, size_t total_size ); | |||||
| }; | |||||
| // audio data ********************************************************************************* | // audio data ********************************************************************************* | ||||
| class EXPORT NetAudioBuffer | |||||
| { | |||||
| private: | |||||
| int fNPorts; | |||||
| jack_nframes_t fPeriodSize; | |||||
| jack_nframes_t fSubPeriodSize; | |||||
| size_t fSubPeriodBytesSize; | |||||
| char* fNetBuffer; | |||||
| public: | |||||
| NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||||
| ~NetAudioBuffer(); | |||||
| sample_t** fPortBuffer; | |||||
| size_t GetSize(); | |||||
| //jack<->buffer | |||||
| void RenderFromJackPorts ( int subcycle ); | |||||
| void RenderToJackPorts ( int subcycle ); | |||||
| }; | |||||
| class EXPORT NetAudioBuffer | |||||
| { | |||||
| private: | |||||
| int fNPorts; | |||||
| jack_nframes_t fPeriodSize; | |||||
| jack_nframes_t fSubPeriodSize; | |||||
| size_t fSubPeriodBytesSize; | |||||
| char* fNetBuffer; | |||||
| public: | |||||
| NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||||
| ~NetAudioBuffer(); | |||||
| sample_t** fPortBuffer; | |||||
| size_t GetSize(); | |||||
| //jack<->buffer | |||||
| void RenderFromJackPorts ( int subcycle ); | |||||
| void RenderToJackPorts ( int subcycle ); | |||||
| }; | |||||
| //utility ************************************************************************************* | //utility ************************************************************************************* | ||||
| //socket API management | |||||
| EXPORT int SocketAPIInit(); | |||||
| EXPORT int SocketAPIEnd(); | |||||
| //n<-->h functions | |||||
| EXPORT void SessionParamsHToN ( session_params_t* params ); | |||||
| EXPORT void SessionParamsNToH ( session_params_t* params ); | |||||
| EXPORT void PacketHeaderHToN ( packet_header_t* header ); | |||||
| EXPORT void PacketHeaderNToH ( packet_header_t* header ); | |||||
| //display session parameters | |||||
| EXPORT void SessionParamsDisplay ( session_params_t* params ); | |||||
| //display packet header | |||||
| EXPORT void PacketHeaderDisplay ( packet_header_t* header ); | |||||
| //get the packet type from a sesion parameters | |||||
| EXPORT sync_packet_type_t GetPacketType ( session_params_t* params ); | |||||
| //set the packet type in a session parameters | |||||
| EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type ); | |||||
| //step of network initialization | |||||
| EXPORT jack_nframes_t SetFramesPerPacket ( session_params_t* params ); | |||||
| //get the midi packet number for a given cycle | |||||
| EXPORT int GetNMidiPckt ( session_params_t* params, size_t data_size ); | |||||
| //set the recv timeout on a socket | |||||
| EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params ); | |||||
| //check if 'next' packet is really the next after 'previous' | |||||
| EXPORT bool IsNextPacket ( packet_header_t* previous, packet_header_t* next, uint subcycles ); | |||||
| //socket API management | |||||
| EXPORT int SocketAPIInit(); | |||||
| EXPORT int SocketAPIEnd(); | |||||
| //n<-->h functions | |||||
| EXPORT void SessionParamsHToN ( session_params_t* params ); | |||||
| EXPORT void SessionParamsNToH ( session_params_t* params ); | |||||
| EXPORT void PacketHeaderHToN ( packet_header_t* header ); | |||||
| EXPORT void PacketHeaderNToH ( packet_header_t* header ); | |||||
| //display session parameters | |||||
| EXPORT void SessionParamsDisplay ( session_params_t* params ); | |||||
| //display packet header | |||||
| EXPORT void PacketHeaderDisplay ( packet_header_t* header ); | |||||
| //get the packet type from a sesion parameters | |||||
| EXPORT sync_packet_type_t GetPacketType ( session_params_t* params ); | |||||
| //set the packet type in a session parameters | |||||
| EXPORT int SetPacketType ( session_params_t* params, sync_packet_type_t packet_type ); | |||||
| //step of network initialization | |||||
| EXPORT jack_nframes_t SetFramesPerPacket ( session_params_t* params ); | |||||
| //get the midi packet number for a given cycle | |||||
| EXPORT int GetNMidiPckt ( session_params_t* params, size_t data_size ); | |||||
| //set the recv timeout on a socket | |||||
| EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params ); | |||||
| //check if 'next' packet is really the next after 'previous' | |||||
| EXPORT bool IsNextPacket ( packet_header_t* previous, packet_header_t* next, uint subcycles ); | |||||
| } | } | ||||
| @@ -20,270 +20,270 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackNetUnixSocket.h" | #include "JackNetUnixSocket.h" | ||||
| namespace Jack | namespace Jack | ||||
| { | |||||
| //utility ********************************************************************************************************* | |||||
| int GetHostName ( char * name, int size ) | |||||
| { | |||||
| if ( gethostname ( name, size) == SOCKET_ERROR ) | |||||
| { | |||||
| jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) ); | |||||
| strcpy ( name, "default" ); | |||||
| return -1; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| //construct/destruct*********************************************************************************************** | |||||
| JackNetUnixSocket::JackNetUnixSocket() | |||||
| { | |||||
| fSockfd = 0; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetUnixSocket::JackNetUnixSocket ( const char* ip, int port ) | |||||
| { | |||||
| fSockfd = 0; | |||||
| fPort = port; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetUnixSocket::~JackNetUnixSocket() | |||||
| { | |||||
| Close(); | |||||
| } | |||||
| //socket*********************************************************************************************************** | |||||
| int JackNetUnixSocket::NewSocket() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| { | |||||
| Close(); | |||||
| Reset(); | |||||
| } | |||||
| fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); | |||||
| return fSockfd; | |||||
| } | |||||
| int JackNetUnixSocket::Bind() | |||||
| { | |||||
| return bind ( fSockfd, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), sizeof ( socket_address_t ) ); | |||||
| } | |||||
| int JackNetUnixSocket::BindWith ( const char* ip ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fRecvAddr.sin_addr ); | |||||
| if ( addr_conv < 0 ) | |||||
| return addr_conv; | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetUnixSocket::BindWith ( int port ) | |||||
| { | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetUnixSocket::Connect() | |||||
| { | |||||
| return connect ( fSockfd, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); | |||||
| } | |||||
| int JackNetUnixSocket::ConnectTo ( const char* ip ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| if ( addr_conv < 0 ) | |||||
| return addr_conv; | |||||
| return Connect(); | |||||
| } | |||||
| void JackNetUnixSocket::Close() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| close ( fSockfd ); | |||||
| fSockfd = 0; | |||||
| } | |||||
| void JackNetUnixSocket::Reset() | |||||
| { | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( fPort ); | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( fPort ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| bool JackNetUnixSocket::IsSocket() | |||||
| { | |||||
| return ( fSockfd ) ? true : false; | |||||
| } | |||||
| //IP/PORT*********************************************************************************************************** | |||||
| void JackNetUnixSocket::SetPort ( int port ) | |||||
| { | |||||
| fPort = port; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| } | |||||
| int JackNetUnixSocket::GetPort() | |||||
| { | |||||
| return fPort; | |||||
| } | |||||
| //address*********************************************************************************************************** | |||||
| int JackNetUnixSocket::SetAddress ( const char* ip, int port ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| if ( addr_conv < 0 ) | |||||
| return addr_conv; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| return 0; | |||||
| } | |||||
| char* JackNetUnixSocket::GetSendIP() | |||||
| { | |||||
| return inet_ntoa ( fSendAddr.sin_addr ); | |||||
| } | |||||
| char* JackNetUnixSocket::GetRecvIP() | |||||
| { | |||||
| return inet_ntoa ( fRecvAddr.sin_addr ); | |||||
| } | |||||
| //utility************************************************************************************************************ | |||||
| int JackNetUnixSocket::GetName ( char* name ) | |||||
| { | |||||
| return gethostname ( name, 255 ); | |||||
| } | |||||
| int JackNetUnixSocket::JoinMCastGroup ( const char* ip ) | |||||
| { | |||||
| struct ip_mreq multicast_req; | |||||
| inet_aton ( ip, &multicast_req.imr_multiaddr ); | |||||
| multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY ); | |||||
| 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************************************************************************************************************ | |||||
| int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen ) | |||||
| { | |||||
| return setsockopt ( fSockfd, level, optname, optval, optlen ); | |||||
| } | |||||
| int JackNetUnixSocket::GetOption ( int level, int optname, void* optval, socklen_t* optlen ) | |||||
| { | |||||
| return getsockopt ( fSockfd, level, optname, optval, optlen ); | |||||
| } | |||||
| //timeout************************************************************************************************************* | |||||
| int JackNetUnixSocket::SetTimeOut ( int& msec ) | |||||
| { | |||||
| //negative timeout, or exceeding 10s, return | |||||
| if ( ( msec < 0 ) || ( msec > 10000 ) ) | |||||
| return -1; | |||||
| struct timeval timeout; | |||||
| //less than 1sec | |||||
| if ( msec < 1000 ) | |||||
| { | |||||
| timeout.tv_sec = 0; | |||||
| timeout.tv_usec = msec * 1000; | |||||
| return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) ); | |||||
| } | |||||
| //more than 1sec | |||||
| if ( msec >= 1000 ) | |||||
| { | |||||
| float sec = static_cast<float>( msec ) / 1000.0f; | |||||
| timeout.tv_sec = ( int ) sec; | |||||
| float usec = ( sec - timeout.tv_sec ) * 1000000; | |||||
| timeout.tv_usec = ( int ) usec; | |||||
| return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) ); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| //local loop********************************************************************************************************** | |||||
| int JackNetUnixSocket::SetLocalLoop() | |||||
| { | |||||
| char disable = 0; | |||||
| return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); | |||||
| } | |||||
| //network operations************************************************************************************************** | |||||
| int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); | |||||
| } | |||||
| int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| if ( addr_conv < 1 ) | |||||
| return addr_conv; | |||||
| return SendTo ( buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return send ( fSockfd, buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| socklen_t addr_len = sizeof ( socket_address_t ); | |||||
| return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len ); | |||||
| } | |||||
| int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return recv ( fSockfd, buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| socklen_t addr_len = sizeof ( socket_address_t ); | |||||
| return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len ); | |||||
| } | |||||
| net_error_t JackNetUnixSocket::GetError() | |||||
| { | |||||
| switch ( errno ) | |||||
| { | |||||
| case EAGAIN: | |||||
| return NET_NO_DATA; | |||||
| case ECONNABORTED: | |||||
| return NET_CONN_ERROR; | |||||
| case ECONNREFUSED: | |||||
| return NET_CONN_ERROR; | |||||
| case ECONNRESET: | |||||
| return NET_CONN_ERROR; | |||||
| case EHOSTDOWN: | |||||
| return NET_CONN_ERROR; | |||||
| case EHOSTUNREACH: | |||||
| return NET_CONN_ERROR; | |||||
| default: | |||||
| return NET_OP_ERROR; | |||||
| } | |||||
| } | |||||
| { | |||||
| //utility ********************************************************************************************************* | |||||
| int GetHostName ( char * name, int size ) | |||||
| { | |||||
| if ( gethostname ( name, size) == SOCKET_ERROR ) | |||||
| { | |||||
| jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) ); | |||||
| strcpy ( name, "default" ); | |||||
| return -1; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| //construct/destruct*********************************************************************************************** | |||||
| JackNetUnixSocket::JackNetUnixSocket() | |||||
| { | |||||
| fSockfd = 0; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetUnixSocket::JackNetUnixSocket ( const char* ip, int port ) | |||||
| { | |||||
| fSockfd = 0; | |||||
| fPort = port; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetUnixSocket::~JackNetUnixSocket() | |||||
| { | |||||
| Close(); | |||||
| } | |||||
| //socket*********************************************************************************************************** | |||||
| int JackNetUnixSocket::NewSocket() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| { | |||||
| Close(); | |||||
| Reset(); | |||||
| } | |||||
| fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); | |||||
| return fSockfd; | |||||
| } | |||||
| int JackNetUnixSocket::Bind() | |||||
| { | |||||
| return bind ( fSockfd, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), sizeof ( socket_address_t ) ); | |||||
| } | |||||
| int JackNetUnixSocket::BindWith ( const char* ip ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fRecvAddr.sin_addr ); | |||||
| if ( addr_conv < 0 ) | |||||
| return addr_conv; | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetUnixSocket::BindWith ( int port ) | |||||
| { | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetUnixSocket::Connect() | |||||
| { | |||||
| return connect ( fSockfd, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); | |||||
| } | |||||
| int JackNetUnixSocket::ConnectTo ( const char* ip ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| if ( addr_conv < 0 ) | |||||
| return addr_conv; | |||||
| return Connect(); | |||||
| } | |||||
| void JackNetUnixSocket::Close() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| close ( fSockfd ); | |||||
| fSockfd = 0; | |||||
| } | |||||
| void JackNetUnixSocket::Reset() | |||||
| { | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( fPort ); | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( fPort ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| bool JackNetUnixSocket::IsSocket() | |||||
| { | |||||
| return ( fSockfd ) ? true : false; | |||||
| } | |||||
| //IP/PORT*********************************************************************************************************** | |||||
| void JackNetUnixSocket::SetPort ( int port ) | |||||
| { | |||||
| fPort = port; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| } | |||||
| int JackNetUnixSocket::GetPort() | |||||
| { | |||||
| return fPort; | |||||
| } | |||||
| //address*********************************************************************************************************** | |||||
| int JackNetUnixSocket::SetAddress ( const char* ip, int port ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| if ( addr_conv < 0 ) | |||||
| return addr_conv; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| return 0; | |||||
| } | |||||
| char* JackNetUnixSocket::GetSendIP() | |||||
| { | |||||
| return inet_ntoa ( fSendAddr.sin_addr ); | |||||
| } | |||||
| char* JackNetUnixSocket::GetRecvIP() | |||||
| { | |||||
| return inet_ntoa ( fRecvAddr.sin_addr ); | |||||
| } | |||||
| //utility************************************************************************************************************ | |||||
| int JackNetUnixSocket::GetName ( char* name ) | |||||
| { | |||||
| return gethostname ( name, 255 ); | |||||
| } | |||||
| int JackNetUnixSocket::JoinMCastGroup ( const char* ip ) | |||||
| { | |||||
| struct ip_mreq multicast_req; | |||||
| inet_aton ( ip, &multicast_req.imr_multiaddr ); | |||||
| multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY ); | |||||
| 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************************************************************************************************************ | |||||
| int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen ) | |||||
| { | |||||
| return setsockopt ( fSockfd, level, optname, optval, optlen ); | |||||
| } | |||||
| int JackNetUnixSocket::GetOption ( int level, int optname, void* optval, socklen_t* optlen ) | |||||
| { | |||||
| return getsockopt ( fSockfd, level, optname, optval, optlen ); | |||||
| } | |||||
| //timeout************************************************************************************************************* | |||||
| int JackNetUnixSocket::SetTimeOut ( int& msec ) | |||||
| { | |||||
| //negative timeout, or exceeding 10s, return | |||||
| if ( ( msec < 0 ) || ( msec > 10000 ) ) | |||||
| return -1; | |||||
| struct timeval timeout; | |||||
| //less than 1sec | |||||
| if ( msec < 1000 ) | |||||
| { | |||||
| timeout.tv_sec = 0; | |||||
| timeout.tv_usec = msec * 1000; | |||||
| return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) ); | |||||
| } | |||||
| //more than 1sec | |||||
| if ( msec >= 1000 ) | |||||
| { | |||||
| float sec = static_cast<float>( msec ) / 1000.0f; | |||||
| timeout.tv_sec = ( int ) sec; | |||||
| float usec = ( sec - timeout.tv_sec ) * 1000000; | |||||
| timeout.tv_usec = ( int ) usec; | |||||
| return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) ); | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| //local loop********************************************************************************************************** | |||||
| int JackNetUnixSocket::SetLocalLoop() | |||||
| { | |||||
| char disable = 0; | |||||
| return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); | |||||
| } | |||||
| //network operations************************************************************************************************** | |||||
| int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); | |||||
| } | |||||
| int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ) | |||||
| { | |||||
| int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||||
| if ( addr_conv < 1 ) | |||||
| return addr_conv; | |||||
| return SendTo ( buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return send ( fSockfd, buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| socklen_t addr_len = sizeof ( socket_address_t ); | |||||
| return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len ); | |||||
| } | |||||
| int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return recv ( fSockfd, buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| socklen_t addr_len = sizeof ( socket_address_t ); | |||||
| return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len ); | |||||
| } | |||||
| net_error_t JackNetUnixSocket::GetError() | |||||
| { | |||||
| switch ( errno ) | |||||
| { | |||||
| case EAGAIN: | |||||
| return NET_NO_DATA; | |||||
| case ECONNABORTED: | |||||
| return NET_CONN_ERROR; | |||||
| case ECONNREFUSED: | |||||
| return NET_CONN_ERROR; | |||||
| case ECONNRESET: | |||||
| return NET_CONN_ERROR; | |||||
| case EHOSTDOWN: | |||||
| return NET_CONN_ERROR; | |||||
| case EHOSTUNREACH: | |||||
| return NET_CONN_ERROR; | |||||
| default: | |||||
| return NET_OP_ERROR; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -29,73 +29,73 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| #define NET_ERROR_CODE errno | |||||
| #define SOCKET_ERROR -1 | |||||
| #define StrError strerror | |||||
| typedef struct sockaddr socket_address_t; | |||||
| typedef struct in_addr address_t; | |||||
| //JackNetUnixSocket******************************************** | |||||
| class EXPORT JackNetUnixSocket | |||||
| { | |||||
| private: | |||||
| int fSockfd; | |||||
| int fPort; | |||||
| struct sockaddr_in fSendAddr; | |||||
| struct sockaddr_in fRecvAddr; | |||||
| public: | |||||
| JackNetUnixSocket(); | |||||
| JackNetUnixSocket ( const char* ip, int port ); | |||||
| ~JackNetUnixSocket(); | |||||
| //socket management | |||||
| int NewSocket(); | |||||
| int Bind(); | |||||
| int BindWith ( const char* ip ); | |||||
| int BindWith ( int port ); | |||||
| int Connect(); | |||||
| int ConnectTo ( const char* ip ); | |||||
| void Close(); | |||||
| void Reset(); | |||||
| bool IsSocket(); | |||||
| //IP/PORT management | |||||
| void SetPort ( int port ); | |||||
| int GetPort(); | |||||
| //address management | |||||
| int SetAddress ( const char* ip, int port ); | |||||
| char* GetSendIP(); | |||||
| char* GetRecvIP(); | |||||
| //utility | |||||
| int GetName ( char* name ); | |||||
| int JoinMCastGroup ( const char* mcast_ip ); | |||||
| void CopyParams ( JackNetUnixSocket* socket ); | |||||
| //options management | |||||
| int SetOption ( int level, int optname, const void* optval, socklen_t optlen ); | |||||
| int GetOption ( int level, int optname, void* optval, socklen_t* optlen ); | |||||
| //timeout | |||||
| int SetTimeOut ( int& msec ); | |||||
| //local loop | |||||
| int SetLocalLoop(); | |||||
| //network operations | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags ); | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ); | |||||
| int Send ( const void* buffer, size_t nbytes, int flags ); | |||||
| int RecvFrom ( void* buffer, size_t nbytes, int flags ); | |||||
| int Recv ( void* buffer, size_t nbytes, int flags ); | |||||
| int CatchHost ( void* buffer, size_t nbytes, int flags ); | |||||
| //error management | |||||
| net_error_t GetError(); | |||||
| }; | |||||
| #define NET_ERROR_CODE errno | |||||
| #define SOCKET_ERROR -1 | |||||
| #define StrError strerror | |||||
| typedef struct sockaddr socket_address_t; | |||||
| typedef struct in_addr address_t; | |||||
| //JackNetUnixSocket******************************************** | |||||
| class EXPORT JackNetUnixSocket | |||||
| { | |||||
| private: | |||||
| int fSockfd; | |||||
| int fPort; | |||||
| struct sockaddr_in fSendAddr; | |||||
| struct sockaddr_in fRecvAddr; | |||||
| public: | |||||
| JackNetUnixSocket(); | |||||
| JackNetUnixSocket ( const char* ip, int port ); | |||||
| ~JackNetUnixSocket(); | |||||
| //socket management | |||||
| int NewSocket(); | |||||
| int Bind(); | |||||
| int BindWith ( const char* ip ); | |||||
| int BindWith ( int port ); | |||||
| int Connect(); | |||||
| int ConnectTo ( const char* ip ); | |||||
| void Close(); | |||||
| void Reset(); | |||||
| bool IsSocket(); | |||||
| //IP/PORT management | |||||
| void SetPort ( int port ); | |||||
| int GetPort(); | |||||
| //address management | |||||
| int SetAddress ( const char* ip, int port ); | |||||
| char* GetSendIP(); | |||||
| char* GetRecvIP(); | |||||
| //utility | |||||
| int GetName ( char* name ); | |||||
| int JoinMCastGroup ( const char* mcast_ip ); | |||||
| void CopyParams ( JackNetUnixSocket* socket ); | |||||
| //options management | |||||
| int SetOption ( int level, int optname, const void* optval, socklen_t optlen ); | |||||
| int GetOption ( int level, int optname, void* optval, socklen_t* optlen ); | |||||
| //timeout | |||||
| int SetTimeOut ( int& msec ); | |||||
| //local loop | |||||
| int SetLocalLoop(); | |||||
| //network operations | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags ); | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ); | |||||
| int Send ( const void* buffer, size_t nbytes, int flags ); | |||||
| int RecvFrom ( void* buffer, size_t nbytes, int flags ); | |||||
| int Recv ( void* buffer, size_t nbytes, int flags ); | |||||
| int CatchHost ( void* buffer, size_t nbytes, int flags ); | |||||
| //error management | |||||
| net_error_t GetError(); | |||||
| }; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -1,336 +1,340 @@ | |||||
| /* | |||||
| Copyright (C) 2008 Romain Moret at Grame | |||||
| This program is free software; you can redistribute it and/or modify | |||||
| it under the terms of the GNU General Public License as published by | |||||
| the Free Software Foundation; either version 2 of the License, or | |||||
| (at your option) any later version. | |||||
| This program is distributed in the hope that it will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU General Public License | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| */ | |||||
| #include "JackNetWinSocket.h" | |||||
| namespace Jack | |||||
| { | |||||
| //utility ********************************************************************************************************* | |||||
| EXPORT int GetHostName ( char * name, int size ) | |||||
| { | |||||
| if ( gethostname ( name, size ) == SOCKET_ERROR ) | |||||
| { | |||||
| jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) ); | |||||
| strcpy ( name, "default" ); | |||||
| return -1; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| struct { int code; char* msg; } NetErrorList[] = | |||||
| { | |||||
| E(0, "No error"), | |||||
| E(WSAEINTR, "Interrupted system call"), | |||||
| E(WSAEBADF, "Bad file number"), | |||||
| E(WSAEACCES, "Permission denied"), | |||||
| E(WSAEFAULT, "Bad address"), | |||||
| E(WSAEINVAL, "Invalid argument"), | |||||
| E(WSAEMFILE, "Too many open sockets"), | |||||
| E(WSAEWOULDBLOCK, "Operation would block"), | |||||
| E(WSAEINPROGRESS, "Operation now in progress"), | |||||
| E(WSAEALREADY, "Operation already in progress"), | |||||
| E(WSAENOTSOCK, "Socket operation on non-socket"), | |||||
| E(WSAEDESTADDRREQ, "Destination address required"), | |||||
| E(WSAEMSGSIZE, "Message too long"), | |||||
| E(WSAEPROTOTYPE, "Protocol wrong type for socket"), | |||||
| E(WSAENOPROTOOPT, "Bad protocol option"), | |||||
| E(WSAEPROTONOSUPPORT, "Protocol not supported"), | |||||
| E(WSAESOCKTNOSUPPORT, "Socket type not supported"), | |||||
| E(WSAEOPNOTSUPP, "Operation not supported on socket"), | |||||
| E(WSAEPFNOSUPPORT, "Protocol family not supported"), | |||||
| E(WSAEAFNOSUPPORT, "Address family not supported"), | |||||
| E(WSAEADDRINUSE, "Address already in use"), | |||||
| E(WSAEADDRNOTAVAIL, "Can't assign requested address"), | |||||
| E(WSAENETDOWN, "Network is down"), | |||||
| E(WSAENETUNREACH, "Network is unreachable"), | |||||
| E(WSAENETRESET, "Net connection reset"), | |||||
| E(WSAECONNABORTED, "Software caused connection abort"), | |||||
| E(WSAECONNRESET, "Connection reset by peer"), | |||||
| E(WSAENOBUFS, "No buffer space available"), | |||||
| E(WSAEISCONN, "Socket is already connected"), | |||||
| E(WSAENOTCONN, "Socket is not connected"), | |||||
| E(WSAESHUTDOWN, "Can't send after socket shutdown"), | |||||
| E(WSAETOOMANYREFS, "Too many references, can't splice"), | |||||
| E(WSAETIMEDOUT, "Connection timed out"), | |||||
| E(WSAECONNREFUSED, "Connection refused"), | |||||
| E(WSAELOOP, "Too many levels of symbolic links"), | |||||
| E(WSAENAMETOOLONG, "File name too long"), | |||||
| E(WSAEHOSTDOWN, "Host is down"), | |||||
| E(WSAEHOSTUNREACH, "No route to host"), | |||||
| E(WSAENOTEMPTY, "Directory not empty"), | |||||
| E(WSAEPROCLIM, "Too many processes"), | |||||
| E(WSAEUSERS, "Too many users"), | |||||
| E(WSAEDQUOT, "Disc quota exceeded"), | |||||
| E(WSAESTALE, "Stale NFS file handle"), | |||||
| E(WSAEREMOTE, "Too many levels of remote in path"), | |||||
| E(WSASYSNOTREADY, "Network system is unavailable"), | |||||
| E(WSAVERNOTSUPPORTED, "Winsock version out of range"), | |||||
| E(WSANOTINITIALISED, "WSAStartup not yet called"), | |||||
| E(WSAEDISCON, "Graceful shutdown in progress"), | |||||
| E(WSAHOST_NOT_FOUND, "Host not found"), | |||||
| E(WSANO_DATA, "No host data of that type was found"), | |||||
| { -1, NULL }, | |||||
| }; | |||||
| EXPORT const char* PrintError ( int error ) | |||||
| { | |||||
| int i; | |||||
| for ( i = 0; NetErrorList[i].code >= 0; ++i) | |||||
| { | |||||
| if ( error == NetErrorList[i].code ) | |||||
| return NetErrorList[i].msg; | |||||
| } | |||||
| return strerror ( error ); | |||||
| } | |||||
| //construct/destruct*********************************************************************************************** | |||||
| JackNetWinSocket::JackNetWinSocket() | |||||
| { | |||||
| fSockfd = 0; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetWinSocket::JackNetWinSocket ( const char* ip, int port ) | |||||
| { | |||||
| fSockfd = 0; | |||||
| fPort = port; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetWinSocket::~JackNetWinSocket() | |||||
| { | |||||
| Close(); | |||||
| } | |||||
| //socket*********************************************************************************************************** | |||||
| int JackNetWinSocket::NewSocket() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| { | |||||
| Close(); | |||||
| Reset(); | |||||
| } | |||||
| fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); | |||||
| return fSockfd; | |||||
| } | |||||
| int JackNetWinSocket::Bind() | |||||
| { | |||||
| return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) ); | |||||
| } | |||||
| int JackNetWinSocket::BindWith ( const char* ip ) | |||||
| { | |||||
| fRecvAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetWinSocket::BindWith ( int port ) | |||||
| { | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetWinSocket::Connect() | |||||
| { | |||||
| return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) ); | |||||
| } | |||||
| int JackNetWinSocket::ConnectTo ( const char* ip ) | |||||
| { | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| return Connect(); | |||||
| } | |||||
| void JackNetWinSocket::Close() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| closesocket ( fSockfd ); | |||||
| fSockfd = 0; | |||||
| } | |||||
| void JackNetWinSocket::Reset() | |||||
| { | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( fPort ); | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( fPort ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| bool JackNetWinSocket::IsSocket() | |||||
| { | |||||
| return ( fSockfd ) ? true : false; | |||||
| } | |||||
| //IP/PORT*********************************************************************************************************** | |||||
| void JackNetWinSocket::SetPort ( int port ) | |||||
| { | |||||
| fPort = port; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| } | |||||
| int JackNetWinSocket::GetPort() | |||||
| { | |||||
| return fPort; | |||||
| } | |||||
| //address*********************************************************************************************************** | |||||
| int JackNetWinSocket::SetAddress ( const char* ip, int port ) | |||||
| { | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| return 0; | |||||
| } | |||||
| char* JackNetWinSocket::GetSendIP() | |||||
| { | |||||
| return inet_ntoa ( fSendAddr.sin_addr ); | |||||
| } | |||||
| char* JackNetWinSocket::GetRecvIP() | |||||
| { | |||||
| return inet_ntoa ( fRecvAddr.sin_addr ); | |||||
| } | |||||
| //utility************************************************************************************************************ | |||||
| int JackNetWinSocket::GetName ( char* name ) | |||||
| { | |||||
| return gethostname ( name, 255 ); | |||||
| } | |||||
| int JackNetWinSocket::JoinMCastGroup ( const char* ip ) | |||||
| { | |||||
| struct ip_mreq multicast_req; | |||||
| multicast_req.imr_multiaddr.s_addr = inet_addr ( ip ); | |||||
| multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY ); | |||||
| //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...) | |||||
| return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) ); | |||||
| } | |||||
| void JackNetWinSocket::CopyParams ( JackNetWinSocket* socket ) | |||||
| { | |||||
| fPort = socket->fPort; | |||||
| fSendAddr = socket->fSendAddr; | |||||
| fRecvAddr = socket->fRecvAddr; | |||||
| } | |||||
| //options************************************************************************************************************ | |||||
| int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen ) | |||||
| { | |||||
| return setsockopt ( fSockfd, level, optname, static_cast<const char*>(optval), optlen ); | |||||
| } | |||||
| int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen ) | |||||
| { | |||||
| return getsockopt ( fSockfd, level, optname, static_cast<char*>(optval), optlen ); | |||||
| } | |||||
| //tiemout************************************************************************************************************ | |||||
| int JackNetWinSocket::SetTimeOut ( int& msec ) | |||||
| { | |||||
| //negative timeout, or exceeding 10s, return | |||||
| if ( ( msec < 0 ) || ( msec > 10000 ) ) | |||||
| return -1; | |||||
| return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &msec, sizeof ( msec ) ); | |||||
| } | |||||
| //local loop********************************************************************************************************* | |||||
| int JackNetWinSocket::SetLocalLoop() | |||||
| { | |||||
| char enable = 1; | |||||
| return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &enable, sizeof ( enable ) ); | |||||
| } | |||||
| //network operations************************************************************************************************* | |||||
| int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return sendto ( fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) ); | |||||
| } | |||||
| int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ) | |||||
| { | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| return SendTo ( buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return send ( fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags ); | |||||
| } | |||||
| int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| SOCKLEN addr_len = sizeof ( SOCKADDR ); | |||||
| return recvfrom ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len ); | |||||
| } | |||||
| int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return recv ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags ); | |||||
| } | |||||
| int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| SOCKLEN addr_len = sizeof ( SOCKADDR ); | |||||
| return recvfrom ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len ); | |||||
| } | |||||
| net_error_t JackNetWinSocket::GetError() | |||||
| { | |||||
| switch ( NET_ERROR_CODE ) | |||||
| { | |||||
| case WSABASEERR: | |||||
| return NET_NO_ERROR; | |||||
| case WSAETIMEDOUT: | |||||
| return NET_NO_DATA; | |||||
| case WSAECONNREFUSED: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAECONNRESET: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAEACCES: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAECONNABORTED: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAEHOSTDOWN: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAEHOSTUNREACH: | |||||
| return NET_CONN_ERROR; | |||||
| default: | |||||
| return NET_OP_ERROR; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* | |||||
| Copyright (C) 2008 Romain Moret at Grame | |||||
| This program is free software; you can redistribute it and/or modify | |||||
| it under the terms of the GNU General Public License as published by | |||||
| the Free Software Foundation; either version 2 of the License, or | |||||
| (at your option) any later version. | |||||
| This program is distributed in the hope that it will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU General Public License | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| */ | |||||
| #include "JackNetWinSocket.h" | |||||
| namespace Jack | |||||
| { | |||||
| //utility ********************************************************************************************************* | |||||
| EXPORT int GetHostName ( char * name, int size ) | |||||
| { | |||||
| if ( gethostname ( name, size ) == SOCKET_ERROR ) | |||||
| { | |||||
| jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) ); | |||||
| strcpy ( name, "default" ); | |||||
| return -1; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| struct | |||||
| { | |||||
| int code; | |||||
| char* msg; | |||||
| } NetErrorList[] = | |||||
| { | |||||
| E(0, "No error"), | |||||
| E(WSAEINTR, "Interrupted system call"), | |||||
| E(WSAEBADF, "Bad file number"), | |||||
| E(WSAEACCES, "Permission denied"), | |||||
| E(WSAEFAULT, "Bad address"), | |||||
| E(WSAEINVAL, "Invalid argument"), | |||||
| E(WSAEMFILE, "Too many open sockets"), | |||||
| E(WSAEWOULDBLOCK, "Operation would block"), | |||||
| E(WSAEINPROGRESS, "Operation now in progress"), | |||||
| E(WSAEALREADY, "Operation already in progress"), | |||||
| E(WSAENOTSOCK, "Socket operation on non-socket"), | |||||
| E(WSAEDESTADDRREQ, "Destination address required"), | |||||
| E(WSAEMSGSIZE, "Message too long"), | |||||
| E(WSAEPROTOTYPE, "Protocol wrong type for socket"), | |||||
| E(WSAENOPROTOOPT, "Bad protocol option"), | |||||
| E(WSAEPROTONOSUPPORT, "Protocol not supported"), | |||||
| E(WSAESOCKTNOSUPPORT, "Socket type not supported"), | |||||
| E(WSAEOPNOTSUPP, "Operation not supported on socket"), | |||||
| E(WSAEPFNOSUPPORT, "Protocol family not supported"), | |||||
| E(WSAEAFNOSUPPORT, "Address family not supported"), | |||||
| E(WSAEADDRINUSE, "Address already in use"), | |||||
| E(WSAEADDRNOTAVAIL, "Can't assign requested address"), | |||||
| E(WSAENETDOWN, "Network is down"), | |||||
| E(WSAENETUNREACH, "Network is unreachable"), | |||||
| E(WSAENETRESET, "Net connection reset"), | |||||
| E(WSAECONNABORTED, "Software caused connection abort"), | |||||
| E(WSAECONNRESET, "Connection reset by peer"), | |||||
| E(WSAENOBUFS, "No buffer space available"), | |||||
| E(WSAEISCONN, "Socket is already connected"), | |||||
| E(WSAENOTCONN, "Socket is not connected"), | |||||
| E(WSAESHUTDOWN, "Can't send after socket shutdown"), | |||||
| E(WSAETOOMANYREFS, "Too many references, can't splice"), | |||||
| E(WSAETIMEDOUT, "Connection timed out"), | |||||
| E(WSAECONNREFUSED, "Connection refused"), | |||||
| E(WSAELOOP, "Too many levels of symbolic links"), | |||||
| E(WSAENAMETOOLONG, "File name too long"), | |||||
| E(WSAEHOSTDOWN, "Host is down"), | |||||
| E(WSAEHOSTUNREACH, "No route to host"), | |||||
| E(WSAENOTEMPTY, "Directory not empty"), | |||||
| E(WSAEPROCLIM, "Too many processes"), | |||||
| E(WSAEUSERS, "Too many users"), | |||||
| E(WSAEDQUOT, "Disc quota exceeded"), | |||||
| E(WSAESTALE, "Stale NFS file handle"), | |||||
| E(WSAEREMOTE, "Too many levels of remote in path"), | |||||
| E(WSASYSNOTREADY, "Network system is unavailable"), | |||||
| E(WSAVERNOTSUPPORTED, "Winsock version out of range"), | |||||
| E(WSANOTINITIALISED, "WSAStartup not yet called"), | |||||
| E(WSAEDISCON, "Graceful shutdown in progress"), | |||||
| E(WSAHOST_NOT_FOUND, "Host not found"), | |||||
| E(WSANO_DATA, "No host data of that type was found"), | |||||
| { -1, NULL }, | |||||
| }; | |||||
| EXPORT const char* PrintError ( int error ) | |||||
| { | |||||
| int i; | |||||
| for ( i = 0; NetErrorList[i].code >= 0; ++i) | |||||
| { | |||||
| if ( error == NetErrorList[i].code ) | |||||
| return NetErrorList[i].msg; | |||||
| } | |||||
| return strerror ( error ); | |||||
| } | |||||
| //construct/destruct*********************************************************************************************** | |||||
| JackNetWinSocket::JackNetWinSocket() | |||||
| { | |||||
| fSockfd = 0; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetWinSocket::JackNetWinSocket ( const char* ip, int port ) | |||||
| { | |||||
| fSockfd = 0; | |||||
| fPort = port; | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| JackNetWinSocket::~JackNetWinSocket() | |||||
| { | |||||
| Close(); | |||||
| } | |||||
| //socket*********************************************************************************************************** | |||||
| int JackNetWinSocket::NewSocket() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| { | |||||
| Close(); | |||||
| Reset(); | |||||
| } | |||||
| fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); | |||||
| return fSockfd; | |||||
| } | |||||
| int JackNetWinSocket::Bind() | |||||
| { | |||||
| return bind ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), sizeof ( SOCKADDR ) ); | |||||
| } | |||||
| int JackNetWinSocket::BindWith ( const char* ip ) | |||||
| { | |||||
| fRecvAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetWinSocket::BindWith ( int port ) | |||||
| { | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| return Bind(); | |||||
| } | |||||
| int JackNetWinSocket::Connect() | |||||
| { | |||||
| return connect ( fSockfd, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) ); | |||||
| } | |||||
| int JackNetWinSocket::ConnectTo ( const char* ip ) | |||||
| { | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| return Connect(); | |||||
| } | |||||
| void JackNetWinSocket::Close() | |||||
| { | |||||
| if ( fSockfd ) | |||||
| closesocket ( fSockfd ); | |||||
| fSockfd = 0; | |||||
| } | |||||
| void JackNetWinSocket::Reset() | |||||
| { | |||||
| fSendAddr.sin_family = AF_INET; | |||||
| fSendAddr.sin_port = htons ( fPort ); | |||||
| fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fSendAddr.sin_zero, 0, 8 ); | |||||
| fRecvAddr.sin_family = AF_INET; | |||||
| fRecvAddr.sin_port = htons ( fPort ); | |||||
| fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||||
| memset ( &fRecvAddr.sin_zero, 0, 8 ); | |||||
| } | |||||
| bool JackNetWinSocket::IsSocket() | |||||
| { | |||||
| return ( fSockfd ) ? true : false; | |||||
| } | |||||
| //IP/PORT*********************************************************************************************************** | |||||
| void JackNetWinSocket::SetPort ( int port ) | |||||
| { | |||||
| fPort = port; | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| fRecvAddr.sin_port = htons ( port ); | |||||
| } | |||||
| int JackNetWinSocket::GetPort() | |||||
| { | |||||
| return fPort; | |||||
| } | |||||
| //address*********************************************************************************************************** | |||||
| int JackNetWinSocket::SetAddress ( const char* ip, int port ) | |||||
| { | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| fSendAddr.sin_port = htons ( port ); | |||||
| return 0; | |||||
| } | |||||
| char* JackNetWinSocket::GetSendIP() | |||||
| { | |||||
| return inet_ntoa ( fSendAddr.sin_addr ); | |||||
| } | |||||
| char* JackNetWinSocket::GetRecvIP() | |||||
| { | |||||
| return inet_ntoa ( fRecvAddr.sin_addr ); | |||||
| } | |||||
| //utility************************************************************************************************************ | |||||
| int JackNetWinSocket::GetName ( char* name ) | |||||
| { | |||||
| return gethostname ( name, 255 ); | |||||
| } | |||||
| int JackNetWinSocket::JoinMCastGroup ( const char* ip ) | |||||
| { | |||||
| struct ip_mreq multicast_req; | |||||
| multicast_req.imr_multiaddr.s_addr = inet_addr ( ip ); | |||||
| multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY ); | |||||
| //12 is IP_ADD_MEMBERSHIP in winsock2 (differs from winsock1...) | |||||
| return SetOption ( IPPROTO_IP, 12, &multicast_req, sizeof ( multicast_req ) ); | |||||
| } | |||||
| void JackNetWinSocket::CopyParams ( JackNetWinSocket* socket ) | |||||
| { | |||||
| fPort = socket->fPort; | |||||
| fSendAddr = socket->fSendAddr; | |||||
| fRecvAddr = socket->fRecvAddr; | |||||
| } | |||||
| //options************************************************************************************************************ | |||||
| int JackNetWinSocket::SetOption ( int level, int optname, const void* optval, SOCKLEN optlen ) | |||||
| { | |||||
| return setsockopt ( fSockfd, level, optname, static_cast<const char*>(optval), optlen ); | |||||
| } | |||||
| int JackNetWinSocket::GetOption ( int level, int optname, void* optval, SOCKLEN* optlen ) | |||||
| { | |||||
| return getsockopt ( fSockfd, level, optname, static_cast<char*>(optval), optlen ); | |||||
| } | |||||
| //tiemout************************************************************************************************************ | |||||
| int JackNetWinSocket::SetTimeOut ( int& msec ) | |||||
| { | |||||
| //negative timeout, or exceeding 10s, return | |||||
| if ( ( msec < 0 ) || ( msec > 10000 ) ) | |||||
| return -1; | |||||
| return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &msec, sizeof ( msec ) ); | |||||
| } | |||||
| //local loop********************************************************************************************************* | |||||
| int JackNetWinSocket::SetLocalLoop() | |||||
| { | |||||
| char enable = 1; | |||||
| return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &enable, sizeof ( enable ) ); | |||||
| } | |||||
| //network operations************************************************************************************************* | |||||
| int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return sendto ( fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), sizeof ( SOCKADDR ) ); | |||||
| } | |||||
| int JackNetWinSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ) | |||||
| { | |||||
| fSendAddr.sin_addr.s_addr = inet_addr ( ip ); | |||||
| return SendTo ( buffer, nbytes, flags ); | |||||
| } | |||||
| int JackNetWinSocket::Send ( const void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return send ( fSockfd, reinterpret_cast<const char*>(buffer), nbytes, flags ); | |||||
| } | |||||
| int JackNetWinSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| SOCKLEN addr_len = sizeof ( SOCKADDR ); | |||||
| return recvfrom ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fRecvAddr ), &addr_len ); | |||||
| } | |||||
| int JackNetWinSocket::Recv ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| return recv ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags ); | |||||
| } | |||||
| int JackNetWinSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) | |||||
| { | |||||
| SOCKLEN addr_len = sizeof ( SOCKADDR ); | |||||
| return recvfrom ( fSockfd, reinterpret_cast<char*>(buffer), nbytes, flags, reinterpret_cast<SOCKADDR*> ( &fSendAddr ), &addr_len ); | |||||
| } | |||||
| net_error_t JackNetWinSocket::GetError() | |||||
| { | |||||
| switch ( NET_ERROR_CODE ) | |||||
| { | |||||
| case WSABASEERR: | |||||
| return NET_NO_ERROR; | |||||
| case WSAETIMEDOUT: | |||||
| return NET_NO_DATA; | |||||
| case WSAECONNREFUSED: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAECONNRESET: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAEACCES: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAECONNABORTED: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAEHOSTDOWN: | |||||
| return NET_CONN_ERROR; | |||||
| case WSAEHOSTUNREACH: | |||||
| return NET_CONN_ERROR; | |||||
| default: | |||||
| return NET_OP_ERROR; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,102 +1,102 @@ | |||||
| /* | |||||
| Copyright (C) 2008 Romain Moret at Grame | |||||
| This program is free software; you can redistribute it and/or modify | |||||
| it under the terms of the GNU General Public License as published by | |||||
| the Free Software Foundation; either version 2 of the License, or | |||||
| (at your option) any later version. | |||||
| This program is distributed in the hope that it will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU General Public License | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| */ | |||||
| #ifndef __JackNetWinSocket__ | |||||
| #define __JackNetWinSocket__ | |||||
| #include "JackNetSocket.h" | |||||
| #ifdef __MINGW32__ | |||||
| #include <winsock2.h> | |||||
| #include <ws2tcpip.h> | |||||
| #endif | |||||
| namespace Jack | |||||
| { | |||||
| #define E(code, s) { code, s } | |||||
| #define NET_ERROR_CODE WSAGetLastError() | |||||
| #define StrError PrintError | |||||
| typedef uint32_t uint; | |||||
| typedef int SOCKLEN; | |||||
| EXPORT const char* PrintError ( int error ); | |||||
| //JeckNetWinSocket*************************************************************************** | |||||
| class EXPORT JackNetWinSocket | |||||
| { | |||||
| private: | |||||
| int fSockfd; | |||||
| int fPort; | |||||
| SOCKADDR_IN fSendAddr; | |||||
| SOCKADDR_IN fRecvAddr; | |||||
| public: | |||||
| JackNetWinSocket(); | |||||
| JackNetWinSocket ( const char* ip, int port ); | |||||
| ~JackNetWinSocket(); | |||||
| //socket management | |||||
| int NewSocket(); | |||||
| int Bind(); | |||||
| int BindWith ( const char* ip ); | |||||
| int BindWith ( int port ); | |||||
| int Connect(); | |||||
| int ConnectTo ( const char* ip ); | |||||
| void Close(); | |||||
| void Reset(); | |||||
| bool IsSocket(); | |||||
| //IP/PORT management | |||||
| void SetPort ( int port ); | |||||
| int GetPort(); | |||||
| //address management | |||||
| int SetAddress ( const char* ip, int port ); | |||||
| char* GetSendIP(); | |||||
| char* GetRecvIP(); | |||||
| //utility | |||||
| int GetName ( char* name ); | |||||
| int JoinMCastGroup ( const char* mcast_ip ); | |||||
| void CopyParams ( JackNetWinSocket* socket ); | |||||
| //options management | |||||
| int SetOption ( int level, int optname, const void* optval, SOCKLEN optlen ); | |||||
| int GetOption ( int level, int optname, void* optval, SOCKLEN* optlen ); | |||||
| //timeout | |||||
| int SetTimeOut ( int& msec ); | |||||
| //local loop | |||||
| int SetLocalLoop(); | |||||
| //network operations | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags ); | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ); | |||||
| int Send ( const void* buffer, size_t nbytes, int flags ); | |||||
| int RecvFrom ( void* buffer, size_t nbytes, int flags ); | |||||
| int Recv ( void* buffer, size_t nbytes, int flags ); | |||||
| int CatchHost ( void* buffer, size_t nbytes, int flags ); | |||||
| //error management | |||||
| net_error_t GetError(); | |||||
| }; | |||||
| } | |||||
| #endif | |||||
| /* | |||||
| Copyright (C) 2008 Romain Moret at Grame | |||||
| This program is free software; you can redistribute it and/or modify | |||||
| it under the terms of the GNU General Public License as published by | |||||
| the Free Software Foundation; either version 2 of the License, or | |||||
| (at your option) any later version. | |||||
| This program is distributed in the hope that it will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU General Public License | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| */ | |||||
| #ifndef __JackNetWinSocket__ | |||||
| #define __JackNetWinSocket__ | |||||
| #include "JackNetSocket.h" | |||||
| #ifdef __MINGW32__ | |||||
| #include <winsock2.h> | |||||
| #include <ws2tcpip.h> | |||||
| #endif | |||||
| namespace Jack | |||||
| { | |||||
| #define E(code, s) { code, s } | |||||
| #define NET_ERROR_CODE WSAGetLastError() | |||||
| #define StrError PrintError | |||||
| typedef uint32_t uint; | |||||
| typedef int SOCKLEN; | |||||
| EXPORT const char* PrintError ( int error ); | |||||
| //JeckNetWinSocket*************************************************************************** | |||||
| class EXPORT JackNetWinSocket | |||||
| { | |||||
| private: | |||||
| int fSockfd; | |||||
| int fPort; | |||||
| SOCKADDR_IN fSendAddr; | |||||
| SOCKADDR_IN fRecvAddr; | |||||
| public: | |||||
| JackNetWinSocket(); | |||||
| JackNetWinSocket ( const char* ip, int port ); | |||||
| ~JackNetWinSocket(); | |||||
| //socket management | |||||
| int NewSocket(); | |||||
| int Bind(); | |||||
| int BindWith ( const char* ip ); | |||||
| int BindWith ( int port ); | |||||
| int Connect(); | |||||
| int ConnectTo ( const char* ip ); | |||||
| void Close(); | |||||
| void Reset(); | |||||
| bool IsSocket(); | |||||
| //IP/PORT management | |||||
| void SetPort ( int port ); | |||||
| int GetPort(); | |||||
| //address management | |||||
| int SetAddress ( const char* ip, int port ); | |||||
| char* GetSendIP(); | |||||
| char* GetRecvIP(); | |||||
| //utility | |||||
| int GetName ( char* name ); | |||||
| int JoinMCastGroup ( const char* mcast_ip ); | |||||
| void CopyParams ( JackNetWinSocket* socket ); | |||||
| //options management | |||||
| int SetOption ( int level, int optname, const void* optval, SOCKLEN optlen ); | |||||
| int GetOption ( int level, int optname, void* optval, SOCKLEN* optlen ); | |||||
| //timeout | |||||
| int SetTimeOut ( int& msec ); | |||||
| //local loop | |||||
| int SetLocalLoop(); | |||||
| //network operations | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags ); | |||||
| int SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ); | |||||
| int Send ( const void* buffer, size_t nbytes, int flags ); | |||||
| int RecvFrom ( void* buffer, size_t nbytes, int flags ); | |||||
| int Recv ( void* buffer, size_t nbytes, int flags ); | |||||
| int CatchHost ( void* buffer, size_t nbytes, int flags ); | |||||
| //error management | |||||
| net_error_t GetError(); | |||||
| }; | |||||
| } | |||||
| #endif | |||||