diff --git a/README.md b/README.md
index 6f35202..78459f7 100644
--- a/README.md
+++ b/README.md
@@ -14,17 +14,17 @@ This repository contains the entire open-source firmware for the Zodiac FX inclu
The latest firmware is available in the [Northbound Networks Forums](http://forums.northboundnetworks.com/index.php?topic=52.0).
-Starting from version 0.80, Zodiac FX supports firmware updates via the CLI and web interface. In order to make this possible, major changes were made to the firmware flashing process. Follow the update process below, based on your current firmware version.
+Starting from version 0.81, Zodiac FX supports firmware updates via the CLI and web interface. In order to make this possible, major changes were made to the firmware flashing process. Follow the update process below, based on your current firmware version.
-#### For firmware versions BEFORE version 0.80
+#### For firmware versions BEFORE version 0.81
-To update to version 0.80 or later, a **full upgrade firmware** needs to be flashed.
+To update to version 0.81 or later, a **full upgrade firmware** needs to be flashed.
Download the latest **full upgrade firmware** from the [Northbound Networks Forums](http://forums.northboundnetworks.com/index.php?topic=52.0) - 'Full Upgrade Firmware (v0.XX) - ZodiacFX_vXX_full_install.bin'
Follow the firmware update process detailed in **Section 2. Updating Firmware** in the [Zodiac FX User Guide](http://forums.northboundnetworks.com/downloads/zodiac_fx/guides/ZodiacFX_UserGuide_0317.pdf).
-#### For firmware versions AFTER version 0.80
+#### For firmware versions AFTER version 0.81
The update process has been simplified for the newer releases.
@@ -83,7 +83,7 @@ The Zodiac FX uses a simple additive checksum to verify the integrity of the upl
To sign your own modified firmware, follow the steps below:
* Build a 'Release' binary of the modified firmware
* Update the Zodiac FX with the modified firmware
- * Follow the instructions outlined in Flashing/Updating the Firmware - For firmware versions AFTER version 0.80
+ * Follow the instructions outlined in Flashing/Updating the Firmware - For firmware versions AFTER version 0.81
* The firmware will fail the verification check, but will still be stored inside the Zodiac FX flash memory
* In the root context of the CLI, type in the hidden command 'get crc'
* Open the ZodiacFX.bin file in a hex editor, and append the 8 bytes to the end of the firmware file
@@ -99,6 +99,12 @@ Issues can also be [raised](https://github.com/NorthboundNetworks/ZodiacFX/issue
## Release Notes
+**Version 0.81**
+* Firmware upload fixes (full upgrade required)
+* Metering bug-fixes & updates (initial DSCP remark support)
+* Port stat output bug-fixes
+* Web interface improvements
+
**Version 0.80**
* Firmware upload via CLI and web interface added
* Metering added to OpenFlow 1.3
diff --git a/ZodiacFX/ZodiacFX.cproj b/ZodiacFX/ZodiacFX.cproj
index e3e4036..bb1eeff 100644
--- a/ZodiacFX/ZodiacFX.cproj
+++ b/ZodiacFX/ZodiacFX.cproj
@@ -274,11 +274,11 @@
JTAG
com.atmel.avrdbg.tool.atmelice
- J41800058832
+ J41800009874
Atmel-ICE
JTAG
- J41800058832
+ J41800009874
0xA3CC0CE0
7500000
@@ -368,7 +368,7 @@
True
- -Wl,--defsym,__stack_size__=0x1400 -Wl,--entry=Reset_Handler -Wl,-section-start=.text=0x00420000 -Wl,--cref -mthumb -T../src/ASF/sam/utils/linker_scripts/sam4e/sam4e8/gcc/flash.ld
+ -Wl,--defsym,__stack_size__=0x1400 -Wl,--entry=Reset_Handler -Wl,-section-start=.text=0x00410000 -Wl,--cref -mthumb -T../src/ASF/sam/utils/linker_scripts/sam4e/sam4e8/gcc/flash.ld
../src/ASF/sam/drivers/efc
diff --git a/ZodiacFX/src/command.c b/ZodiacFX/src/command.c
index 864f33d..8c1befa 100644
--- a/ZodiacFX/src/command.c
+++ b/ZodiacFX/src/command.c
@@ -24,6 +24,7 @@
* along with this program. If not, see .
*
* Author: Paul Zanna
+ * & Kristopher Chen
*
*/
@@ -60,16 +61,14 @@ extern uint16_t ofp13_oxm_inst_size[MAX_FLOWS_13];
extern struct flows_counter flow_counters[MAX_FLOWS_13];
extern struct flow_tbl_actions *flow_actions10[MAX_FLOWS_13];
extern int iLastFlow;
-extern struct ofp10_port_stats phys10_port_stats[4];
-extern struct ofp13_port_stats phys13_port_stats[4];
+extern struct ofp10_port_stats phys10_port_stats[TOTAL_PORTS];
+extern struct ofp13_port_stats phys13_port_stats[TOTAL_PORTS];
extern struct table_counter table_counters[MAX_TABLES];
extern struct meter_entry13 *meter_entry[MAX_METER_13];
extern struct meter_band_stats_array band_stats_array[MAX_METER_13];
-extern bool masterselect;
-extern bool stackenabled = false;
extern bool trace = false;
extern struct tcp_pcb *tcp_pcb;
-extern uint8_t port_status[4];
+extern uint8_t port_status[TOTAL_PORTS];
extern int totaltime;
extern int32_t ul_temp;
extern int OF_Version;
@@ -82,7 +81,6 @@ uint8_t uCLIContext = 0;
struct arp_header arp_test;
uint8_t esc_char = 0;
-
// Internal Functions
void saveConfig(void);
void command_root(char *command, char *param1, char *param2, char *param3);
@@ -124,6 +122,18 @@ void saveConfig(void)
return;
}
+/*
+* Restart Zodiac FX
+*
+*/
+void software_reset(void)
+{
+ for(int x = 0;x<100000;x++); // Let the above message get sent to the terminal before detaching
+ udc_detach(); // Detach the USB device before restart
+ rstc_start_software_reset(RSTC); // Software reset
+ while (1);
+}
+
/*
* Main command line loop
*
@@ -142,10 +152,7 @@ void task_command(char *str, char *str_last)
if(restart_required_outer == true)
{
printf("Restarting the Zodiac FX, please reopen your terminal application.\r\n");
- for(int x = 0;x<100000;x++); // Let the above message get sent to the terminal before detaching
- udc_detach(); // Detach the USB device before restart
- rstc_start_software_reset(RSTC); // Software reset
- while (1);
+ software_reset();
}
while(udi_cdc_is_rx_ready()){
@@ -318,28 +325,35 @@ void command_root(char *command, char *param1, char *param2, char *param3)
{
int i;
printf("\r\n-------------------------------------------------------------------------\r\n");
- for (i=0;i<4;i++)
+ for (i=0;i 3)
{
- if (Zodiac_Config.vlan_list[x].portmap[i] == 1)
+ printf(" VLAN type: OpenFlow\r\n");
+ printf(" VLAN ID: n/a\r\n");
+ } else
+ {
+ for (int x=0;x 3) printf(" RX Packets: %" PRIu64 "\r\n", phys10_port_stats[i].rx_packets);
+ if (Zodiac_Config.of_port[i] == 1 || i > 3) printf(" TX Packets: %" PRIu64 "\r\n", phys10_port_stats[i].tx_packets);
printf(" RX Dropped Packets: %" PRIu64 "\r\n", phys10_port_stats[i].rx_dropped);
printf(" TX Dropped Packets: %" PRIu64 "\r\n", phys10_port_stats[i].tx_dropped);
printf(" RX CRC Errors: %" PRIu64 "\r\n", phys10_port_stats[i].rx_crc_err);
@@ -348,8 +362,8 @@ void command_root(char *command, char *param1, char *param2, char *param3)
{
printf(" RX Bytes: %" PRIu64 "\r\n", phys13_port_stats[i].rx_bytes);
printf(" TX Bytes: %" PRIu64 "\r\n", phys13_port_stats[i].tx_bytes);
- if (Zodiac_Config.of_port[i] == 1) printf(" RX Packets: %" PRIu64 "\r\n", phys13_port_stats[i].rx_packets);
- if (Zodiac_Config.of_port[i] == 1) printf(" TX Packets: %" PRIu64 "\r\n", phys13_port_stats[i].tx_packets);
+ if (Zodiac_Config.of_port[i] == 1 || i > 3) printf(" RX Packets: %" PRIu64 "\r\n", phys13_port_stats[i].rx_packets);
+ if (Zodiac_Config.of_port[i] == 1 || i > 3) printf(" TX Packets: %" PRIu64 "\r\n", phys13_port_stats[i].tx_packets);
printf(" RX Dropped Packets: %" PRIu64 "\r\n", phys13_port_stats[i].rx_dropped);
printf(" TX Dropped Packets: %" PRIu64 "\r\n", phys13_port_stats[i].tx_dropped);
printf(" RX CRC Errors: %" PRIu64 "\r\n", phys13_port_stats[i].rx_crc_err);
@@ -447,10 +461,7 @@ void command_root(char *command, char *param1, char *param2, char *param3)
if (strcmp(command, "restart")==0)
{
printf("Restarting the Zodiac FX, please reopen your terminal application.\r\n");
- for(int x = 0;x<100000;x++); // Let the above message get sent to the terminal before detaching
- udc_detach(); // Detach the USB device before restart
- rstc_start_software_reset(RSTC); // Software reset
- while (1);
+ software_reset();
}
// Get CRC
@@ -461,6 +472,19 @@ void command_root(char *command, char *param1, char *param2, char *param3)
printf("Append [%08x 00000000] to the binary\r\n", ntohl(verify.calculated));
return;
}
+
+ if (strcmp(command, "dump")==0 && strcmp(param1, "flash")==0)
+ {
+ uint8_t* buffer_pmem = FLASH_BUFFER;
+ while(buffer_pmem < FLASH_BUFFER_END)
+ {
+ printf("%02x", *buffer_pmem);
+ buffer_pmem++;
+ }
+ printf("\n");
+
+ return;
+ }
// Unknown Command
printf("Unknown command\r\n");
@@ -506,10 +530,7 @@ void command_config(char *command, char *param1, char *param2, char *param3)
if (strcmp(command, "restart")==0)
{
printf("Restarting the Zodiac FX, please reopen your terminal application.\r\n");
- for(int x = 0;x<100000;x++); // Let the above message get send to the terminal before detaching
- udc_detach(); // Detach the USB device before restart
- rstc_start_software_reset(RSTC); // Software reset
- while (1);
+ software_reset();
}
// Display Config
@@ -534,10 +555,6 @@ void command_config(char *command, char *param1, char *param2, char *param3)
} else {
printf(" Force OpenFlow version: Disabled\r\n");
}
- if (masterselect == true) printf(" Stacking Select: SLAVE\r\n");
- if (masterselect == false) printf(" Stacking Select: MASTER\r\n");
- if (stackenabled == true) printf(" Stacking Status: Enabled\r\n");
- if (stackenabled == false) printf(" Stacking Select: Disabled\r\n");
if (Zodiac_Config.ethtype_filter == 1) printf(" EtherType Filtering: Enabled\r\n");
if (Zodiac_Config.ethtype_filter != 1) printf(" EtherType Filtering: Disabled\r\n");
printf("\r\n-------------------------------------------------------------------------\r\n\n");
@@ -1540,7 +1557,7 @@ void command_openflow(char *command, char *param1, char *param2, char *param3)
}
else if(ptr_band->type == OFPMBT13_DSCP_REMARK)
{
- printf("DSCP REMARK (unsupported)\r\n");
+ printf("DSCP REMARK\r\n");
}
else
{
@@ -1549,6 +1566,11 @@ void command_openflow(char *command, char *param1, char *param2, char *param3)
printf("\t\t Rate:\t\t%d\t\r\n", ptr_band->rate);
printf("\t\t Burst Size:\t%d\t\r\n", ptr_band->burst_size);
+ if(ptr_band->type == OFPMBT13_DSCP_REMARK)
+ {
+ printf("\t\t Precedence:\t+%d\t\r\n", ((struct ofp13_meter_band_dscp_remark*)ptr_band)->prec_level);
+ }
+
// Find band index
int band_index = ((uint8_t*)ptr_band - (uint8_t*)&(meter_entry[meter_index]->bands)) / sizeof(struct ofp13_meter_band_drop);
@@ -1611,12 +1633,6 @@ void command_debug(char *command, char *param1, char *param2, char *param3)
return;
}
- if (strcmp(command, "spi")==0)
- {
- //stack_write(atoi(param1));
- return;
- }
-
if (strcmp(command, "mem")==0)
{
printf("mem total: %d\r\n", membag_get_total());
@@ -1670,10 +1686,12 @@ void printhelp(void)
printf(" config\r\n");
printf(" openflow\r\n");
printf(" debug\r\n");
- printf(" show ports\r\n");
+ printf(" update\r\n");
printf(" show status\r\n");
printf(" show version\r\n");
+ printf(" show ports\r\n");
printf(" restart\r\n");
+ printf(" help\r\n");
printf("\r\n");
printf("Config:\r\n");
printf(" save\r\n");
@@ -1693,13 +1711,14 @@ void printhelp(void)
printf(" set vlan-type \r\n");
printf(" add vlan-port \r\n");
printf(" delete vlan-port \r\n");
- printf(" factory reset\r\n");
printf(" set of-version \r\n");
printf(" set ethertype-filter \r\n");
+ printf(" factory reset\r\n");
printf(" exit\r\n");
printf("\r\n");
printf("OpenFlow:\r\n");
printf(" show status\r\n");
+ printf(" show tables\r\n");
printf(" show flows\r\n");
printf(" show meters\r\n");
printf(" enable\r\n");
diff --git a/ZodiacFX/src/command.h b/ZodiacFX/src/command.h
index b2d0f36..bee2417 100644
--- a/ZodiacFX/src/command.h
+++ b/ZodiacFX/src/command.h
@@ -93,5 +93,6 @@ typedef struct arp_header {
void task_command(char *str, char * str_last);
void loadConfig(void);
+void software_reset(void);
#endif /* COMMANDS_H_ */
diff --git a/ZodiacFX/src/config/config_zodiac.h b/ZodiacFX/src/config/config_zodiac.h
index 6698768..bdfbe2c 100644
--- a/ZodiacFX/src/config/config_zodiac.h
+++ b/ZodiacFX/src/config/config_zodiac.h
@@ -31,7 +31,9 @@
#define CONFIG_ZODIAC_H_
-#define VERSION "0.80" // Firmware version number
+#define VERSION "0.81" // Firmware version number
+
+#define TOTAL_PORTS 4 // Total number of physical ports on the Zodiac FX
#define MAX_OFP_VERSION 0x04
diff --git a/ZodiacFX/src/flash.c b/ZodiacFX/src/flash.c
index 25ac197..c02ac78 100644
--- a/ZodiacFX/src/flash.c
+++ b/ZodiacFX/src/flash.c
@@ -36,19 +36,18 @@
#include "openflow/openflow.h"
#include "trace.h"
#include "command.h"
+#include "switch.h"
// Global variables
extern uint8_t shared_buffer[SHARED_BUFFER_LEN];
struct verification_data verify;
+uint32_t flash_page_addr;
// Static variables
static uint32_t page_addr;
//static uint32_t ul_rc;
-static uint32_t flash_page_addr;
static uint32_t ul_rc;
-static uint32_t ul_idx;
-static uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
/*
@@ -67,7 +66,7 @@ void get_serial(uint32_t *uid_buf)
*/
int firmware_update_init(void)
{
- flash_page_addr = NEW_FW_BASE;
+ flash_page_addr = FLASH_BUFFER;
/* Initialize flash: 6 wait states for flash writing. */
ul_rc = flash_init(FLASH_ACCESS_MODE_128, 6);
@@ -92,19 +91,18 @@ int firmware_update_init(void)
unlock_address += IFLASH_LOCK_REGION_SIZE;
}
- // Erase 192k
+ // Erase 32 pages at a time
uint32_t erase_address = flash_page_addr;
- while(erase_address < IFLASH_ADDR + IFLASH_SIZE - (ERASE_SECTOR_SIZE - 1))
+ while(erase_address < FLASH_BUFFER_END)
{
- //printf("-I- Erasing sector with address: 0x%08x\r\n", erase_address);
- ul_rc = flash_erase_sector(erase_address);
+ ul_rc = flash_erase_page(erase_address, IFLASH_ERASE_PAGES_32);
if (ul_rc != FLASH_RC_OK)
{
//printf("-F- Flash programming error %lu\n\r", (unsigned long)ul_rc);
return 0;
}
- erase_address += ERASE_SECTOR_SIZE;
+ erase_address += ((uint8_t)32*IFLASH_PAGE_SIZE);
}
return 1;
@@ -152,9 +150,7 @@ void cli_update(void)
if(verification_check() == SUCCESS)
{
printf("Firmware upload complete - Restarting the Zodiac FX.\r\n");
- for(int x = 0;x<100000;x++); // Let the above message get send to the terminal before detaching
- udc_detach(); // Detach the USB device before restart
- rstc_start_software_reset(RSTC); // Software reset
+ software_reset();
}
else
{
@@ -343,7 +339,7 @@ int xmodem_xfer(void)
* Remove XMODEM 0x1A padding at end of data
*
*/
-xmodem_clear_padding(uint8_t *buff)
+void xmodem_clear_padding(uint8_t *buff)
{
int len = IFLASH_PAGE_SIZE;
@@ -372,4 +368,3 @@ xmodem_clear_padding(uint8_t *buff)
return; // Padding characters removed
}
-
diff --git a/ZodiacFX/src/flash.h b/ZodiacFX/src/flash.h
index 7c25a9e..f08c547 100644
--- a/ZodiacFX/src/flash.h
+++ b/ZodiacFX/src/flash.h
@@ -52,11 +52,7 @@ struct verification_data
#define X_ACK 0x06
#define X_NAK 0x15
-#define ERASE_SECTOR_SIZE 8192
-#define NEW_FW_BASE (IFLASH_ADDR + (5*IFLASH_NB_OF_PAGES/8)*IFLASH_PAGE_SIZE)
-#define NEW_FW_MAX_SIZE 196608
-
-#define FLASH_BUFFER 0x450000
+#define FLASH_BUFFER 0x448000
#define FLASH_BUFFER_END 0x480000
#define NN_VERIFICATION_LEN 8
diff --git a/ZodiacFX/src/http.c b/ZodiacFX/src/http.c
index fca726f..9846d63 100644
--- a/ZodiacFX/src/http.c
+++ b/ZodiacFX/src/http.c
@@ -48,12 +48,13 @@
extern int totaltime;
extern int32_t ul_temp;
extern struct zodiac_config Zodiac_Config;
-extern uint8_t port_status[4];
+extern uint8_t port_status[8];
extern uint32_t uid_buf[4]; // Unique identifier
extern struct tcp_pcb *tcp_pcb;
extern int OF_Version;
extern uint8_t shared_buffer[SHARED_BUFFER_LEN]; // SHARED_BUFFER_LEN must never be reduced below 2048
extern int tcp_con_state; // Check connection state
+extern uint32_t flash_page_addr;
extern struct ofp_flow_mod *flow_match10[MAX_FLOWS_10];
extern struct ofp13_flow_mod *flow_match13[MAX_FLOWS_13];
@@ -66,13 +67,10 @@ extern struct meter_entry13 *meter_entry[MAX_METER_13];
extern struct meter_band_stats_array band_stats_array[MAX_METER_13];
extern int iLastFlow;
extern int iLastMeter;
-extern struct ofp10_port_stats phys10_port_stats[4];
-extern struct ofp13_port_stats phys13_port_stats[4];
+extern struct ofp10_port_stats phys10_port_stats[TOTAL_PORTS];
+extern struct ofp13_port_stats phys13_port_stats[TOTAL_PORTS];
extern struct table_counter table_counters[MAX_TABLES];
-extern int firmware_update_init(void);
-extern int flash_write_page(uint8_t *flash_page);
-
// Local Variables
struct tcp_pcb *http_pcb;
static char http_msg[64]; // Buffer for HTTP message filtering
@@ -98,7 +96,9 @@ void http_send(char *buffer, struct tcp_pcb *pcb, bool out);
static err_t http_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
void http_close(struct tcp_pcb *pcb);
-static uint8_t upload_handler(char *payload, int len);
+static uint8_t upload_handler(char *payload, int len);
+static uint8_t process_pagebuff(uint8_t * buff_addr, uint16_t buff_index, uint8_t * match_addr);
+static uint16_t send_pagebuff(uint8_t * buff_addr, uint16_t buff_index);
// HTML resources
static uint8_t interfaceCreate_Frames(void);
@@ -211,12 +211,9 @@ static err_t http_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len)
}
if(restart_required == true)
{
+ // Indicates to task_command() that a restart is required on the next loop
+ // This allows the 'Restarting...' page to display before the restart occurs
restart_required_outer = true;
- //TRACE("http.c: restarting the Zodiac FX. Please reconnect.");
- //for(int x = 0;x<100000;x++); // Let the above message get sent to the terminal before detaching
- //udc_detach(); // Detach the USB device before restart
- //rstc_start_software_reset(RSTC); // Software reset
- //while (1);
}
return ERR_OK;
@@ -341,14 +338,30 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
else
{
upload_handler(NULL, 0); // Clean up upload operation
- if(interfaceCreate_Upload_Status(3))
+
+ if(flash_page_addr >= FLASH_BUFFER_END-IFLASH_PAGE_SIZE)
{
- http_send(&shared_buffer, pcb, 1);
- TRACE("http.c: Page sent successfully - %d bytes", strlen(shared_buffer));
+ if(interfaceCreate_Upload_Status(5))
+ {
+ http_send(&shared_buffer, pcb, 1);
+ TRACE("http.c: Page sent successfully - %d bytes", strlen(shared_buffer));
+ }
+ else
+ {
+ TRACE("http.c: Unable to serve page - buffer at %d bytes", strlen(shared_buffer));
+ }
}
else
{
- TRACE("http.c: Unable to serve page - buffer at %d bytes", strlen(shared_buffer));
+ if(interfaceCreate_Upload_Status(3))
+ {
+ http_send(&shared_buffer, pcb, 1);
+ TRACE("http.c: Page sent successfully - %d bytes", strlen(shared_buffer));
+ }
+ else
+ {
+ TRACE("http.c: Unable to serve page - buffer at %d bytes", strlen(shared_buffer));
+ }
}
}
}
@@ -472,7 +485,24 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
if(interfaceCreate_Display_Ports(1))
{
- // Call TCP output & close the connection
+ http_send(&shared_buffer, pcb, 0);
+ }
+ else
+ {
+ TRACE("http.c: Unable to serve page - buffer at %d bytes", strlen(shared_buffer));
+ }
+
+ if(interfaceCreate_Display_Ports(2))
+ {
+ http_send(&shared_buffer, pcb, 0);
+ }
+ else
+ {
+ TRACE("http.c: Unable to serve page - buffer at %d bytes", strlen(shared_buffer));
+ }
+
+ if(interfaceCreate_Display_Ports(3))
+ {
http_send(&shared_buffer, pcb, 1);
TRACE("http.c: Page sent successfully - %d bytes", strlen(shared_buffer));
}
@@ -722,10 +752,7 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
eeprom_write();
TRACE("http.c: restarting the Zodiac FX. Please reconnect.");
- for(int x = 0;x<100000;x++); // Let the above message get sent to the terminal before detaching
- udc_detach(); // Detach the USB device before restart
- rstc_start_software_reset(RSTC); // Software reset
- while (1);
+ software_reset();
}
else if(strcmp(post_msg,"save_ports") == 0)
{
@@ -819,7 +846,7 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
{
// Only write to buffer - don't send
http_send(&shared_buffer, pcb, 0);
- TRACE("http.c: updated ports page sent successfully (1/2) - %d bytes", strlen(shared_buffer));
+ TRACE("http.c: updated ports page sent successfully (1/4) - %d bytes", strlen(shared_buffer));
}
else
{
@@ -827,10 +854,32 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
}
if(interfaceCreate_Display_Ports(1))
+ {
+ // Call TCP output & close the connection
+ http_send(&shared_buffer, pcb, 0);
+ TRACE("http.c: updated ports page sent successfully (2/4) - %d bytes", strlen(shared_buffer));
+ }
+ else
+ {
+ TRACE("http.c: unable to serve updated page - buffer at %d bytes", strlen(shared_buffer));
+ }
+
+ if(interfaceCreate_Display_Ports(2))
+ {
+ // Call TCP output & close the connection
+ http_send(&shared_buffer, pcb, 0);
+ TRACE("http.c: updated ports page sent successfully (3/4) - %d bytes", strlen(shared_buffer));
+ }
+ else
+ {
+ TRACE("http.c: unable to serve updated page - buffer at %d bytes", strlen(shared_buffer));
+ }
+
+ if(interfaceCreate_Display_Ports(3))
{
// Call TCP output & close the connection
http_send(&shared_buffer, pcb, 1);
- TRACE("http.c: updated ports page sent successfully (2/2) - %d bytes", strlen(shared_buffer));
+ TRACE("http.c: updated ports page sent successfully (4/4) - %d bytes", strlen(shared_buffer));
}
else
{
@@ -1156,20 +1205,22 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err
if(pdat[i+1] == 'w')
{
int oc1,oc2,oc3,oc4;
- if (strlen(http_msg) > 15 )
+ if (strlen(http_msg) <= 15 )
{
- TRACE("http.c: incorrect IP format");
- return;
- }
- sscanf(http_msg, "%d.%d.%d.%d", &oc1,&oc2,&oc3,&oc4);
- Zodiac_Config.OFIP_address[0] = oc1;
- Zodiac_Config.OFIP_address[1] = oc2;
- Zodiac_Config.OFIP_address[2] = oc3;
- Zodiac_Config.OFIP_address[3] = oc4;
- TRACE("http.c: openflow server address set to %d.%d.%d.%d" ,\
+ sscanf(http_msg, "%d.%d.%d.%d", &oc1,&oc2,&oc3,&oc4);
+ Zodiac_Config.OFIP_address[0] = oc1;
+ Zodiac_Config.OFIP_address[1] = oc2;
+ Zodiac_Config.OFIP_address[2] = oc3;
+ Zodiac_Config.OFIP_address[3] = oc4;
+ TRACE("http.c: openflow server address set to %d.%d.%d.%d" ,\
Zodiac_Config.OFIP_address[0], Zodiac_Config.OFIP_address[1],\
Zodiac_Config.OFIP_address[2], Zodiac_Config.OFIP_address[3]\
- );
+ );
+ }
+ else
+ {
+ TRACE("http.c: incorrect IP format");
+ }
}
else
{
@@ -1412,23 +1463,24 @@ void http_close(struct tcp_pcb *pcb)
*/
static uint8_t upload_handler(char *payload, int len)
{
- static char page[IFLASH_PAGE_SIZE] = {0}; // Storage for each page of data
- static uint16_t saved_bytes = 0; // Persistent counter of unwritten data
- uint16_t handled_bytes = 0; // Counter of handled data
- static uint32_t total_handled_bytes = 0; // Counter of total handled data
- static char boundary_ID[BOUNDARY_MAX_LEN] = {0}; // Storage for boundary ID
+ // Persistent local variables
+ static uint8_t pagebuff[PAGEBUFF_SIZE] = {0}; // Storage for each page of data
+ static uint8_t boundary_ID[BOUNDARY_MAX_LEN] = {0}; // Storage for boundary ID
+ static uint16_t pagebuff_index = 0;
+
+ // Local variables
+ uint16_t payload_index = 0;
+ uint8_t boundary_ret = 0;
if(payload == NULL || len == 0)
{
// Clean up upload handler (on interrupted/failed upload)
- memset(&page, 0, IFLASH_PAGE_SIZE); // Clear page storage
+ memset(&pagebuff, 0, PAGEBUFF_SIZE); // Clear page storage
memset(&boundary_ID, 0, BOUNDARY_MAX_LEN); // Clear boundary storage
- saved_bytes = 0; // Clear saved byte counter
file_upload = false; // Clear file upload flag
boundary_start = 1; // Set starting boundary required flag
upload_pcb = NULL; // Clear pcb connection pointer
upload_timer = 0; // Clear upload timeout
- total_handled_bytes = 0;
return 1;
}
@@ -1542,7 +1594,7 @@ static uint8_t upload_handler(char *payload, int len)
boundary_start = 0;
// Clear page array before use
- memset(&page, 0, IFLASH_PAGE_SIZE); // Clear shared_buffer
+ memset(&pagebuff, 0, PAGEBUFF_SIZE); // Clear shared_buffer
}
}
else
@@ -1551,277 +1603,62 @@ static uint8_t upload_handler(char *payload, int len)
px = payload;
}
- // Search for ending boundary
- py = payload + len;
-
- i = 128;
- while(i>0)
+ // Fix alignment after boundary detection
+ if(px > payload)
{
- py--;
- // Latch onto '----' ("----[boundary ID]")
- if((*(py-1)) == '\x2d' && (*(py-2)) == '\x2d' && (*(py-3)) == '\x2d' && (*(py-4)) == '\x2d')
- {
- // Store the discovered boundary
- char tmpID[BOUNDARY_MAX_LEN] = {0};
- int z = 0;
- while(z < BOUNDARY_MAX_LEN && *(py+z) != '\x2d' && *(py+z) != '\x0d' && *(py+z) != '\x0a')
- {
- tmpID[z] = *(py+z);
- z++;
- }
-
- TRACE("http.c: discovered boundary ID : %s", tmpID);
-
- // Match the boundary ID with stored ID
- if(strcmp(tmpID, boundary_ID) == 0)
- {
- TRACE("http.c: boundary IDs match");
- TRACE("http.c: moving data end pointer");
- // Traverse through the preceding newline characters
- while(*(py-1) == '\x0d' || *(py-1) == '\x0a' || *(py-1) == '\x2d')
- {
- py--;
- }
-
- i = 0;
- // 'i' will be decremented to -1 if this line is run
- }
- else
- {
- TRACE("http.c: boundary IDs do not match");
- i = 1;
- // 'i' will be decremented to 0 if this line is run
- }
- }
- i--;
+ len = len - (px - payload);
+ payload = px;
}
-
- if(i == 0)
+ while(payload_index < len)
{
- TRACE("http.c: ending boundary not found - ending data is valid");
-
- // Return ending pointer to the end
- py = payload + len;
- }
- else
- {
- TRACE("http.c: ending boundary found");
- final = 1;
- }
-
- // Get length of uploaded part
- data_len = py - px;
-
- // Check if any existing data needs to be handled
- if(saved_bytes)
- {
- TRACE("http.c: %d saved bytes need to be cleared", saved_bytes);
-
- if(final)
- {
- /* Final page needs to be written */
-
- // Fill 512-byte array
- while(saved_bytes < IFLASH_PAGE_SIZE)
- {
- if(px < py)
- {
- // Write data
- page[saved_bytes] = *px;
- px++;
- handled_bytes++;
- }
- else
- {
- // Append 0xFF
- page[saved_bytes] = 0xFF;
- }
-
- saved_bytes++;
- }
-
- // Write data to page
- if(flash_write_page(&page))
- {
- TRACE("http.c: final firmware page written successfully");
- page_ctr++;
- }
- else
- {
- TRACE("http.c: final firmware page write FAILED");
- }
- }
- else if(saved_bytes + len < IFLASH_PAGE_SIZE)
+ if(pagebuff_index < PAGEBUFF_SIZE)
{
- int max_len = saved_bytes + len;
- // Fill existing partially-complete page with new data
- while(saved_bytes < max_len && handled_bytes < len)
- {
- page[saved_bytes] = *px;
- if(px < py)
- {
- px++;
- }
- else
- {
- TRACE("http.c: ERROR - multi-part start pointer has passed the end pointer");
- }
- saved_bytes++;
- handled_bytes++;
- }
-
- // Handle edge-case
- TRACE("http.c: unable to fill a complete page - skipping page write");
- TRACE("http.c: %d bytes saved", saved_bytes);
-
- total_handled_bytes += handled_bytes;
- return 1;
+ pagebuff[pagebuff_index] = payload[payload_index];
+ pagebuff_index++;
}
- else
+
+ if(pagebuff_index >= PAGEBUFF_SIZE)
{
- // Fill existing partially-complete page with new data
- while(saved_bytes < IFLASH_PAGE_SIZE && handled_bytes < len)
- {
- page[saved_bytes] = *px;
- if(px < py)
- {
- px++;
- }
- else
- {
- TRACE("http.c: ERROR - multi-part start pointer has passed the end pointer");
- }
- saved_bytes++;
- handled_bytes++;
- }
+ boundary_ret = process_pagebuff(pagebuff, pagebuff_index, boundary_ID);
+ if(boundary_ret == 1) break;
- // Write data to page
- if(flash_write_page(&page))
- {
- TRACE("http.c: firmware page written successfully");
- page_ctr++;
- }
- else
- {
- TRACE("http.c: firmware page write FAILED");
- }
+ pagebuff_index = send_pagebuff(pagebuff, pagebuff_index);
}
-
- // Saved bytes have been handled - clear the counter
- saved_bytes = 0;
- TRACE("http.c: saved bytes have been cleared");
- TRACE("http.c: handled_bytes: %04d, data_len: %04d", handled_bytes, data_len);
+ payload_index++;
}
-
- while(handled_bytes < data_len)
+
+ if(boundary_ret == 0)
{
- if(data_len - handled_bytes >= IFLASH_PAGE_SIZE)
- {
- // Fill 512-byte array
- int j = 0;
- while(j < IFLASH_PAGE_SIZE)
- {
- page[j] = *px;
- if(px < py)
- {
- px++;
- }
- else
- {
- TRACE("http.c: ERROR - multi-part start pointer has passed the end pointer");
- }
- j++;
- handled_bytes++;
- }
-
- // Write to page
- if(flash_write_page(&page))
- {
- TRACE("http.c: firmware page written successfully");
- page_ctr++;
- }
- else
- {
- TRACE("http.c: firmware page write FAILED");
- }
- }
- else if(!final)
+ boundary_ret = process_pagebuff(pagebuff, pagebuff_index, boundary_ID);
+ }
+
+ if(boundary_ret == 1)
+ {
+ if(pagebuff_index >= 512)
{
- /* Data needs to be saved */
- TRACE("http.c: data needs to be saved");
-
- // Save leftover into page array for next run-through
- int j = 0;
- while(handled_bytes < data_len)
+ pagebuff_index = send_pagebuff(pagebuff, pagebuff_index);
+ for(pagebuff_index; pagebuff_index < IFLASH_PAGE_SIZE; pagebuff_index++)
{
- page[j] = *px;
- if(px < py)
- {
- px++;
- }
- else
- {
- TRACE("http.c: ERROR - multi-part start pointer has passed the end pointer");
- }
- j++;
- handled_bytes++;
- saved_bytes++;
+ pagebuff[pagebuff_index] = 0xFF;
}
-
- TRACE("http.c: %d bytes saved", saved_bytes);
+ pagebuff_index = send_pagebuff(pagebuff, pagebuff_index);
}
else
{
- /* Final page needs to be written */
-
- // Fill 512-byte array
- int j = 0;
- while(j < IFLASH_PAGE_SIZE)
- {
- if(px < py)
- {
- // Write data
- page[j] = *px;
- px++;
- handled_bytes++;
- }
- else
- {
- // Append 0xFF
- page[j] = 0xFF;
- }
-
- j++;
- }
-
- // Write to page
- if(flash_write_page(&page))
- {
- TRACE("http.c: final page written successfully");
- page_ctr++;
- }
- else
- {
- TRACE("http.c: final page write FAILED");
- }
+ pagebuff_index = send_pagebuff(pagebuff, pagebuff_index);
}
-
- TRACE("http.c: handled_bytes: %04d, data_len: %04d", handled_bytes, data_len);
- }
-
- total_handled_bytes += handled_bytes;
- TRACE("http.c: total_handled_bytes: %d", total_handled_bytes);
-
- if(final)
- {
+
return 2;
}
- else
+
+ if(pagebuff_index >= 512)
{
- return 1;
+ pagebuff_index = send_pagebuff(pagebuff, pagebuff_index);
}
+
+ return 1;
}
static uint8_t Config_Network(char *payload, int len)
@@ -1884,7 +1721,7 @@ static uint8_t Config_Network(char *payload, int len)
if (strlen(http_msg) != 27 ) // Accounting for ":" as "%3A"
{
TRACE("http.c: incorrect MAC address format");
- return;
+ return FAILURE;
}
// Decode http string
@@ -1942,7 +1779,7 @@ static uint8_t Config_Network(char *payload, int len)
if (strlen(http_msg) > 15 )
{
TRACE("http.c: incorrect IP format");
- return;
+ return FAILURE;
}
sscanf(http_msg, "%d.%d.%d.%d", &ip1, &ip2,&ip3,&ip4);
Zodiac_Config.IP_address[0] = ip1;
@@ -1981,7 +1818,7 @@ static uint8_t Config_Network(char *payload, int len)
if (strlen(http_msg) > 15 )
{
TRACE("http.c: incorrect netmask format");
- return;
+ return FAILURE;
}
sscanf(http_msg, "%d.%d.%d.%d", &nm1, &nm2,&nm3,&nm4);
Zodiac_Config.netmask[0] = nm1;
@@ -2021,7 +1858,7 @@ static uint8_t Config_Network(char *payload, int len)
if (strlen(http_msg) > 15 )
{
TRACE("http.c: incorrect gateway format");
- return;
+ return FAILURE;
}
sscanf(http_msg, "%d.%d.%d.%d", &gw1, &gw2,&gw3,&gw4);
Zodiac_Config.gateway_address[0] = gw1;
@@ -2080,11 +1917,9 @@ static uint8_t interfaceCreate_Frames(void)
""\
"