I've attached a zipped up minimal example at the bottom. Any ideas?
edit: I'm running this on a MOD54417 with NNDK 2.7.0
main.cpp
Code: Select all
#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <dhcpclient.h>
#include "netinterface.h"
#include "websockets.h"
#include "ftpd.h"
#include <effs_fat/fat.h>
#include "FileSystemUtils.h"
#if ( defined(USE_MMC) && defined(MOD5441X) )
#define MULTI_MMC TRUE // For modules with onboard flash sockets, even if you are using external flash cards
#include <effs_fat/multi_drive_mmc_mcf.h>
#elif ( defined(USE_MMC) )
#include <effs_fat/mmc_mcf.h>
#elif ( defined(USE_CFC) )
#include <effs_fat/cfc_mcf.h>
#endif
extern "C" {
void UserMain(void * pd);
}
const char * AppName="SimpleWebSocketTest";
extern http_wshandler *TheWSHandler;
int GlobalWebSocket = 0;
OS_SEM UploadSocketReady;
int MyDoWSUpgrade( HTTP_Request *req, int sock, PSTR url, PSTR rxb )
{
if(httpstricmp(url, "WEBSOCKETUPLOAD"))
{
int webSocket = WSUpgrade( req, sock );
if (webSocket >= 0)
{
iprintf("\r\nSocket connection received");
GlobalWebSocket = webSocket;
OSSemPost(&UploadSocketReady);
//handler now has ownership of socket
return 2;
}
else
{
iprintf("\r\nUnable to open web socket.\r\n");
return 0;
}
}
iprintf("\r\nWebSocket URL '%s' not found.\r\n", url);
NotFoundResponse( sock, url );
return 0;
}
void UploadTask(void *ptr)
{
//create buffer to read raw data into before writing to file
int myBufferSize = 250;
char myBuffer[myBufferSize];
//to signal the end of the file transfer i just use a timeout
int uploadTimeout = TICKS_PER_SECOND * 5;
F_FILE *uploadFile;
while(1)
{
iprintf("\r\nWaiting for upload socket...");
OSSemPend(&UploadSocketReady,0);
//grab the global websocket and store it for local use
int thisWebSocket = GlobalWebSocket;
f_chdrive(EXT_FLASH_DRV_NUM);
f_chdir( "/" );
uploadFile = f_open( "upload.txt", "w" ); // Open it for write
if(!uploadFile)
{
iprintf("\r\nFailed to open file for writing");
close(thisWebSocket);
thisWebSocket = 0;
continue;
}
iprintf("\r\n...Upload socket acquired.\r\nBegin transmission: \r\n");
fd_set read_fds;
fd_set error_fds;
while(thisWebSocket)
{
FD_ZERO( &read_fds );
FD_ZERO( &error_fds );
FD_SET(thisWebSocket, &read_fds);
FD_SET(thisWebSocket, &error_fds);
//wait for data on the web socket
if(select(FD_SETSIZE, &read_fds, NULL, &error_fds, uploadTimeout))
{
if(FD_ISSET(thisWebSocket, &read_fds))
{
int n;
//read data from the fd until none is left
do
{
//read as much as will fit into our buffer
n = read( thisWebSocket, myBuffer, myBufferSize );
if(n > 0)
{
int bytesWritten = 0;
int RetryAttempts = 0;
//try 3 times to write the data to the file
while(bytesWritten < n && ( RetryAttempts++ < 3 ))
{
if(RetryAttempts > 1)
OSTimeDly(TICKS_PER_SECOND / 4);//pause a moment if we weren't able to write everything
//DEBUG: display out the serial port so we can see the raw data we received
//write(0, (char *) (myBuffer + bytesWritten), n-bytesWritten);
//write the bytes to the file
bytesWritten += f_write( myBuffer + bytesWritten, 1, n-bytesWritten, uploadFile );
}
if(RetryAttempts >= 3)
{
iprintf("\r\nFailed to write bytes to file");
}
}
}while(n > 0);//keep reading until no data is left on the socket
}
if(FD_ISSET(thisWebSocket, &error_fds))
{
//socket error
iprintf("\r\nError on socket.\r\n");
close(thisWebSocket);
f_close(uploadFile);
thisWebSocket = 0;
}
}
else
{
//timed out
iprintf("\r\nUpload complete");
close(thisWebSocket);
f_close(uploadFile);
thisWebSocket = 0;
}
}
}
}
#define FTP_PRIO 58
#define UPLOAD_PRIO 59
#define MY_MAIN_PRIO 60
void UserMain(void * pd)
{
InitializeStack();
if (EthernetIP == 0) GetDHCPAddress();
OSChangePrio(MAIN_PRIO);
EnableAutoUpdate();
StartHTTP();
OSSemInit(&UploadSocketReady, 0);
//display links for the web page and ftp
iprintf("\r\nGo to:\r\nhttp://");
ShowIP(EthernetIP);
iprintf("\r\n");
iprintf("\r\nYou can download the file 'Upload.txt' from:\r\nftp://");
ShowIP(EthernetIP);
iprintf("\r\n\r\n");
// We have to enter the file system for each task
OSChangePrio( FTP_PRIO );
f_enterFS();
OSChangePrio( UPLOAD_PRIO );
f_enterFS();
OSChangePrio( MY_MAIN_PRIO );
f_enterFS();
InitExtFlash(); // Initialize the CFC or SD/MMC external flash drive
FTPDStart( 21, FTP_PRIO);
TheWSHandler = MyDoWSUpgrade;
OSSimpleTaskCreatewName(UploadTask,UPLOAD_PRIO,"UploadTask");
iprintf("\r\nApplication started");
while (1) {
OSTimeDly(20);
}
}
Code: Select all
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
//create a web socket variable
var ws;
function uploadFile()
{
//get the file
var file = document.getElementById('filename').files[0];
//make a reader for the file
var reader = new FileReader();
//create an array buffer view to use on the file
var rawData = new ArrayBuffer();
reader.loadend = function()
{
}
reader.onload = function(e)
{
//once the file has been read, set the array buffer view on it
rawData = e.target.result;
//send the data
ws.send(rawData);
console.log("File sent");
alert("the File has been transferred.");
}
//trigger the reading of the file
reader.readAsArrayBuffer(file);
}
function sendFile()
{
connectChatServer();
}
function connectChatServer()
{
//create web socket
var webSocketAddress = "ws://" + window.location.hostname + "/WEBSOCKETUPLOAD";
ws = new WebSocket(webSocketAddress);
//we will send the file as an array buffer
ws.binaryType = "arraybuffer";
ws.onopen = function()
{
//once we connect, send the file
console.log("Connected.");
uploadFile();
};
ws.onmessage = function(evt)
{
console.log(evt.msg);
};
ws.onclose = function()
{
console.log("Connection is closed...");
};
ws.onerror = function(e)
{
console.log(e.msg);
}
}
</script>
Select file and click upload. It will be stored on the SD card root directory under the name Upload.txt
<br>
<input type="file" id="filename" />
<br>
<input type="button" value="Upload" onclick="sendFile()" />
</body>
</html>