mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
Merged rfs_server/mux VS2010 compilation patch from Peter Edwards
This commit is contained in:
commit
d717fc44db
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,4 +11,6 @@ inc/romfiles.h
|
||||
.sconf_temp/
|
||||
.sconsign.dblite
|
||||
config.log
|
||||
mux
|
||||
rfs_server
|
||||
|
||||
|
2
mux.lua
2
mux.lua
@ -6,7 +6,7 @@ builder:init( args )
|
||||
builder:set_build_mode( builder.BUILD_DIR_LINEARIZED )
|
||||
|
||||
local flist = "main.c"
|
||||
local rfs_flist = "main.c server.c log.c deskutils.c"
|
||||
local rfs_flist = "main.c server.c log.c deskutils.c rfs_transports.c"
|
||||
local cdefs = "RFS_UDP_TRANSPORT RFS_INSIDE_MUX_MODE"
|
||||
local socklib
|
||||
if utils.is_windows() then
|
||||
|
2
mux.py
2
mux.py
@ -1,7 +1,7 @@
|
||||
import os, sys, platform
|
||||
|
||||
flist = "main.c"
|
||||
rfs_flist = "main.c server.c log.c deskutils.c"
|
||||
rfs_flist = "main.c server.c log.c deskutils.c rfs_transports.c"
|
||||
cdefs = "-DRFS_UDP_TRANSPORT -DRFS_INSIDE_MUX_MODE"
|
||||
socklib = ''
|
||||
ptlib = ''
|
||||
|
@ -145,7 +145,12 @@ static int parse_transport( const char* s )
|
||||
#define FIRST_SERVICE_IDX 3
|
||||
#define MIN_ARGC_COUNT 4
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strcasecmp _stricmp
|
||||
int main( int argc, char *argv[] )
|
||||
#else
|
||||
int main( int argc, char **argv )
|
||||
#endif
|
||||
{
|
||||
unsigned i;
|
||||
SERVICE_DATA *tservice;
|
||||
|
107
mux_src/mux.vcxproj
Normal file
107
mux_src/mux.vcxproj
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\rfs_server_src\deskutils.h" />
|
||||
<ClInclude Include="..\rfs_server_src\log.h" />
|
||||
<ClInclude Include="..\rfs_server_src\net.h" />
|
||||
<ClInclude Include="..\rfs_server_src\rfs.h" />
|
||||
<ClInclude Include="..\rfs_server_src\rfs_transports.h" />
|
||||
<ClInclude Include="..\rfs_server_src\serial.h" />
|
||||
<ClInclude Include="..\rfs_server_src\server.h" />
|
||||
<ClInclude Include="config.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\rfs_server_src\deskutils.c" />
|
||||
<ClCompile Include="..\rfs_server_src\log.c" />
|
||||
<ClCompile Include="..\rfs_server_src\net_win32.c" />
|
||||
<ClCompile Include="..\rfs_server_src\os_io_win32.c" />
|
||||
<ClCompile Include="..\rfs_server_src\rfs_transports.c" />
|
||||
<ClCompile Include="..\rfs_server_src\serial_win32.c" />
|
||||
<ClCompile Include="..\rfs_server_src\server.c" />
|
||||
<ClCompile Include="..\src\eluarpc.c" />
|
||||
<ClCompile Include="..\src\remotefs\remotefs.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{68EE7183-C1E2-41A9-AADA-3456B4773685}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>mux</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>..\rfs_server_src;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>..\rfs_server_src;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32_BUILD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32_BUILD;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
69
mux_src/mux.vcxproj.filters
Normal file
69
mux_src/mux.vcxproj.filters
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\rfs_server_src\deskutils.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rfs_server_src\server.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\eluarpc.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rfs_server_src\log.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rfs_server_src\net_win32.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rfs_server_src\os_io_win32.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\remotefs\remotefs.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rfs_server_src\rfs_transports.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\rfs_server_src\serial_win32.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="config.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\deskutils.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\log.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\net.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\rfs.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\rfs_transports.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\serial.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\rfs_server_src\server.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="source">
|
||||
<UniqueIdentifier>{edd07642-0c4f-4725-9e8f-641858b5e631}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="headers">
|
||||
<UniqueIdentifier>{7234826d-2dcc-404c-9472-998da14f1314}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -20,12 +20,12 @@ if utils.is_windows() then
|
||||
print "SIM target not supported under Windows"
|
||||
os.exit( 1 )
|
||||
end
|
||||
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c"
|
||||
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c rfs_transports.c"
|
||||
cdefs = cdefs .. " WIN32_BUILD"
|
||||
exeprefix = ".exe"
|
||||
socklib = 'ws2_32'
|
||||
else
|
||||
flist = mainname .. " server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c"
|
||||
flist = mainname .. " server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c rfs_transports.c"
|
||||
end
|
||||
|
||||
local output = sim == 0 and 'rfs_server' or 'rfs_sim_server'
|
||||
|
@ -13,12 +13,12 @@ if platform.system() == "Windows":
|
||||
if sim == '1':
|
||||
print "SIM target not supported under Windows"
|
||||
os.exit( 1 )
|
||||
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c"
|
||||
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c rfs_transports.c"
|
||||
cdefs = cdefs + " -DWIN32_BUILD"
|
||||
exeprefix = ".exe"
|
||||
socklib = '-lws2_32'
|
||||
else:
|
||||
flist = "%s server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c" % mainname
|
||||
flist = "%s server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c rfs_transports.c" % mainname
|
||||
exeprefix = ""
|
||||
|
||||
if sim == '0':
|
||||
|
@ -15,413 +15,7 @@
|
||||
#include <string.h>
|
||||
#include "rfs.h"
|
||||
#include "deskutils.h"
|
||||
|
||||
// ****************************************************************************
|
||||
// Local definitions
|
||||
|
||||
typedef void ( *p_read_request )( void );
|
||||
typedef void ( *p_send_response )( void );
|
||||
typedef void ( *p_cleanup )( void );
|
||||
typedef struct
|
||||
{
|
||||
p_read_request f_read_request;
|
||||
p_send_response f_send_response;
|
||||
p_cleanup f_cleanup;
|
||||
} RFS_TRANSPORT_DATA;
|
||||
|
||||
// ****************************************************************************
|
||||
// Local variables
|
||||
|
||||
#define MAX_PACKET_SIZE 4096
|
||||
static u8 rfs_buffer[ MAX_PACKET_SIZE + ELUARPC_WRITE_REQUEST_EXTRA ];
|
||||
static const RFS_TRANSPORT_DATA *p_transport_data;
|
||||
|
||||
// ****************************************************************************
|
||||
// Serial transport implementation
|
||||
|
||||
static ser_handler ser;
|
||||
|
||||
static void flush_serial()
|
||||
{
|
||||
// Flush all data in serial port
|
||||
while( ser_read_byte( ser, SER_NO_TIMEOUT ) != -1 );
|
||||
}
|
||||
|
||||
// Read a packet from the serial port
|
||||
static void ser_read_request_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
u32 readbytes;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// First read the length
|
||||
if( ( readbytes = ser_read( ser, rfs_buffer, ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != ELUARPC_START_OFFSET )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR reading packet length. Requested %d bytes, got %d bytes\n", ELUARPC_START_OFFSET, readbytes );
|
||||
flush_serial();
|
||||
continue;
|
||||
}
|
||||
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR getting packet size.\n" );
|
||||
flush_serial();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Then the rest of the data
|
||||
if( ( readbytes = ser_read( ser, rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != temp16 - ELUARPC_START_OFFSET )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR reading full packet, got %u bytes, expected %u bytes\n", ( unsigned )readbytes, ( unsigned )temp16 - ELUARPC_START_OFFSET );
|
||||
flush_serial();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a packet to the serial port
|
||||
static void ser_send_response_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
|
||||
// Send request
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
|
||||
ser_write( ser, rfs_buffer, temp16 );
|
||||
}
|
||||
}
|
||||
|
||||
static int ser_server_init( const char *portname, int serspeed, int flow )
|
||||
{
|
||||
// Setup serial port
|
||||
if( ( ser = ser_open( portname ) ) == SER_HANDLER_INVALID )
|
||||
{
|
||||
log_err( "Cannot open port %s\n", portname );
|
||||
return 0;
|
||||
}
|
||||
if( ser_setup( ser, ( u32 )serspeed, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1, flow ) != SER_OK )
|
||||
{
|
||||
log_err( "Unable to initialize serial port\n" );
|
||||
return 0;
|
||||
}
|
||||
flush_serial();
|
||||
|
||||
// User report
|
||||
log_msg( "Running RFS server on serial port %s (%u baud).\n", portname, ( unsigned )serspeed );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ser_cleanup()
|
||||
{
|
||||
ser_close( ser );
|
||||
}
|
||||
|
||||
static const RFS_TRANSPORT_DATA ser_transport_data = { ser_read_request_packet, ser_send_response_packet, ser_cleanup };
|
||||
|
||||
// ****************************************************************************
|
||||
// UDP transport implementation
|
||||
|
||||
static NET_SOCKET trans_socket = INVALID_SOCKET_VALUE;
|
||||
static struct sockaddr_in trans_from;
|
||||
|
||||
// Helper: read (blocking) the specified number of bytes
|
||||
|
||||
static void udp_read_helper( u8 *dest, u32 size )
|
||||
{
|
||||
socklen_t fromlen;
|
||||
int readbytes;
|
||||
|
||||
while( size )
|
||||
{
|
||||
fromlen = sizeof( trans_from );
|
||||
readbytes = net_recvfrom( trans_socket, ( char* )dest, size, 0, ( struct sockaddr* )&trans_from, &fromlen, NET_INF_TIMEOUT );
|
||||
size -= readbytes;
|
||||
if( size == 0 )
|
||||
break;
|
||||
dest += readbytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void udp_read_request_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// First read the length
|
||||
udp_read_helper( rfs_buffer, ELUARPC_START_OFFSET );
|
||||
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR getting packet size.\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Then the rest of the data
|
||||
udp_read_helper( rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void udp_send_response_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
|
||||
// Send request
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
|
||||
net_sendto( trans_socket, ( char* )rfs_buffer, temp16, 0, ( struct sockaddr* )&trans_from, sizeof( trans_from ) );
|
||||
}
|
||||
}
|
||||
|
||||
static int udp_server_init( unsigned server_port )
|
||||
{
|
||||
int length;
|
||||
struct sockaddr_in server;
|
||||
|
||||
if( ( trans_socket = net_create_socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET_VALUE )
|
||||
{
|
||||
log_err( "Unable to create socket\n" );
|
||||
return 1;
|
||||
}
|
||||
length = sizeof( server );
|
||||
memset( &server, 0, sizeof( server ) );
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons( server_port );
|
||||
if( bind( net_socket( trans_socket ), ( struct sockaddr * )&server, length ) < 0 )
|
||||
{
|
||||
log_err( "Unable to bind socket\n" );
|
||||
return 0;
|
||||
}
|
||||
log_msg( "Running RFS server on UDP port %u.\n", ( unsigned )server_port );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void udp_cleanup()
|
||||
{
|
||||
net_close( trans_socket );
|
||||
}
|
||||
|
||||
static const RFS_TRANSPORT_DATA udp_transport_data = { udp_read_request_packet, udp_send_response_packet, udp_cleanup };
|
||||
|
||||
// ****************************************************************************
|
||||
// Memory transport implementation
|
||||
|
||||
// Read state machine
|
||||
enum
|
||||
{
|
||||
MEM_STATE_READ_LENGTH,
|
||||
MEM_STATE_READ_REQUEST,
|
||||
MEM_STATE_REQUEST_DONE
|
||||
};
|
||||
|
||||
static int mem_read_len;
|
||||
static int mem_expected_len;
|
||||
static int mem_read_state;
|
||||
static int mem_response_flag;
|
||||
|
||||
void rfs_mem_start_request()
|
||||
{
|
||||
mem_read_state = MEM_STATE_READ_LENGTH;
|
||||
mem_read_len = mem_expected_len = 0;
|
||||
mem_response_flag = 0;
|
||||
}
|
||||
|
||||
int rfs_mem_read_request_packet( int c )
|
||||
{
|
||||
u16 temp16;
|
||||
int res = 1;
|
||||
|
||||
if( c == -1 )
|
||||
{
|
||||
rfs_mem_start_request();
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch( mem_read_state )
|
||||
{
|
||||
case MEM_STATE_READ_LENGTH:
|
||||
rfs_buffer[ mem_read_len ++ ] = c;
|
||||
if( mem_read_len == ELUARPC_START_OFFSET )
|
||||
{
|
||||
mem_read_len = 0;
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "RFS read_request_packet: ERROR getting packet size.\n" );
|
||||
mem_read_state = MEM_STATE_REQUEST_DONE;
|
||||
res = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_read_state = MEM_STATE_READ_REQUEST;
|
||||
mem_expected_len = temp16 - ELUARPC_START_OFFSET;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MEM_STATE_READ_REQUEST:
|
||||
rfs_buffer[ ELUARPC_START_OFFSET + mem_read_len ] = c;
|
||||
mem_read_len ++;
|
||||
if( mem_read_len == mem_expected_len )
|
||||
{
|
||||
mem_read_state = MEM_STATE_REQUEST_DONE;
|
||||
mem_response_flag = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int rfs_mem_has_response()
|
||||
{
|
||||
return mem_response_flag;
|
||||
}
|
||||
|
||||
void rfs_mem_write_response( u16 *plen, u8 **pdata )
|
||||
{
|
||||
// Execute request
|
||||
server_execute_request( rfs_buffer );
|
||||
|
||||
// Send response
|
||||
if( eluarpc_get_packet_size( rfs_buffer, plen ) != ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )*plen );
|
||||
*pdata = rfs_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_msg( "ERROR in send_response_packet!\n" );
|
||||
*plen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int mem_server_init()
|
||||
{
|
||||
rfs_mem_start_request();
|
||||
log_msg( "RFS: using memory transport.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const RFS_TRANSPORT_DATA mem_transport_data = { NULL, NULL, NULL };
|
||||
|
||||
// ****************************************************************************
|
||||
// Helper functions
|
||||
|
||||
// Transport parser
|
||||
static int parse_transport_and_init( const char* s )
|
||||
{
|
||||
const char *c, *c2;
|
||||
char *temps, *tempb;
|
||||
long tempi;
|
||||
int flow;
|
||||
|
||||
if( strstr( s, "ser:" ) == s )
|
||||
{
|
||||
p_transport_data = &ser_transport_data;
|
||||
s += strlen( "ser:" );
|
||||
if( ( c = strchr( s, ',' ) ) == NULL )
|
||||
{
|
||||
log_err( "Invalid serial transport syntax\n" );
|
||||
return 0;
|
||||
}
|
||||
temps = l_strndup( s, c - s );
|
||||
if( ( c2 = strchr( c + 1, ',' ) ) == NULL )
|
||||
{
|
||||
log_err( "Invalid serial transport syntax.\n" );
|
||||
return 0;
|
||||
}
|
||||
tempb = l_strndup( c + 1, c2 - c - 1 );
|
||||
if( secure_atoi( tempb, &tempi ) == 0 )
|
||||
{
|
||||
log_err( "Invalid port speed\n" );
|
||||
return 0;
|
||||
}
|
||||
free( tempb );
|
||||
if( !strcmp( c2 + 1, "none" ) )
|
||||
flow = SER_FLOW_NONE;
|
||||
else if( !strcmp( c2 + 1, "rtscts" ) )
|
||||
flow = SER_FLOW_RTSCTS;
|
||||
else
|
||||
{
|
||||
log_err( "Invalid flow control type.\n" );
|
||||
return 0;
|
||||
}
|
||||
tempi = ser_server_init( temps, tempi, flow );
|
||||
free( temps );
|
||||
return tempi;
|
||||
}
|
||||
else if( strstr( s, "udp:" ) == s )
|
||||
{
|
||||
p_transport_data = &udp_transport_data;
|
||||
s += strlen( "udp:" );
|
||||
if( secure_atoi( s, &tempi ) == 0 )
|
||||
{
|
||||
log_err( "Invalid port number\n" );
|
||||
return 0;
|
||||
}
|
||||
if( net_init() == 0 )
|
||||
{
|
||||
log_err( "Unable to initialize network\n" );
|
||||
return 0;
|
||||
}
|
||||
return udp_server_init( tempi );
|
||||
}
|
||||
else if( !strcmp( s, "mem" ) )
|
||||
{
|
||||
// Direct memory transport, only used with mux in rfsmux mode
|
||||
p_transport_data = &mem_transport_data;
|
||||
return mem_server_init( tempi );
|
||||
}
|
||||
log_err( "Error: unsupported transport\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Entry point
|
||||
|
||||
#define TRANSPORT_ARG_IDX 1
|
||||
#define DIRNAME_ARG_IDX 2
|
||||
#define VERBOSE_ARG_IDX 3
|
||||
#define MIN_ARGC_COUNT 3
|
||||
#define VERBOSE_ARGC_COUNT 4
|
||||
|
||||
int rfs_init( int argc, const char **argv )
|
||||
{
|
||||
setvbuf( stdout, NULL, _IONBF, 0 );
|
||||
if( argc < MIN_ARGC_COUNT )
|
||||
{
|
||||
log_err( "Usage: %s <transport> <dirname> [-v]\n", argv[ 0 ] );
|
||||
log_err( " Serial transport: 'ser:<sername>,<serspeed>,<flow> ('flow' defines the flow control and can be either 'none' or 'rtscts')\n" );
|
||||
log_err( " UDP transport: 'udp:<port>'\n" );
|
||||
log_err( "Use -v for verbose output.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( ( argc >= VERBOSE_ARGC_COUNT ) && !strcmp( argv[ VERBOSE_ARG_IDX ], "-v" ) )
|
||||
log_init( LOG_ALL );
|
||||
else
|
||||
log_init( LOG_NONE );
|
||||
|
||||
if( !os_isdir( argv[ DIRNAME_ARG_IDX ] ) )
|
||||
{
|
||||
log_err( "Invalid directory %s\n", argv[ DIRNAME_ARG_IDX ] );
|
||||
return 1;
|
||||
}
|
||||
if( parse_transport_and_init( argv[ TRANSPORT_ARG_IDX ] ) == 0 )
|
||||
return 1;
|
||||
|
||||
// Setup RFS server
|
||||
server_setup( argv[ DIRNAME_ARG_IDX ] );
|
||||
log_msg( "Sharing directory %s\n", argv[ DIRNAME_ARG_IDX ] );
|
||||
return 0;
|
||||
}
|
||||
#include "rfs_transports.h"
|
||||
|
||||
#ifdef RFS_STANDALONE_MODE
|
||||
int main( int argc, const char **argv )
|
||||
|
105
rfs_server_src/rfs_server.vcxproj
Normal file
105
rfs_server_src/rfs_server.vcxproj
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\eluarpc.c" />
|
||||
<ClCompile Include="..\src\remotefs\remotefs.c" />
|
||||
<ClCompile Include="deskutils.c" />
|
||||
<ClCompile Include="log.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="net_win32.c" />
|
||||
<ClCompile Include="os_io_win32.c" />
|
||||
<ClCompile Include="rfs_transports.c" />
|
||||
<ClCompile Include="serial_win32.c" />
|
||||
<ClCompile Include="server.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="deskutils.h" />
|
||||
<ClInclude Include="log.h" />
|
||||
<ClInclude Include="net.h" />
|
||||
<ClInclude Include="rfs.h" />
|
||||
<ClInclude Include="rfs_transports.h" />
|
||||
<ClInclude Include="serial.h" />
|
||||
<ClInclude Include="server.h" />
|
||||
<ClInclude Include="type.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4A3A33C6-6A0C-4C82-8C07-A6896BAFB4FA}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>rfs_server</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>.\;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>.\;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>RFS_STANDALONE_MODE;WIN32_BUILD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>RFS_STANDALONE_MODE;WIN32_BUILD;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
69
rfs_server_src/rfs_server.vcxproj.filters
Normal file
69
rfs_server_src/rfs_server.vcxproj.filters
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="server.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="deskutils.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\eluarpc.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="log.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="net_win32.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="os_io_win32.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\remotefs\remotefs.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rfs_transports.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="serial_win32.c">
|
||||
<Filter>source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="deskutils.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rfs_transports.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="serial.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="server.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="type.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="net.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rfs.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="log.h">
|
||||
<Filter>headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="headers">
|
||||
<UniqueIdentifier>{337cdfd6-7a94-45a7-9773-202c632d5000}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="source">
|
||||
<UniqueIdentifier>{ed41819a-7341-42c2-b1ee-525a54aeeee1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
413
rfs_server_src/rfs_transports.c
Normal file
413
rfs_server_src/rfs_transports.c
Normal file
@ -0,0 +1,413 @@
|
||||
// Remote FS server
|
||||
|
||||
#include "net.h"
|
||||
#include "remotefs.h"
|
||||
#include "eluarpc.h"
|
||||
#include "serial.h"
|
||||
#include "server.h"
|
||||
#include "type.h"
|
||||
#include "log.h"
|
||||
#include "os_io.h"
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rfs.h"
|
||||
#include "deskutils.h"
|
||||
#include "rfs_transports.h"
|
||||
|
||||
// ****************************************************************************
|
||||
// Local variables
|
||||
|
||||
|
||||
u8 rfs_buffer[ MAX_PACKET_SIZE + ELUARPC_WRITE_REQUEST_EXTRA ];
|
||||
const RFS_TRANSPORT_DATA *p_transport_data;
|
||||
|
||||
// ****************************************************************************
|
||||
// Serial transport implementation
|
||||
|
||||
static ser_handler ser;
|
||||
|
||||
static void flush_serial()
|
||||
{
|
||||
// Flush all data in serial port
|
||||
while( ser_read_byte( ser, SER_NO_TIMEOUT ) != -1 );
|
||||
}
|
||||
|
||||
// Read a packet from the serial port
|
||||
static void ser_read_request_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
u32 readbytes;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// First read the length
|
||||
if( ( readbytes = ser_read( ser, rfs_buffer, ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != ELUARPC_START_OFFSET )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR reading packet length. Requested %d bytes, got %d bytes\n", ELUARPC_START_OFFSET, readbytes );
|
||||
flush_serial();
|
||||
continue;
|
||||
}
|
||||
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR getting packet size.\n" );
|
||||
flush_serial();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Then the rest of the data
|
||||
if( ( readbytes = ser_read( ser, rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != temp16 - ELUARPC_START_OFFSET )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR reading full packet, got %u bytes, expected %u bytes\n", ( unsigned )readbytes, ( unsigned )temp16 - ELUARPC_START_OFFSET );
|
||||
flush_serial();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a packet to the serial port
|
||||
static void ser_send_response_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
|
||||
// Send request
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
|
||||
ser_write( ser, rfs_buffer, temp16 );
|
||||
}
|
||||
}
|
||||
|
||||
static int ser_server_init( const char *portname, int serspeed, int flow )
|
||||
{
|
||||
// Setup serial port
|
||||
if( ( ser = ser_open( portname ) ) == SER_HANDLER_INVALID )
|
||||
{
|
||||
log_err( "Cannot open port %s\n", portname );
|
||||
return 0;
|
||||
}
|
||||
if( ser_setup( ser, ( u32 )serspeed, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1, flow ) != SER_OK )
|
||||
{
|
||||
log_err( "Unable to initialize serial port\n" );
|
||||
return 0;
|
||||
}
|
||||
flush_serial();
|
||||
|
||||
// User report
|
||||
log_msg( "Running RFS server on serial port %s (%u baud).\n", portname, ( unsigned )serspeed );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ser_cleanup()
|
||||
{
|
||||
ser_close( ser );
|
||||
}
|
||||
|
||||
const RFS_TRANSPORT_DATA ser_transport_data = { ser_read_request_packet, ser_send_response_packet, ser_cleanup };
|
||||
|
||||
// ****************************************************************************
|
||||
// UDP transport implementation
|
||||
|
||||
static NET_SOCKET trans_socket = INVALID_SOCKET_VALUE;
|
||||
static struct sockaddr_in trans_from;
|
||||
|
||||
// Helper: read (blocking) the specified number of bytes
|
||||
|
||||
static void udp_read_helper( u8 *dest, u32 size )
|
||||
{
|
||||
socklen_t fromlen;
|
||||
int readbytes;
|
||||
|
||||
while( size )
|
||||
{
|
||||
fromlen = sizeof( trans_from );
|
||||
readbytes = net_recvfrom( trans_socket, ( char* )dest, size, 0, ( struct sockaddr* )&trans_from, &fromlen, NET_INF_TIMEOUT );
|
||||
size -= readbytes;
|
||||
if( size == 0 )
|
||||
break;
|
||||
dest += readbytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void udp_read_request_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// First read the length
|
||||
udp_read_helper( rfs_buffer, ELUARPC_START_OFFSET );
|
||||
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "read_request_packet: ERROR getting packet size.\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Then the rest of the data
|
||||
udp_read_helper( rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void udp_send_response_packet()
|
||||
{
|
||||
u16 temp16;
|
||||
|
||||
// Send request
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
|
||||
net_sendto( trans_socket, ( char* )rfs_buffer, temp16, 0, ( struct sockaddr* )&trans_from, sizeof( trans_from ) );
|
||||
}
|
||||
}
|
||||
|
||||
static int udp_server_init( unsigned server_port )
|
||||
{
|
||||
int length;
|
||||
struct sockaddr_in server;
|
||||
|
||||
if( ( trans_socket = net_create_socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET_VALUE )
|
||||
{
|
||||
log_err( "Unable to create socket\n" );
|
||||
return 1;
|
||||
}
|
||||
length = sizeof( server );
|
||||
memset( &server, 0, sizeof( server ) );
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons( server_port );
|
||||
if( bind( net_socket( trans_socket ), ( struct sockaddr * )&server, length ) < 0 )
|
||||
{
|
||||
log_err( "Unable to bind socket\n" );
|
||||
return 0;
|
||||
}
|
||||
log_msg( "Running RFS server on UDP port %u.\n", ( unsigned )server_port );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void udp_cleanup()
|
||||
{
|
||||
net_close( trans_socket );
|
||||
}
|
||||
|
||||
const RFS_TRANSPORT_DATA udp_transport_data = { udp_read_request_packet, udp_send_response_packet, udp_cleanup };
|
||||
|
||||
// ****************************************************************************
|
||||
// Memory transport implementation
|
||||
|
||||
// Read state machine
|
||||
enum
|
||||
{
|
||||
MEM_STATE_READ_LENGTH,
|
||||
MEM_STATE_READ_REQUEST,
|
||||
MEM_STATE_REQUEST_DONE
|
||||
};
|
||||
|
||||
static int mem_read_len;
|
||||
static int mem_expected_len;
|
||||
static int mem_read_state;
|
||||
static int mem_response_flag;
|
||||
|
||||
void rfs_mem_start_request()
|
||||
{
|
||||
mem_read_state = MEM_STATE_READ_LENGTH;
|
||||
mem_read_len = mem_expected_len = 0;
|
||||
mem_response_flag = 0;
|
||||
}
|
||||
|
||||
int rfs_mem_read_request_packet( int c )
|
||||
{
|
||||
u16 temp16;
|
||||
int res = 1;
|
||||
|
||||
if( c == -1 )
|
||||
{
|
||||
rfs_mem_start_request();
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch( mem_read_state )
|
||||
{
|
||||
case MEM_STATE_READ_LENGTH:
|
||||
rfs_buffer[ mem_read_len ++ ] = c;
|
||||
if( mem_read_len == ELUARPC_START_OFFSET )
|
||||
{
|
||||
mem_read_len = 0;
|
||||
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "RFS read_request_packet: ERROR getting packet size.\n" );
|
||||
mem_read_state = MEM_STATE_REQUEST_DONE;
|
||||
res = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_read_state = MEM_STATE_READ_REQUEST;
|
||||
mem_expected_len = temp16 - ELUARPC_START_OFFSET;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MEM_STATE_READ_REQUEST:
|
||||
rfs_buffer[ ELUARPC_START_OFFSET + mem_read_len ] = c;
|
||||
mem_read_len ++;
|
||||
if( mem_read_len == mem_expected_len )
|
||||
{
|
||||
mem_read_state = MEM_STATE_REQUEST_DONE;
|
||||
mem_response_flag = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int rfs_mem_has_response()
|
||||
{
|
||||
return mem_response_flag;
|
||||
}
|
||||
|
||||
void rfs_mem_write_response( u16 *plen, u8 **pdata )
|
||||
{
|
||||
// Execute request
|
||||
server_execute_request( rfs_buffer );
|
||||
|
||||
// Send response
|
||||
if( eluarpc_get_packet_size( rfs_buffer, plen ) != ELUARPC_ERR )
|
||||
{
|
||||
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )*plen );
|
||||
*pdata = rfs_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_msg( "ERROR in send_response_packet!\n" );
|
||||
*plen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int mem_server_init()
|
||||
{
|
||||
rfs_mem_start_request();
|
||||
log_msg( "RFS: using memory transport.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
const RFS_TRANSPORT_DATA mem_transport_data = { NULL, NULL, NULL };
|
||||
|
||||
// ****************************************************************************
|
||||
// Helper functions
|
||||
|
||||
// Transport parser
|
||||
static int parse_transport_and_init( const char* s )
|
||||
{
|
||||
const char *c, *c2;
|
||||
char *temps, *tempb;
|
||||
long tempi = 0;
|
||||
int flow;
|
||||
|
||||
if( strstr( s, "ser:" ) == s )
|
||||
{
|
||||
p_transport_data = &ser_transport_data;
|
||||
s += strlen( "ser:" );
|
||||
if( ( c = strchr( s, ',' ) ) == NULL )
|
||||
{
|
||||
log_err( "Invalid serial transport syntax\n" );
|
||||
return 0;
|
||||
}
|
||||
temps = l_strndup( s, c - s );
|
||||
if( ( c2 = strchr( c + 1, ',' ) ) == NULL )
|
||||
{
|
||||
log_err( "Invalid serial transport syntax.\n" );
|
||||
return 0;
|
||||
}
|
||||
tempb = l_strndup( c + 1, c2 - c - 1 );
|
||||
if( secure_atoi( tempb, &tempi ) == 0 )
|
||||
{
|
||||
log_err( "Invalid port speed\n" );
|
||||
return 0;
|
||||
}
|
||||
free( tempb );
|
||||
if( !strcmp( c2 + 1, "none" ) )
|
||||
flow = SER_FLOW_NONE;
|
||||
else if( !strcmp( c2 + 1, "rtscts" ) )
|
||||
flow = SER_FLOW_RTSCTS;
|
||||
else
|
||||
{
|
||||
log_err( "Invalid flow control type.\n" );
|
||||
return 0;
|
||||
}
|
||||
tempi = ser_server_init( temps, tempi, flow );
|
||||
free( temps );
|
||||
return tempi;
|
||||
}
|
||||
else if( strstr( s, "udp:" ) == s )
|
||||
{
|
||||
p_transport_data = &udp_transport_data;
|
||||
s += strlen( "udp:" );
|
||||
if( secure_atoi( s, &tempi ) == 0 )
|
||||
{
|
||||
log_err( "Invalid port number\n" );
|
||||
return 0;
|
||||
}
|
||||
if( net_init() == 0 )
|
||||
{
|
||||
log_err( "Unable to initialize network\n" );
|
||||
return 0;
|
||||
}
|
||||
return udp_server_init( tempi );
|
||||
}
|
||||
else if( !strcmp( s, "mem" ) )
|
||||
{
|
||||
// Direct memory transport, only used with mux in rfsmux mode
|
||||
p_transport_data = &mem_transport_data;
|
||||
return mem_server_init( tempi );
|
||||
}
|
||||
log_err( "Error: unsupported transport\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Entry point
|
||||
|
||||
#define TRANSPORT_ARG_IDX 1
|
||||
#define DIRNAME_ARG_IDX 2
|
||||
#define VERBOSE_ARG_IDX 3
|
||||
#define MIN_ARGC_COUNT 3
|
||||
#define VERBOSE_ARGC_COUNT 4
|
||||
|
||||
int rfs_init( int argc, const char **argv )
|
||||
{
|
||||
setvbuf( stdout, NULL, _IONBF, 0 );
|
||||
if( argc < MIN_ARGC_COUNT )
|
||||
{
|
||||
log_err( "Usage: %s <transport> <dirname> [-v]\n", argv[ 0 ] );
|
||||
log_err( " Serial transport: 'ser:<sername>,<serspeed>,<flow> ('flow' defines the flow control and can be either 'none' or 'rtscts')\n" );
|
||||
log_err( " UDP transport: 'udp:<port>'\n" );
|
||||
log_err( "Use -v for verbose output.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( ( argc >= VERBOSE_ARGC_COUNT ) && !strcmp( argv[ VERBOSE_ARG_IDX ], "-v" ) )
|
||||
log_init( LOG_ALL );
|
||||
else
|
||||
log_init( LOG_NONE );
|
||||
|
||||
if( !os_isdir( argv[ DIRNAME_ARG_IDX ] ) )
|
||||
{
|
||||
log_err( "Invalid directory %s\n", argv[ DIRNAME_ARG_IDX ] );
|
||||
return 1;
|
||||
}
|
||||
if( parse_transport_and_init( argv[ TRANSPORT_ARG_IDX ] ) == 0 )
|
||||
return 1;
|
||||
|
||||
// Setup RFS server
|
||||
server_setup( argv[ DIRNAME_ARG_IDX ] );
|
||||
log_msg( "Sharing directory %s\n", argv[ DIRNAME_ARG_IDX ] );
|
||||
return 0;
|
||||
}
|
||||
|
22
rfs_server_src/rfs_transports.h
Normal file
22
rfs_server_src/rfs_transports.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef _RFS_TRANSPORTS_H
|
||||
#define _RFS_TRANSPORTS_H
|
||||
|
||||
typedef void ( *p_read_request )( void );
|
||||
typedef void ( *p_send_response )( void );
|
||||
typedef void ( *p_cleanup )( void );
|
||||
typedef struct
|
||||
{
|
||||
p_read_request f_read_request;
|
||||
p_send_response f_send_response;
|
||||
p_cleanup f_cleanup;
|
||||
} RFS_TRANSPORT_DATA;
|
||||
|
||||
#define MAX_PACKET_SIZE 4096
|
||||
|
||||
extern const RFS_TRANSPORT_DATA *p_transport_data;
|
||||
extern const RFS_TRANSPORT_DATA mem_transport_data;
|
||||
extern const RFS_TRANSPORT_DATA udp_transport_data;
|
||||
extern const RFS_TRANSPORT_DATA ser_transport_data;
|
||||
extern u8 rfs_buffer[ MAX_PACKET_SIZE + ELUARPC_WRITE_REQUEST_EXTRA ];
|
||||
|
||||
#endif
|
@ -232,7 +232,7 @@ u32 ser_write_byte( ser_handler id, u8 data )
|
||||
int ser_select_byte( ser_handler *pobjects, unsigned nobjects, int timeout )
|
||||
{
|
||||
int i;
|
||||
DWORD readbytes;
|
||||
DWORD readbytes, dwRes;
|
||||
int res = -1;
|
||||
unsigned num_wait = 0;
|
||||
ser_handler hnd;
|
||||
@ -259,7 +259,7 @@ int ser_select_byte( ser_handler *pobjects, unsigned nobjects, int timeout )
|
||||
if( num_wait == 0 )
|
||||
return -1;
|
||||
|
||||
DWORD dwRes = WaitForMultipleObjects( num_wait, sel_handlers, FALSE, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
|
||||
dwRes = WaitForMultipleObjects( num_wait, sel_handlers, FALSE, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
|
||||
if( dwRes >= WAIT_OBJECT_0 && dwRes < WAIT_OBJECT_0 + num_wait )
|
||||
{
|
||||
i = dwRes - WAIT_OBJECT_0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user