colorchord/embedded8266/web/pushtodev.c

237 lines
5 KiB
C

//Unless what else is individually marked, all code in this file is
//Copyright 2015 <>< Charles Lohr Under the MIT/x11 License, NewBSD License or
// ColorChord License. You Choose.
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define sector_SIZE 4096
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0x0 //Don't request NOSIGNAL on systems where this is not implemented.
#endif
int sockfd;
char recvline[10000];
int PushMatch( const char * match )
{
struct timeval tva, tvb;
gettimeofday( &tva, 0 );
gettimeofday( &tvb, 0 );
while( tvb.tv_sec - tva.tv_sec < 3 ) //3 second timeout.
{
struct pollfd ufds;
ufds.fd = sockfd;
ufds.events = POLLIN;
int rv = poll(&ufds, 1, 500);
if( rv > 0 )
{
// tbuf = recvline;
int n=recvfrom(sockfd,recvline,10000,0,NULL,NULL);
// printf( "!!%d ->%s\n", n,recvline );
// printf( "%s === %s\n", recvline, match );
if( strncmp( recvline, match, strlen( match ) ) == 0 )
{
// printf( "Ok\n" ); fflush( stdout );
return 0;
}
}
gettimeofday( &tvb, 0 );
}
return 1;
}
int main(int argc, char**argv)
{
int n;
struct sockaddr_in servaddr,cliaddr;
char sendline[1000];
// char recvline[1000];
if (argc != 4)
{
printf("usage: pushtodev [IP address] [address offset] [file]\n");
exit(-1);
}
int offset = atoi( argv[2] );
const char * file = argv[3];
if( offset <= 0 )
{
fprintf( stderr, "Error: Cannot write to address 0 or before.\n" );
exit(-2);
}
FILE * f = fopen( file, "rb" );
if( !f || feof( f ) )
{
fprintf( stderr, "Error: cannot open file.\n" );
exit(-3);
}
sockfd=socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr(argv[1]);
servaddr.sin_port=htons(7878);
int devo = 0;
int lastsector_block = -1;
int resend_times = 0;
int r;
while( !feof( f ) )
{
int tries;
int thissuccess;
char buffer[1024];
char bufferout[1600];
int reads = fread( buffer, 1, 1024, f );
int sendplace = offset + devo;
int sendsize = reads;
#ifdef SECTOR
int sector = sendplace / sector_SIZE;
if( sector != lastsector_block )
{
char se[64];
int sel = sprintf( se, "FE%d\r\n", sector );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
printf( "Erase: %d\n", sector );
sendto( sockfd, se, sel, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FE%d", sector );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
lastsector_block = sector;
}
#else //block
int block = sendplace / 65536;
if( block != lastsector_block )
{
char se[64];
int sel = sprintf( se, "FB%d\r\n", block );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
printf( "Erase: %d\n", block );
sendto( sockfd, se, sel, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FB%d", block );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
lastsector_block = block;
}
#endif
resend_times = 0;
resend:
r = sprintf( bufferout, "FW%d\t%d\t", sendplace, sendsize );
printf( "bufferout: %d %d %s\n", sendplace, sendsize, bufferout );
memcpy( bufferout + r, buffer, sendsize );
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[75];
sendto( sockfd, bufferout, reads + r, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
sprintf( match, "FW%d", sendplace );
if( PushMatch(match) == 0 ) { thissuccess = 1; break; }
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Timeout in communications.\n" );
exit( -6 );
}
/*
printf( "Verifying..." );
fflush( stdout );
int r = sprintf( bufferout, "FR%d:%d", sendplace, sendsize );
bufferout[r] = 0;
thissuccess = 0;
for( tries = 0; tries < 10; tries++ )
{
char match[1600];
sendto( sockfd, bufferout, r, MSG_NOSIGNAL, (struct sockaddr *)&servaddr,sizeof(servaddr));
devo += reads;
sprintf( match, "FR%08d", sendplace );
if( PushMatch(match) == 0 ) {
//Check data...
//printf( "RR:%s\n", recvline );
char * colon1 = strchr( recvline, ':' );
char * colon2 = (colon1)?strchr( colon1+1, ':' ):0;
//printf( "::%p %p \"%s\"\n", colon1, colon2,recvline );
if( colon2 )
{
if( memcmp( colon2+1, buffer, sendsize ) == 0 )
thissuccess = 1;
}
if( !thissuccess )
{
if( resend_times > 2 )
{
break;
}
resend_times++;
goto resend;
}
break;
}
printf( "Retry.\n" );
}
if( !thissuccess )
{
fprintf( stderr, "Error: Fault verifying.\n" );
exit( -6 );
}
*/
devo += reads;
}
return 0;
}