Go Down

Topic: Help intergrating some code i found (Ethernet Code).... (Read 2542 times) previous topic - next topic

cjdelphi

I'm very much in need of a routine to get the IP address (remote IP so i can do a basic IP filter)

Re: Get client's IP address from ethernet server?

http://www.tnhsmith.net/Misc/Ethernet-bh-mods-20100510.zip

Quote

Here's a note from Brett, there also some code on the Rogue Robotics site that uses the getRemoteIP call.  Thanks once again Brett!

Here's the revised "Ethernet" library.  It's definitely not official, but I will be working on it over time.  I'll get it into a code repository soon enough and integrate all of the improvements.

To get the remote IP address, you need to call getRemoteIP() when you have the Client class from your server.available() call.

e.g.

Code: [Select]

Server s;
Client c;
byte rip[4];

c = s.available();

if (c)
{
  c.getRemoteIP(rip);
  // rip[] now has 4 quads of the remote IP address }
  ...

Back to top    

I want that one function (get the ip address function) and merge it in with the Ethernet Library, but i'm not sure about C++ how's
the header and .cpp file come together? is it even possible to do this now on Arduinio 1?

Thanks....

Marek080

Depends on the hardware you are using. For the W5100 on the ethernet shield you have to look up the specs and search for a routine to retrieve the ip address. This chip implements quite a lot in hardware and has functions for filtering build in. If there are some matching functions to call for the W5100 this should be possible - needs some understanding of the source of the ethernet library and a plan how to realize it with the W5100. Coding is then not so complicated.
loved the 68000 assembler back then and now I have to deal with THIS 8 bit thingy

cjdelphi

#2
Apr 07, 2012, 12:04 pm Last Edit: Apr 07, 2012, 12:07 pm by cjdelphi Reason: 1
The board i'm using is this one...

http://www.freetronics.com/collections/all-products/products/etherten

Quote
The EtherTen is a 100% Arduino compatible board that can talk to the world. Do Twitter updates automatically, serve web pages, connect to web services, display sensor data online, and control devices using a web browser. The Freetronics EtherTen uses the same ATmega328P as the Duemilanove and the same Wiznet W5100 chip used by the official Arduino Ethernet Shield, so it's 100% compatible with the Ethernet library and sketches. Any project you would previously have built with an Arduino and an Ethernet shield stacked together, you can now do all in a single, integrated board.


I'm talking about modifying and which files to modify that are in arduion1\libraries\Ethernet....

Not sure which parts i need to copy and paste from (from the zip) and to where....

dxw00d

Take a backup of the existing ethernet library files, then try copying all the files from the zip into the existing folder.

cjdelphi

not going to work due to the updated ethernet code shipped with Arduino Version 1.

I need to literally copy and paste the functions out of the .h/cpp files into the new ones... someone should know C++ well enough to help me get an idea.

dxw00d


cjdelphi

it's really that convoluted to add 1 single function?


dxw00d

#7
Apr 07, 2012, 12:49 pm Last Edit: Apr 07, 2012, 12:59 pm by dxw00d Reason: 1
It can be, if that function has dependencies. Network communication is not a trivial thing to implement.

cjdelphi

Code: [Select]

#define Sn_PORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0004)
/**
@brief Peer MAC register address
*/
#define Sn_DHAR0(ch) (CH_BASE + ch * CH_SIZE + 0x0006)
/**
@brief Peer IP register address
*/
#define Sn_DIPR0(ch) (CH_BASE + ch * CH_SIZE + 0x000C)
/**


So I need to add the address 0c

Code: [Select]

  __GP_REGISTER8 (MR,     0x0000);    // Mode
  __GP_REGISTER_N(GAR,    0x0001, 4); // Gateway IP address
  __GP_REGISTER_N(SUBR,   0x0005, 4); // Subnet mask address
  __GP_REGISTER_N(SHAR,   0x0009, 6); // Source MAC address
  __GP_REGISTER_N(SIPR,   0x000F, 4); // Source IP address
  __GP_REGISTER8 (IR,     0x0015);    // Interrupt
  __GP_REGISTER8 (IMR,    0x0016);    // Interrupt Mask
  __GP_REGISTER16(RTR,    0x0017);    // Timeout address
  __GP_REGISTER8 (RCR,    0x0019);    // Retry count
  __GP_REGISTER8 (RMSR,   0x001A);    // Receive memory size
  __GP_REGISTER8 (TMSR,   0x001B);    // Transmit memory size
  __GP_REGISTER8 (PATR,   0x001C);    // Authentication type address in PPPoE mode
  __GP_REGISTER8 (PTIMER, 0x0028);    // PPP LCP Request Timer
  __GP_REGISTER8 (PMAGIC, 0x0029);    // PPP LCP Magic Number
  __GP_REGISTER_N(UIPR,   0x002A, 4); // Unreachable IP address in UDP mode
  __GP_REGISTER16(UPORT,  0x002E);    // Unreachable Port address in UDP mode

//new one here?

    __GP_REGISTER_N(SIPR,   0x000C, 4); // Remote IP address  ??? now what






cjdelphi

I also found standalone code how to communicate over SPI.

Code: [Select]

I have written this code,trying to interface a PIC18F4550 with a wiznet811mj.The problem is that, when I'm trying to ping the wiz, the answer is destination unreachable.And those two leds(green and yellow are off).I've tried both..conecting with an utp cable to switch,and direct connection with crossover to my pc..the same problem.

#include <stdio.h>
#include "p18f4550.h"
#include <string.h>
#include <stdlib.h>


#pragma config FOSC   = INTOSC_HS
#pragma config WDT    = OFF
#pragma config MCLRE  = OFF
#pragma config LVP    = OFF
#pragma config PBADEN = OFF

#define WIZNET_WRITE_OPCODE 0xF0
#define WIZNET_READ_OPCODE 0x0F// Wiznet W5100 Register Addresses

#define MR   0x0000   // Mode Register
#define GAR  0x0001   // Gateway Address: 0x0001 to 0x0004
#define SUBR 0x0005   // Subnet mask Address: 0x0005 to 0x0008
#define SAR  0x0009   // Source Hardware Address (MAC): 0x0009 to 0x000E
#define SIPR 0x000F   // Source IP Address: 0x000F to 0x0012
#define RMSR 0x001A   // RX Memory Size Register
#define TMSR 0x001B   // TX Memory Size Register

#define DEL_1us          16
#define DEL_10ms  80000
#define DEL_1ms   8000

void InitializePIC(void);
void Delay(unsigned int N);
void SPI_Write(unsigned int addr,unsigned char data);
unsigned char SPI_Read(unsigned int addr);
void W5100_Init(void);

void InitializePIC(void)
{

  ADCON1 = 0X0F;
  TRISAbits.TRISA5 = 0; // NU STIU DACA E LEGAT ??

  TRISDbits.TRISD0=0;
  TRISDbits.TRISD1=0;
  TRISDbits.TRISD7=0;
  TRISCbits.TRISC0=0;//RESET

  PORTDbits.RD0=0;
  PORTDbits.RD1=0;
  PORTDbits.RD7=0;

  TRISCbits.TRISC7 = 0;  // SDO
  TRISBbits.TRISB0 = 1;  // SDI
  TRISBbits.TRISB1 = 0;  // Sck out in master mode

  SSPSTATbits.SMP = 0;//smp=0 AND CKE=1
  SSPSTATbits.CKE = 1;

  SSPCON1bits.SSPEN = 1;//enable SPI
  SSPCON1bits.WCOL  = 0;
  SSPCON1bits.SSPOV = 0;
  SSPCON1bits.CKP   = 0;

  SSPCON1bits.SSPM0 = 0;//Fosc/4
  SSPCON1bits.SSPM1 = 0;
  SSPCON1bits.SSPM2 = 0;
  SSPCON1bits.SSPM3 = 0;



  RCONbits.IPEN = 1;
  IPR1bits.SSPIP = 0;
  PIE1bits.SSPIE = 0;
  PIR1bits.SSPIF = 0;
  INTCON = 0xC0;
  OSCCON=0x72;// 8 mhz
}

void Delay(unsigned int N) {

  unsigned int i;
  for(i=0; i<N; i++);
   Nop();

}


void SPI_Write(unsigned int addr,unsigned char data)
{
  // Activate the CS pin
  PORTAbits.RA5 = 0;

// Start Wiznet W5100 Write OpCode transmission
  SSPBUF = WIZNET_WRITE_OPCODE;
  while(!PIR1bits.SSPIF);  // Start Wiznet W5100 Address High Bytes transmission
  PIR1bits.SSPIF = 0;

  SSPBUF = ((addr & 0xFF00) >> 8) ;  // Wait for transmission complete
  while(!PIR1bits.SSPIF);  // Start Wiznet W5100 Address Low Bytes transmission
  PIR1bits.SSPIF = 0;

  SSPBUF= addr & 0x00FF;  // Wait for transmission complete
  while(!PIR1bits.SSPIF); 
  PIR1bits.SSPIF = 0;

  SSPBUF = data;  // Wait for transmission complete
  while(!PIR1bits.SSPIF);
  PIR1bits.SSPIF = 0;

  // CS pin is not active

  PORTAbits.RA5 = 1;

}
unsigned char SPI_Read(unsigned int addr)
{
  // Activate the CS pin
PORTAbits.RA5 = 0;
  // Start Wiznet W5100 Read OpCode transmission

  SSPBUF = WIZNET_READ_OPCODE;  // Wait for transmission complete
  while(!PIR1bits.SSPIF);  // Start Wiznet W5100 Address High Bytes transmission
  PIR1bits.SSPIF = 0;

  SSPBUF = (addr & 0xFF00) >> 8;  // Wait for transmission complete
  while(!PIR1bits.SSPIF);  // Start Wiznet W5100 Address Low Bytes transmission
  PIR1bits.SSPIF = 0;

  SSPBUF = addr & 0x00FF;  // Wait for transmission complete
  while(!PIR1bits.SSPIF); 
  PIR1bits.SSPIF = 0;

// Send Dummy transmission for reading the data
  SSPBUF = 0x00;  // Wait for transmission complete
  while(!PIR1bits.SSPIF);
  PIR1bits.SSPIF = 0;
  // CS pin is not active

PORTAbits.RA5 = 1 ;

return(SSPBUF);
}



void W5100_Init(void)
{
  // Ethernet Setup
  unsigned char mac_addr[] = {0x00,0x08,0xDC,0x00,0x00,0x24};
  unsigned char ip_addr[] = {192,168,0,2};
  unsigned char sub_mask[] = {255,255,255,0};
  unsigned char gtw_addr[] = {192,168,0,1};

  PORTDbits.RD0=1;
  SPI_Write(MR,0x80);       

  SPI_Write(GAR + 0,gtw_addr[0]);
  SPI_Write(GAR + 1,gtw_addr[1]);
  SPI_Write(GAR + 2,gtw_addr[2]);
  SPI_Write(GAR + 3,gtw_addr[3]);
  Delay(DEL_1ms);

  SPI_Write(SAR + 0,mac_addr[0]);
  SPI_Write(SAR + 1,mac_addr[1]);
  SPI_Write(SAR + 2,mac_addr[2]);
  SPI_Write(SAR + 3,mac_addr[3]);
  SPI_Write(SAR + 4,mac_addr[4]);
  SPI_Write(SAR + 5,mac_addr[5]);
  Delay(DEL_1ms);

  SPI_Write(SUBR + 0,sub_mask[0]);
  SPI_Write(SUBR + 1,sub_mask[1]);
  SPI_Write(SUBR + 2,sub_mask[2]);
  SPI_Write(SUBR + 3,sub_mask[3]);
  Delay(DEL_1ms);

  SPI_Write(SIPR + 0,ip_addr[0]);
  SPI_Write(SIPR + 1,ip_addr[1]);
  SPI_Write(SIPR + 2,ip_addr[2]);
  SPI_Write(SIPR + 3,ip_addr[3]);
  Delay(DEL_1ms);


  // Setting the Wiznet W5100 RX and TX Memory Size, we use 2KB for Rx/Tx 4 channels
  SPI_Write(RMSR,0x55);
  SPI_Write(TMSR,0x55);
  PORTDbits.RD1=1;

}// Assign I/O stream to UART




////////////////


void main(void) {

  unsigned int i;
unsigned int gar0;

PORTCbits.RC0=0;
Delay(DEL_1us);
PORTCbits.RC0=1;
Delay(DEL_10ms);


InitializePIC();
  PORTAbits.RA5 = 1;

W5100_Init();



Bogdan Baluta





all i want is the Remote IP address (source what's the point, you set that yourserlf, your own local IP) i want the Remote IP :(

Thanks.

Marek080

How about making a plan before coding something? Have you found a function in the W5100 giving you the IP you are looking for? Or does the ethernet library have it already somewhere saved? First is understanding what's going on and then applying changes is easier. Some time ago I went trough the specs of the W5100 and if I remember correctly there was some kind of IP filtering on the chip, maybe it is what you need?
loved the 68000 assembler back then and now I have to deal with THIS 8 bit thingy

cjdelphi

I've figured out on serial input/output how it's done.

  __GP_REGISTER_N(GAR,    0x0001, 4); // Gateway IP address
  __GP_REGISTER_N(SUBR,   0x0005, 4); // Subnet mask address
  __GP_REGISTER_N(SHAR,   0x0009, 6); // Source MAC address
  __GP_REGISTER_N(SIPR,   0x000F, 4); // Source IP address

I want the Remote IP (eg, the person connected to the server)

that's not defined anywhere, but.

  __GP_REGISTER_N(SIPR,   0x000F, 4); // Source IP address

so in Libraries\ethernet\utility\w5100.h

so define my own

  __GP_REGISTER_N(RIPR,   0x000C, 4); // Remote IP address

so the bytes between 0C and 0F = Remote IP address (1.2.3.4);

now i'm lost because i can't find anything to do with the constant "SIPR" in any of the files, if i can i can copy it modify the memory address it sends to the wiznet chip
and then get back what i want..


inline void getIPAddress(uint8_t * addr);

void W5100Class::getIPAddress(uint8_t *_addr) {
  readSIPR(_addr);
}


(code from w5100.h)





SurferTim

This function is passed a pointer (_addr) to a 4 byte array. The ip address will be put in that array, high to low byte.

Code: [Select]
void W5100Class::getIPAddress(uint8_t *_addr) {
  readSIPR(_addr);
}


Marek080

#13
Apr 07, 2012, 05:45 pm Last Edit: Apr 07, 2012, 05:58 pm by Marek080 Reason: 1
After you added
Code: [Select]
__GP_REGISTER_N(RIPR,   0x000C, 4); // Remote IP address
to the public section of W5100Class you already are able to access the IP address via W5100.readRIPR(). Just add a place to store the IP and call the function at the proper moment
Code: [Select]
#include <Ethernet.h>
#include <utility/w5100.h>
...
uint8_t remoteIP[4];
...
W5100.readRIPR(remoteIP);

I'm using Arduino v1.0 and the used defines in W5100.h manage all you need - only the single line you figured out and an additional include to access the W5100 (exported global object) are necessary. Testing of the code is now up to you.

Explanation of the define:
Code: [Select]
#define __GP_REGISTER_N(name, address, size)      \
  static uint16_t write##name(uint8_t *_buff) {   \
    return write(address, _buff, size);           \
  }                                               \
  static uint16_t read##name(uint8_t *_buff) {    \
    return read(address, _buff, size);            \
  }

this one does the trick.

The preprocessor expands the following two lines
Code: [Select]
  __GP_REGISTER_N(RIPR,   0x000C, 4); // Remote IP address
  __GP_REGISTER_N(SIPR,   0x000F, 4); // Source IP address

into the following code before compiling
Code: [Select]
  static uint16_t writeRIPR(uint8_t *_buff) {
    return write(0x000C, _buff, 4);
  }
  static uint16_t readRIPR(uint8_t *_buff) {
    return read(0x000C, _buff, 4);
  }
  static uint16_t writeSIPR(uint8_t *_buff) {
    return write(0x000F, _buff, 4);
  }
  static uint16_t readSIPR(uint8_t *_buff) {
    return read(0x000F, _buff, 4);
  }
loved the 68000 assembler back then and now I have to deal with THIS 8 bit thingy

zoomkat

Some arduino server test code that has code ptched in to send the ip of a connected client to the serial monitor.

Code: [Select]

//zoomkat 12-8-11
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

#include <SPI.h>
#include <Ethernet.h>

byte rip[4];
//byte rip[] = {0,0,0,0};
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString;

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //enable serial data print
  Serial.begin(9600);
  Serial.println("server LED test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging
client.getRemoteIP(rip);
for (int bcount= 0; bcount < 4; bcount++)
     {
        Serial.print(rip[bcount], DEC);
        if (bcount<3) Serial.print(".");
     }

Serial.println();
          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println(); 
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
         
          client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>");
          client.println("<a href=\"/?off\" target=\"inlineframe\">OFF</a>");

          //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
          client.println("<IFRAME name=inlineframe style=\"display:none\" >");         
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}


Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Go Up