1
0
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:
Peter Edwards 2011-05-07 23:56:12 +03:00 committed by Bogdan Marinescu
commit d717fc44db
14 changed files with 801 additions and 415 deletions

2
.gitignore vendored
View File

@ -11,4 +11,6 @@ inc/romfiles.h
.sconf_temp/
.sconsign.dblite
config.log
mux
rfs_server

View File

@ -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
View File

@ -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 = ''

View File

@ -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
View 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>

View 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>

View File

@ -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'

View File

@ -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':

View File

@ -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 )

View 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>

View 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>

View 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;
}

View 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

View File

@ -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;