Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 00002 /* 00003 Generated: Enet_SPI_LPC1768.bin 00004 00005 mbed test software for Ethernet HTTPServer with simultaneous SPI for 4 data byte updates 00006 00007 Version Date Author Change 00008 0.2: 06/10/11 LS Add block checksum character to SPI data 00009 0.3: 07/10/11 LS Add SPI read from cmd_buf 00010 0.4: 13/10/11 LS Integrated with HTTP server example code 00011 0.5: 18/10/11 LS Initial file handling 00012 0.6: 26/10/11 LS File IO handled by SPI_server class 00013 0.78: 17/11/11 LS Add SNMP files for system info reporting, but HTTP svr.bind disabled 00014 0.79 12/12/11 LS Reads network addresses from file & uses enterprise address 00015 0.80 18/12/11 LS Save last number read in read_addrs_from_file(). 00016 0.81 22/12/11 LS Add new_cmd_idx to indicate which parameter has been set (0 for none). 00017 0.82 22/12/11 LS Add blinker to show comms activity 00018 0.83 23/12/11 LS Clear cmd_buf[0] after SPI been read 4 times 00019 0.84 27/12/11 LS snmp_fw_version & f3k_fw_version saved as 4 char strings 00020 0.85 29/12/11 LS Update f3k_sys_set_value() & f3k_sys_set_test() to enable net address change 00021 0.90 29/12/11 LS Add 3-step routine for passing commands over SPI bus from cmd_buf 00022 0.94 10/01/12 LS Add led_link = LPC_GPIO1->FIOPIN & (1<<25) in netservice.cpp 00023 0.95 11/01/12 LS Fix f3k_speed reporting error in private_mib.c 00024 0.96 12/01/12 LS Move led_link = LPC_GPIO1->FIOPIN & (1<<25) to eth_poll in eth_drv.cpp 00025 0.98 26/04/12 LS Increase snmp_publiccommunity[7] to [21] and allow this to be set from file 00026 0.99 08/06/12 LS #define SNMP_TRAP_DESTINATIONS 1. Declare th_ad[4] for host trap address 00027 Add init_traps() to ensure head-head link status trap is sent 00028 21/06/12 Add check for changes to IO bytes and chk_SPI_active() every 60 seconds 00029 1.00 22/06/12 LS Save SNMP changes to net addresses & mask4_IO_registers in net_adrs.txt 00030 00031 http://192.168.99.99/rpc/offset,604 writes 604 to reg_offset 00032 http://192.168.99.99/rpc/led2/write,1 writes 1 to led2 00033 http://192.168.99.99/files/IO1000PX.htm uploads file IO1000PX.htm 00034 */ 00035 00036 #include "mbed.h" 00037 #include "EthernetNetIf.h" 00038 #include "HTTPServer.h" 00039 #include "lwip/snmp_structs.h" 00040 #include "lwip/snmp_msg.h" 00041 #include "IO_file.h" 00042 00043 #define LPC1768 0x60 // SPI address of LPC1768 module 00044 #define READ_IO 0x01 // bit in address field for data reads 00045 #define SPI_BYTES 4 // # of data bytes in SPI message 00046 #define INV_SPI_CNT 0xfffff // invalid (over-range SPI count 00047 #define NUM_READ 8 // # of SPI replies for valid reads 00048 #define NUM_INDX 4 // # of SPI replies for valid cmd_buf index 00049 #define MAX_CMD 4 // size of CMD buffer 00050 #define NO_CMD 0xff // data on cmd_buf[0] when NO_CMD to be sent 00051 #define NO_UPDATE 0 // NO change to Ethernet addresses 00052 #define UPDATED 0xff // Ethernet addresses updated in file 00053 #define NET_ADRS_FILE "/webfs/net_adrs.txt" 00054 00055 00056 const char * snmp_fw_version = "1.a"; 00057 00058 /* default ethernet address setup */ 00059 unsigned char ip_ad[4] = {192,168,99,99}; 00060 unsigned char msk_ad[4] = {255,255,255,0}; 00061 unsigned char gwy_ad[4] = {192,168,99,253}; 00062 unsigned char dns_ad[4] = {192,168,99,253}; 00063 unsigned char th_ad[4] = {146,38,105,49}; // v0.99: host address for SNMP traps 00064 unsigned char net_addrs_set = false; // flags net address update from SNMP 00065 unsigned char net_addrs_chng = NO_UPDATE; // flags net address changed in main CPU 00066 unsigned char byte_changed = false; // true if any IO regs have changed 00067 unsigned char all_IO_updated = false; // true if all 32 IO regs have been read 00068 char hex_mask[12]; // IO mask as hex string 00069 unsigned long mask4_IO_registers = 0x3fffffff; // mask for IO regs ignoring IO31 & 32 00070 unsigned long spi_count = 0; // last SPI_COUNT saved in SPI interrupt 00071 unsigned char spi_active = true; // avoid false trap message at start 00072 00073 static u8_t syslocation[32]; /* v0.9b */ 00074 u8_t sysloc_len; 00075 00076 SPISlave spi_slave(p11, p12, p13, p14); // mosi, miso, sclk, ssel 00077 00078 Ticker comms_tick; 00079 Ticker sys_tick; // system tick for SNMP sysuptime report 00080 Ticker spi_tick; // tick for monitoring SPI activity 00081 Timeout cold_start_delay; 00082 00083 DigitalOut led1(LED1, "led1"); // mimics head-head link status o/p in main CPU I/O 00084 DigitalOut led2(LED2, "led2"); 00085 DigitalOut led3(LED3, "led3"); 00086 DigitalOut led4(LED4, "led4"); 00087 DigitalOut led_link(p29); // Green link status: ON=good, Blink=Activity 00088 DigitalOut led_speed(p30); // Yellow link speed: ON for 100Mb/s 00089 00090 unsigned char blink_led = false; 00091 unsigned char trap_init = false; // true after cold_start trap sent 00092 00093 LocalFileSystem fs( "webfs" ); 00094 00095 IpAddr mip, mnm, mgw, mdns; // instantiate from core\ipaddr.cpp 00096 00097 //EthernetNetIf eth; // use if DNS sets up address 00098 00099 HTTPServer svr; 00100 SPI_Server fsvr( "fsvr" ); 00101 00102 Serial pc( USBTX, USBRX ); // for diagnostic serial comms to PC via USB 00103 00104 /****************************************************************************/ 00105 /* SPI interface data and routines */ 00106 /****************************************************************************/ 00107 /* commands sent to main CPU cpu from cmd_buf[0] and 00108 waiting commands stored in higher indices until sent */ 00109 unsigned char cmd_buf[ MAX_CMD ]; // store for commands from Ethernet 00110 unsigned char new_cmd_idx; 00111 00112 00113 /****************************************************************************/ 00114 /* SPI_Server: 00115 * Description: Instantiates Class to hold & access all data read from RAM by SPI 00116 * Called by FSHandler::doGet() in services\http\server\impl 00117 * Parameters: name of object instantiated 00118 * Returns: NONE 00119 */ 00120 /****************************************************************************/ 00121 SPI_Server::SPI_Server(const char * name) 00122 { 00123 int idx; 00124 for ( idx = 0; idx < MAX_RAM; idx++ ) 00125 { 00126 ram_img[ idx ] = (MAX_RAM - idx) & 0xff; 00127 } 00128 reg_offset = 0; 00129 } 00130 00131 SPI_Server::~SPI_Server() 00132 { 00133 if(fp) fclose(fp); 00134 } 00135 00136 /****************************************************************************/ 00137 /* update_IO_file: 00138 * Description: Reads data from ram_img[] into IO1000PX.htm for web access 00139 * Called by FSHandler::doGet() in services\http\server\impl 00140 * Globals used: NONE 00141 * Parameters: NONE 00142 * Returns: 0 if OK, 1 if failed to open files 00143 */ 00144 /****************************************************************************/ 00145 int SPI_Server::update_IO_file() 00146 { 00147 int c, i; // characters read/written in files 00148 unsigned short chnl, dval; // data from 1000PX 00149 00150 DBG("\r\nIn SPI_Server::update_IO_file()\r\n"); 00151 FILE *fr = fopen("/webfs/hdr.htm", "r"); 00152 if(!fr) { 00153 fprintf(stderr, "\r\nFile /webfs/hdr.htm could not be opened!\r\n"); 00154 exit(1); 00155 } 00156 else 00157 { 00158 fp = fopen( "/webfs/IO1000PX.htm", "w" ); 00159 if(!fp) { 00160 fprintf(stderr, "\r\nFile /webfs/IO1000PX.htm could not be opened to write!\r\n" ); 00161 exit(1); 00162 } 00163 else 00164 { 00165 while ( (c = fgetc(fr)) != EOF ) 00166 { 00167 fputc( c, fp ); 00168 } 00169 fclose(fr); 00170 DBG("\r\nIn SPI_Server::update_IO_file() - header copied\r\n"); 00171 for ( i = 0; i < 16; i++ ) 00172 { 00173 chnl = reg_offset + i; 00174 dval = 256 * ram_img[ 2*chnl ] + ram_img[ 2*chnl + 1 ]; 00175 fprintf(fp, " <TR VALIGN=TOP>\r\n"); 00176 fprintf(fp, " <TD WIDTH=124>\r\n"); 00177 fprintf(fp, " <P>%02d</P>\r\n", chnl ); 00178 fprintf(fp, " </TD>\r\n"); 00179 fprintf(fp, " <TD WIDTH=124>\r\n"); 00180 fprintf(fp, " <P>%d</P>\r\n", dval ); 00181 fprintf(fp, " </TD>\r\n"); 00182 fprintf(fp, " <TD WIDTH=124>\r\n"); 00183 fprintf(fp, " <P>%02x</P>\r\n", (dval/256) ); 00184 fprintf(fp, " </TD>\r\n"); 00185 fprintf(fp, " <TD WIDTH=124>\r\n"); 00186 fprintf(fp, " <P>%02x</P>\r\n", (dval & 0xff) ); 00187 fprintf(fp, " </TD>\r\n"); 00188 fprintf(fp, " </TR>\r\n"); 00189 } 00190 fprintf(fp, "</TABLE>\r\n<P><BR><BR>\r\n</P>\r\n</BODY>\r\n</HTML>\r\n"); 00191 } 00192 } 00193 fclose(fp); 00194 // fclose(fr); 00195 return 0; 00196 } 00197 00198 int SPI_Server::read( void ) 00199 { 00200 DBG("\r\nIn SPI_Server::read()\r\n"); 00201 return reg_offset; 00202 } 00203 00204 void SPI_Server::write( int new_offset ) 00205 { 00206 DBG("\r\nIn SPI_Server::write()\r\n"); 00207 if ( (new_offset >= 0) && (new_offset < MAX_RAM) ) reg_offset = new_offset; 00208 } 00209 00210 unsigned char SPI_Server::get_byte( unsigned short idx ) 00211 { 00212 return ram_img[ idx ]; 00213 } 00214 00215 void SPI_Server::put_byte( unsigned short idx, unsigned char new_byte ) 00216 { 00217 if ( idx < MAX_RAM ) 00218 ram_img[ idx ] = new_byte; 00219 } 00220 00221 unsigned short SPI_Server::get_error( void ) 00222 { 00223 // return error register value from main CPU 00224 return (256 * ram_img[ 1786 ]) + ram_img[ 1787 ]; 00225 } 00226 00227 unsigned short SPI_Server::get_SPI_count( void ) 00228 { 00229 // return SPI write count from main CPU - indicates main CPU running OK 00230 return (256 * ram_img[ SPI_COUNT ]) + ram_img[ SPI_COUNT + 1 ]; 00231 } 00232 00233 unsigned char * SPI_Server::net_address_ptr( void ) 00234 { 00235 return &ram_img[ NET_IP_ADDRESS ]; 00236 } 00237 00238 unsigned char * SPI_Server::trap_host_ptr( void ) 00239 { 00240 return &ram_img[ TRAP_HOST_ADDRESS ]; 00241 } 00242 00243 #if 0 00244 //#ifdef MBED_RPC trap_host_ptr 00245 const struct rpc_method *SPI_Server::get_rpc_methods() { 00246 static const rpc_method methods[] = { 00247 { "read", rpc_method_caller<int, SPI_Server, &SPI_Server::read> }, 00248 { "write", rpc_method_caller<SPI_Server, int, &SPI_Server::write> }, 00249 RPC_METHOD_SUPER(Base) //Stream) 00250 }; 00251 return methods; 00252 } 00253 00254 struct rpc_class *SPI_Server::get_rpc_class() { 00255 static const rpc_function funcs[] = { 00256 { "new", rpc_function_caller<const char*, int, &Base::construct<SPI_Server, int> > }, 00257 RPC_METHOD_END 00258 }; 00259 static rpc_class c = { "SPI_Server", funcs, NULL }; 00260 return &c; 00261 } 00262 #endif 00263 00264 void check4write_offset( char * req ) 00265 { 00266 unsigned char l, c, i; 00267 char v[ 20 ] = {0}; 00268 char s[ 20 ] = {0}; 00269 char * p; 00270 00271 strcpy( v, "/offset," ); 00272 p = strstr( req, v ); 00273 strcpy( s, p ); 00274 if ( p != NULL ) 00275 { 00276 i = strlen(v); 00277 l = strlen(s); 00278 if ( (l > i) && (l < (i + 6)) ) 00279 { 00280 l -= i; 00281 for ( c = 0; c < l; c++ ) 00282 { 00283 v[ c ] = s[ i + c ]; 00284 } 00285 v[ c ] = 0; 00286 fsvr.write( atoi(v) ); 00287 } 00288 } 00289 } 00290 00291 /****************************************************************************/ 00292 /* get_SPI_data: 00293 * Description: Implements transaction as SPI slave. 00294 * Reads 4 data bytes from SPI bus into destbuf for SPI write, or 00295 * Puts 1 byte from srcbuf onto SPI for SPI read 00296 * Called by main when spi_slave.receive interrupts 00297 * LPC1768 SPI slave handles a maximum of 8 bytes per transfer 00298 * Globals used: NONE 00299 * Parameters: IN/OUT: unsigned char * srcbuf : buffer to read from 00300 * Returns: int buf_idx : index to SPI data in destbuf/srcbuf 00301 */ 00302 /****************************************************************************/ 00303 int get_SPI_data( unsigned char * srcbuf ) 00304 { 00305 static unsigned char rd_cnt; // v0.83: count of times valid data put on bus 00306 int buf_idx = 0xffff; // index to save SPI data into destbuf 00307 int idx; // index to compare with net address block 00308 unsigned char spi_buf[ 8 ]; // temporary buffer for SPI data received 00309 unsigned char byte_cnt; // count of SPI data bytes received 00310 unsigned char spiv; // SPI value - initial slave address 00311 unsigned char bcc = 0; // received block check character 00312 unsigned char bcc_ok = false; // default to reject messages without bcc 00313 00314 spiv = spi_slave.read(); // Read byte from master 00315 if ( (spiv & 0xfe) == (LPC1768 & 0xfe) ) 00316 { 00317 if ( spiv & READ_IO ) 00318 { 00319 led4 = 1; 00320 led3 = 0; 00321 if ( *srcbuf < NO_CMD ) 00322 { // new data to be read by main CPU cpu 00323 if ( ++rd_cnt >= NUM_READ ) 00324 { // v0.83: clear data after 4 reads 00325 spi_slave.reply( NO_CMD ); // put invalid data in SPI buffer 00326 *srcbuf = NO_CMD; 00327 rd_cnt = 0; 00328 } 00329 else if ( rd_cnt >= NUM_INDX ) 00330 { // next put data from srcbuf in SPI buffer 00331 spi_slave.reply( *srcbuf ); 00332 } 00333 else // put new_cmd_idx on SPI bus first 00334 { 00335 spi_slave.reply( NO_CMD - new_cmd_idx ); // put new_cmd_idx in SPI buffer 00336 } 00337 } // end if ( *srcbuf < 0xff ) 00338 else 00339 { 00340 rd_cnt = 0; // re-initialise read count 00341 spi_slave.reply( NO_CMD ); // put invalid data in SPI buffer 00342 } 00343 } 00344 else // NOT READ_IO - data write 00345 { 00346 buf_idx = spi_slave.read(); // Read ms index from master 00347 bcc ^= buf_idx; // Start checksum calculation 00348 buf_idx *= 256; // Make ms index from master 00349 buf_idx += spi_slave.read(); // Read ls index from master 00350 bcc ^= (buf_idx & 0xff); 00351 byte_cnt = 0; 00352 while( spi_slave.receive() ) { 00353 if( byte_cnt < SPI_BYTES ) { // Read 4 data bytes 00354 spi_buf[ byte_cnt ] = spi_slave.read(); 00355 bcc ^= spi_buf[ byte_cnt++ ]; 00356 } 00357 else if ( byte_cnt == SPI_BYTES ) { 00358 spiv = spi_slave.read(); 00359 bcc_ok = ( bcc == spiv ); 00360 } 00361 } // end while ( spi_slave.receive() ) 00362 if ( bcc_ok && (buf_idx < MAX_RAM) ) 00363 { 00364 for( byte_cnt = 0; byte_cnt < SPI_BYTES; byte_cnt++ ) 00365 { 00366 idx = buf_idx + byte_cnt; 00367 if ( idx <= MAX_IO_REG_BYTE ) 00368 { // check for IO changed from last saved 00369 if ( (spi_buf[ byte_cnt ] != fsvr.get_byte( idx )) && !byte_changed ) 00370 { 00371 if ( mask4_IO_registers & (1 << (idx/2)) ) 00372 { // masked-in register has changed 00373 byte_changed = true; 00374 } 00375 } 00376 if ( idx == MAX_IO_REG_BYTE ) 00377 { // after each I/O scan 00378 all_IO_updated = true; 00379 spi_count = fsvr.get_SPI_count(); // save last SPI_count value 00380 } 00381 } 00382 else if ( idx == NET_ADDRESS_CHANGE ) 00383 { // v0.93: check for net address update from main CPU CPU 00384 if ( spi_buf[ byte_cnt ] == NO_UPDATE ) 00385 { 00386 net_addrs_chng = NO_UPDATE; 00387 } 00388 else if ( net_addrs_chng != UPDATED ) 00389 { 00390 net_addrs_chng = spi_buf[ byte_cnt ]; 00391 } 00392 } 00393 fsvr.put_byte( idx, spi_buf[ byte_cnt ] ); // save byte read from SPI 00394 } 00395 led3 = 0; 00396 } 00397 else // checksum failed 00398 { 00399 led3 = 1; 00400 } 00401 led4 = 0; 00402 } // end else not READ_IO 00403 } // end if ( (spiv & 0xfe) == (LPC1768 & 0xfe) ) 00404 return buf_idx; 00405 } 00406 00407 /****************************************************************************/ 00408 /* chk_SPI_active: 00409 * Description: checks spi_count has been updated in SPI interrupt 00410 * to be called by timer, independently of SPI interrupt 00411 * Globals used: spi_active, spi_count 00412 * Parameters: NONE 00413 * Returns: NONE 00414 */ 00415 /****************************************************************************/ 00416 void chk_SPI_active( void ) 00417 { 00418 if ( spi_count == INV_SPI_CNT ) 00419 { 00420 spi_active = false; // flag SPI failure 00421 } 00422 else 00423 { 00424 spi_count = INV_SPI_CNT; // set to be overwritten by next SPI update 00425 spi_active = true; // SPI updated OK 00426 } 00427 } 00428 00429 /****************************************************************************/ 00430 /* get_hex_mask: 00431 * Description: converts long mask4_IO_registers to hexadecimal string 00432 * Globals used: mask4_IO_registers, hex_mask 00433 * Parameters: NONE 00434 * Returns: pointer to hex_mask 00435 */ 00436 /****************************************************************************/ 00437 char * get_hex_mask( void ) 00438 { 00439 unsigned char i; 00440 for ( i = 0; i < 12; i++ ) 00441 { 00442 hex_mask[ i ] = 0; 00443 } 00444 sprintf(hex_mask, "%08x", mask4_IO_registers); 00445 return hex_mask; 00446 } 00447 00448 /****************************************************************************/ 00449 /* convert2decimal: 00450 * Description: converts hexadecimal string to long mask4_IO_registers 00451 * Globals used: mask4_IO_registers 00452 * Parameters: u8_t * uc_ptr: pointer to hex-formatted mask string 00453 * u16_t len: length of string 00454 * Returns: NONE 00455 */ 00456 /****************************************************************************/ 00457 void convert2decimal( u8_t * uc_ptr, u16_t len ) 00458 { 00459 char ch, i; 00460 unsigned long temp_sum = 0; 00461 00462 for ( i = 0; i < len; i++ ) 00463 { 00464 ch = (char)*(uc_ptr + i); 00465 if ( islower( ch ) ) 00466 { 00467 ch = ch - 'a' + 10; 00468 } 00469 else if ( isupper( ch ) ) 00470 { 00471 ch = ch - 'A' + 10; 00472 } 00473 else if ( isdigit( ch ) ) 00474 { 00475 ch = ch - '0'; 00476 } 00477 else 00478 { 00479 temp_sum = 0xfffffff; 00480 ch = 15; 00481 i = len; // end on error; 00482 } 00483 temp_sum = 16 * temp_sum + ch; 00484 } 00485 mask4_IO_registers = temp_sum; 00486 } 00487 00488 void send_ram( void ) 00489 { 00490 static int idx; 00491 char i; 00492 00493 if ( (idx & 0x7ff) == 0 ) 00494 { 00495 pc.printf("CMD data %x", idx ); 00496 for ( i = 0; i < MAX_CMD; i++ ) 00497 { 00498 pc.printf(", %x", cmd_buf[ i ] ); 00499 } 00500 pc.printf( "\r\n" ); 00501 pc.printf("RAM data %x", idx & 0x7ff ); 00502 for ( i = 0; i < 8; i++ ) 00503 { 00504 pc.printf(", %x", fsvr.get_byte(idx++ & 0x7ff) ); 00505 } 00506 pc.printf( "\r\n" ); 00507 } 00508 else 00509 { 00510 pc.printf("RAM data %x", idx & 0x7ff ); 00511 for ( i = 0; i < 8; i++ ) 00512 { 00513 pc.printf(", %x", fsvr.get_byte(idx++ & 0x7ff) ); 00514 } 00515 pc.printf( "\r\n" ); 00516 } 00517 } 00518 00519 /****************************************************************************/ 00520 /* write_addrs_to_file: 00521 * Description: Writes net addresses to /webfs/net_adrs.txt 00522 * Globals used: NET_ADRS_FILE 00523 * Parameters: NONE 00524 * Returns: 0 if OK, 1 if failed to open files 00525 */ 00526 /****************************************************************************/ 00527 int write_addrs_to_file() 00528 { 00529 FILE *fp = fopen( NET_ADRS_FILE, "w" ); 00530 if(!fp) { 00531 fprintf(stderr, "\r\nFile /webfs/net_adrs.txt could not be opened to write!\r\n"); 00532 exit(1); 00533 } 00534 else // file opened OK, so save addresses 00535 { 00536 fprintf(fp, "IP address %u.%u.%u.%u \r\n", ip_ad[0],ip_ad[1],ip_ad[2],ip_ad[3]); 00537 fprintf(fp, "Address mask %u.%u.%u.%u \r\n", msk_ad[0],msk_ad[1],msk_ad[2],msk_ad[3]); 00538 fprintf(fp, "Gwy address %u.%u.%u.%u \r\n", gwy_ad[0],gwy_ad[1],gwy_ad[2],gwy_ad[3]); 00539 fprintf(fp, "DNS address %u.%u.%u.%u \r\n", dns_ad[0],dns_ad[1],dns_ad[2],dns_ad[3]); 00540 fprintf(fp, "%s\r\n", snmp_publiccommunity ); // v0.98: save community string 00541 fprintf(fp, "Trap host address %u.%u.%u.%u \r\n", th_ad[0],th_ad[1],th_ad[2],th_ad[3]); 00542 fprintf(fp, "%u \r\n", mask4_IO_registers ); 00543 fclose(fp); 00544 } // file opened OK 00545 return 0; 00546 } 00547 00548 /****************************************************************************/ 00549 /* copy_trap_host_address: v0.99 00550 * Description: Copies src array to th_ad 00551 * Globals used: th_ad 00552 * net_addrs_chng set to UPDATED 00553 * Parameters: IN: unsigned char * src - source array of 4 bytes 00554 * Returns: NONE 00555 */ 00556 /****************************************************************************/ 00557 void copy_trap_host_address( unsigned char * src ) 00558 { 00559 unsigned char i; 00560 for ( i = 0; i < 4; i++ ) 00561 { 00562 if ( src[ i ] != 0 ) 00563 { 00564 { 00565 th_ad[ i ] = src[ i ]; 00566 } 00567 } 00568 } 00569 net_addrs_chng = UPDATED; 00570 } 00571 00572 /****************************************************************************/ 00573 /* copy_net_addresses_from: v0.93 00574 * Description: Copies src array to ip_ad, msk_ad, gwy_ad, dns_ad 00575 * Globals used: ip_ad, msk_ad, gwy_ad, dns_ad 00576 * Parameters: IN: unsigned char * src - source array of 16 bytes 00577 * Returns: NONE 00578 */ 00579 /****************************************************************************/ 00580 void copy_net_addresses_from( unsigned char * src ) 00581 { 00582 unsigned char i; 00583 for ( i = 0; i < 4; i++ ) 00584 { 00585 if ( src[ i ] != 0 ) 00586 { 00587 ip_ad[ i ] = src[ i ]; 00588 } 00589 } 00590 for ( i = 4; i < 8; i++ ) 00591 { 00592 if ( src[ i ] != 0 ) 00593 { 00594 msk_ad[ i-4 ] = src[ i ]; 00595 } 00596 } 00597 for ( i = 8; i < 12; i++ ) 00598 { 00599 if ( src[ i ] != 0 ) 00600 { 00601 gwy_ad[ i-8 ] = src[ i ]; 00602 } 00603 } 00604 for ( i = 12; i < 16; i++ ) 00605 { 00606 if ( src[ i ] != 0 ) 00607 { 00608 dns_ad[ i-12 ] = src[ i ]; 00609 } 00610 } 00611 } 00612 00613 /****************************************************************************/ 00614 /* parse4numbers: 00615 * Description: Reads file fr and separates out max_num numbers delimited by 00616 * any non-digit characters 00617 * Globals used: 00618 * Parameters: IN: FILE *fr - file to read 00619 * OUT: unsigned char * numb - array of numbers read 00620 * IN: unsigned char max_num - number of numbers to read 00621 * Returns: NONE 00622 */ 00623 /****************************************************************************/ 00624 void parse4numbers( FILE *fr, unsigned char * numb, unsigned char max_num ) 00625 { 00626 int c, i, new_num; 00627 char digit_found = false; 00628 char number_completed = false; 00629 00630 i = new_num = 0; 00631 while ( ((c = fgetc(fr)) != EOF) && (i < max_num) ) 00632 { 00633 numb[ i ] = 0; 00634 if ( c < '0' || c > '9' ) 00635 { // not a numeric character 00636 if ( digit_found ) 00637 { 00638 number_completed = true; 00639 if ( i >= (max_num - 1) ) 00640 { // max_num distinct numbers read 00641 break; 00642 } 00643 } 00644 } 00645 else // numeric character 00646 { 00647 digit_found = true; 00648 if ( number_completed ) 00649 { // save number into array 00650 numb[ i++ ] = new_num & 0xff; 00651 new_num = 0; 00652 } 00653 new_num = 10*new_num + c - '0'; 00654 number_completed = false; 00655 } // else numeric character 00656 } // end while 00657 if ( (number_completed || (c == EOF)) && (i < max_num) ) 00658 { // 0.80: save last number read 00659 numb[ i++ ] = new_num & 0xff; 00660 } 00661 } 00662 00663 /****************************************************************************/ 00664 /* read_addrs_from_file: 00665 * Description: Reads data from /webfs/net_adrs.txt 00666 * Globals used: NET_ADRS_FILE 00667 * Parameters: NONE 00668 * Returns: 0 if OK, 1 if failed to open files 00669 */ 00670 /****************************************************************************/ 00671 int read_addrs_from_file() 00672 { 00673 int c, i; 00674 unsigned char numbers[17]; 00675 char community[ MAX_COMMUNITY ]; 00676 00677 for ( i = 0; i < MAX_COMMUNITY; i++ ) 00678 { 00679 community[ i ] = 0; 00680 } 00681 FILE *fr = fopen( NET_ADRS_FILE, "r" ); 00682 if(!fr) { 00683 fprintf(stderr, "\r\nFile /webfs/net_adrs.txt could not be opened!\r\n"); 00684 exit(1); 00685 } 00686 else // file opened OK 00687 { 00688 parse4numbers( fr, numbers, 16 ); 00689 copy_net_addresses_from( numbers ); // v0.93: new subroutine 00690 /* v0.98: now read the community string from the file after reading end of line */ 00691 while ( ((c = fgetc(fr)) != EOF) && ((c == ' ') || (c == '\r') || (c == '\n')) ); 00692 i = 0; 00693 do 00694 { 00695 c = (char)c; 00696 if ( (c != ' ') && (c != '\r') && (c != '\n') && (i < MAX_COMMUNITY-1) ) 00697 { 00698 community[ i++ ] = c; 00699 } 00700 else // string terminated 00701 { 00702 break; 00703 } 00704 } while ( ((c = fgetc(fr)) != EOF) && (c != 0) ); 00705 parse4numbers( fr, numbers, 4 ); // now read in Trap host address 00706 copy_trap_host_address( numbers ); 00707 fscanf( fr, "%lu", &mask4_IO_registers ); 00708 fclose(fr); 00709 } // file opened OK 00710 if ( strlen(community) > 3 ) 00711 { // string length 4 to 20 characters 00712 strcpy( snmp_publiccommunity, community ); 00713 pc.printf("community: %s %d \r\n", snmp_publiccommunity, strlen(snmp_publiccommunity) ); 00714 } 00715 else 00716 { 00717 pc.printf("community too short: %s %d \r\n", community, strlen(community) ); 00718 } 00719 return 0; 00720 } 00721 00722 /****************************************************************************/ 00723 /* blinker: 00724 * Description: Blinks led_link for 10 calls 00725 * Globals used: led_link, blink_led, 00726 * Parameters: NONE 00727 * Returns: NONE 00728 */ 00729 /****************************************************************************/ 00730 void blinker( void ) 00731 { 00732 static unsigned char blink_cnt; 00733 00734 if ( blink_led && blink_cnt++ < 10 ) 00735 { 00736 led_link = !led_link; 00737 } 00738 else 00739 { 00740 blink_cnt = 0; 00741 blink_led = false; 00742 } 00743 } 00744 00745 /****************************************************************************/ 00746 /* init_traps: 00747 * Description: initialises trap flags and sends cold start trap when done 00748 * Globals used: trap_init set true after cold start 00749 * Parameters: NONE 00750 * Returns: NONE 00751 */ 00752 /****************************************************************************/ 00753 void init_traps( void ) 00754 { 00755 snmp_coldstart_trap(); 00756 trap_init = true; 00757 } 00758 00759 /****************************************************************************/ 00760 /* check_all_traps: 00761 * Description: test states for all trap events and sends appropriate trap 00762 * Globals used: led2: set to ON if SPI not active 00763 * byte_changed, all_IO_updated, spi_active 00764 * Parameters: NONE 00765 * Returns: NONE 00766 */ 00767 /****************************************************************************/ 00768 void check_all_traps( void ) 00769 { 00770 if ( !led1 && (fsvr.get_byte( H_H_LINK_LSBYTE ) || fsvr.get_byte( H_H_LINK_MSBYTE )) ) 00771 { // change of link state 00772 led1 = 1; // flag: link is up when led1 on 00773 snmp_linkup_trap(); 00774 } 00775 else if ( (fsvr.get_byte( H_H_LINK_LSBYTE ) == 0) && (fsvr.get_byte( H_H_LINK_MSBYTE ) == 0) && led1 ) 00776 { // change of link state 00777 led1 = 0; 00778 snmp_linkdown_trap(); 00779 } 00780 if ( byte_changed && all_IO_updated ) 00781 { // any masked-in I/O register changed 00782 f3kIOchange_trap(); 00783 all_IO_updated = byte_changed = false; 00784 } 00785 if ( spi_active && led2 ) 00786 { 00787 led2 = 0; // flag: SPI is up when led2 off 00788 snmp_SPIup_trap(); 00789 } 00790 else if ( !spi_active && !led2 ) 00791 { 00792 led2 = 1; // flag: SPI is down when led2 on 00793 snmp_SPIdown_trap(); 00794 } 00795 } 00796 00797 00798 /****************************************************************************/ 00799 /****************************************************************************/ 00800 int main() { 00801 int idx; 00802 00803 new_cmd_idx = 0xaa; 00804 for ( idx = 0; idx < MAX_CMD; idx++ ) 00805 { // put meaningful non-valid data in cmd_buf 00806 cmd_buf[ idx ] = new_cmd_idx; 00807 } 00808 pc.printf("=================== Version %s ====================\r\n", snmp_fw_version); 00809 // pc.printf("Press any key to start...\r\n"); 00810 led3 = 1; 00811 00812 FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path 00813 FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path 00814 read_addrs_from_file(); 00815 00816 /* Force fixed Ethernet address */ 00817 EthernetNetIf eth( 00818 IpAddr( ip_ad[0], ip_ad[1], ip_ad[2], ip_ad[3] ), //IP Address 00819 IpAddr( msk_ad[0], msk_ad[1], msk_ad[2], msk_ad[3] ), //Network Mask 00820 IpAddr( gwy_ad[0], gwy_ad[1], gwy_ad[2], gwy_ad[3] ), //Gateway 00821 IpAddr( dns_ad[0], dns_ad[1], dns_ad[2], dns_ad[3] ) //DNS Server 00822 ); 00823 00824 Base::add_rpc_class<DigitalOut>(); 00825 #if 0 00826 Base::add_rpc_class<SPI_Server>(); 00827 #endif 00828 00829 // pc.getc(); // wait for keyboard 00830 led3 = 0; 00831 00832 strcpy( (char *)syslocation, (const char *)syslocation_default ); 00833 sysloc_len = strlen( (const char *)syslocation ); 00834 snmp_set_syslocation( syslocation, &sysloc_len ); 00835 00836 pc.printf("\r\nSetting up...\r\n"); 00837 EthernetErr ethErr = eth.setup(); 00838 if( ethErr ) 00839 { 00840 pc.printf("Error %d in Ethernet setup.\r\n", ethErr); 00841 // return -1; 00842 } 00843 else // Ethernet Setup OK 00844 { 00845 mip = eth.getIp(); 00846 led3 = 1; 00847 led_speed = LPC_GPIO1->FIOPIN & (1<<26); // GPIO1.26 = "LED_SPEED". 00848 led_link = LPC_GPIO1->FIOPIN & (1<<25); // GPIO1.25 = "LED_LINK". 00849 pc.printf("\r\nEthernet Setup OK\r\n"); 00850 00851 svr.addHandler<RPCHandler>("/rpc"); 00852 svr.addHandler<FSHandler>("/files"); 00853 svr.addHandler<FSHandler>("/"); //Default handler 00854 //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm 00855 00856 // svr.bind(80); disable for SNMP development 00857 00858 // snmp_init(); done in lwip/core/init.c 00859 00860 pc.printf("Listening...\n\r"); 00861 00862 snmp_trap_dst_ip_set( ONLY_TRAP, (ip_addr_t *)&th_ad[0] ); 00863 snmp_trap_dst_enable( ONLY_TRAP, ENABLED ); 00864 snmp_coldstart_trap(); // to force ARP call 00865 00866 led3 = led4 = 0; 00867 spi_slave.format(8,3); // Setup: byte data, high steady state clock, 2nd edge capture 00868 00869 sys_tick.attach( &snmp_inc_sysuptime, 0.01 ); 00870 spi_tick.attach( &chk_SPI_active, 60.0 ); 00871 comms_tick.attach( &blinker, 0.07 ); // tick to blink activity LED 00872 cold_start_delay.attach( &init_traps, 30.0 ); // send cold_start trap after 30 seconds 00873 00874 00875 // Listen indefinitely to Ethernet and SPI 00876 while ( true ) 00877 { 00878 Net::poll(); // check for Ethernet requests 00879 00880 if ( trap_init ) 00881 { 00882 check_all_traps(); 00883 } 00884 00885 if( spi_slave.receive() ) { 00886 // Data available - needs chip select line to activate 00887 get_SPI_data( cmd_buf ); 00888 } // end if( spi_slave.receive() ) 00889 if ( net_addrs_set ) 00890 { // v0.99: address changed from SNMP i/f 00891 write_addrs_to_file(); 00892 net_addrs_set = false; 00893 } 00894 } // end while ( true ) 00895 00896 } // else Ethernet Setup OK 00897 return 0; 00898 }
Generated on Tue Jul 12 2022 19:17:29 by
1.7.2