NTP-Request mit uIP

Gast #4090219
Lesenswert?
• ▲
▼
Hallo,


ich will mit dem uIP-Stack von Adam Dunkels eine NTP-Zeit abfrage 
machen, dass man per UDP machen muss.

Ich habe folgenden Code geschrieben, aber ich bekomme bei jeder Abfrage 
keine korrekte Zeit zurück, sondern ein konstant falsche Zeit, egal zu 
welchem Zeitpunkt ich abfrage. Ich vermute stark, dass das nicht die 
Zeit ist.

Hier ist der Code, vielleicht kann mir jemand, der sich mit uIP und NTP 
auskennt, den Fehler zu finden.





#include "ntp_getTime.h"
#include <avr/pgmspace.h>
#include <stdio.h>
#include <string.h>

#include "uip/uip.h"
#include "uip/timer.h"
#include "uip/pt.h"
#include "uip/uip_arp.h"



/*---------------------------------------------------------------------- 
-------------*/
/** \internal
 * The main UDP function.
 */
/*---------------------------------------------------------------------- 
-------------*/


PROGMEM const char NTP_Request[] = {0xd9, 0x00, 0x0a ,0xfa ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x01 ,0x04 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 
,0x00 ,0x00 ,0x00 ,0x00,
0x00 ,0x00 ,0xca ,0x1a ,0xab ,0x0c ,0x48 ,0x7a ,0xe1 ,0x47};


struct {
#define STATE_IDLE   0
#define STATE_NEW    1
#define STATE_ASKING 2
#define STATE_ERROR  3
  u8_t state;
} ntpstat;


static struct uip_udp_conn *ntp_conn = NULL;




// Prüfen, ob eine ntp-Anfrage vorliegt.
// Falls ja, ntp Request abschicken

void check_ntp_req(void)
{
  char *ntpp;

  if (ntpstat.state == STATE_NEW)           // neue NTP-Anfrage?
     {
     ntpstat.state = STATE_ASKING;          // als "laufend" markieren
     }

  else if (ntpstat.state == STATE_ASKING)        // laufende 
NTP-Anfrage?
     {

       ntpp = (char *)uip_appdata;
       memcpy_P (ntpp, NTP_Request, sizeof(NTP_Request));
       uip_udp_send (sizeof(NTP_Request));
       }
   else                                   // keine Zeitabfrage gestellt
     return;                              // weiter warten
}


/*---------------------------------------------------------------------- 
-------------*/
/** \internal
 * Called when new NTP data arrives.
 */
/*---------------------------------------------------------------------- 
-------------*/
void ntp_newdata(void)
{
  unsigned long timestamp = 0L;
  struct timedata
    {
    char dummy[40];
    unsigned long t_time;
    } *str_udp;

  str_udp = (struct timedata *)uip_appdata;

  if(ntpstat.state == STATE_ASKING)
    {
    // NTP request is now finished.
    ntpstat.state = STATE_IDLE;

  memcpy_P (&timestamp, &(str_udp->t_time), sizeof(timestamp));


 timestamp = timestamp - 0x83AA7E80; // the seconds from Jan 1, 1900 to 
Jan 1, 1970


}
  }



void ntp_init(void)
{
  ntpstat.state = STATE_IDLE;

  uip_ipaddr_t ntpIP;

  uip_ipaddr(ntpIP, 134,130,4,17);

    if(ntp_conn != NULL) {
      uip_udp_remove(ntp_conn);
    }

    ntp_conn = uip_udp_new(&ntpIP, HTONS(123));
    if(ntp_conn != NULL) {
  uip_udp_bind(ntp_conn, HTONS(123)); }
}

void GetNTP_Time(void)
{
  ntpstat.state = STATE_NEW;
}



void ntp_appcall(void)
{
  if(uip_udp_conn->rport == HTONS(123)) {  // NTP protocol

    if(uip_newdata()) {
      ntp_newdata();
      }

     if(uip_poll()) {
      check_ntp_req();
    }

  }

}



Der Code des Headers:



#ifndef NTP_GETTIME_H_
#define NTP_GETTIME_H_




#define UIP_UDP_APPCALL ntp_appcall


// initialize the ntp client
void ntp_init(void);

// called by uIP when it executes the ntp client
void ntp_appcall(void);


void GetNTP_Time(void);



#endif /* NTP_GETTIME_H_ */
Gast #4090370
Lesenswert?
• ▲
▼
ich würde sagen falscher Offset weil du über uip_appdata zugreifst, da 
ist der address+TCP Header schon abgezogen:
1
uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
also direkt die uip_buf Adresse benutzen oder für ohne Adressheader 
(6+6+2 Bytes) das Makro UDPBUF:
1
#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
Gast #4090389
Lesenswert?
• ▲
▼
Jojo S. schrieb:
> ich würde sagen falscher Offset weil du über uip_appdata
> zugreifst, da
> ist der address+TCP Header schon abgezogen:uip_appdata =
> &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
> also direkt die uip_buf Adresse benutzen oder für ohne Adressheader
> (6+6+2 Bytes) das Makro UDPBUF:#define UDPBUF ((struct uip_udpip_hdr
> *)&uip_buf[UIP_LLH_LEN])


Du sprichst hier bestimmt auf 40 dummy Bytes an. Das ist absichtlich so 
gewählt, weil die empfangenen Daten erst nach 40 Bytes der brauchbare 
timestamp steht.

Aber dennoch danke für den Tipp. Übrigens ist die Übertragung hier mit 
UDP.
Gast #4090421
Lesenswert?
• ▲
▼
Jojo S. schrieb:
> SchallRauch schrieb:
>> Aber dennoch danke für den Tipp. Übrigens ist die Übertragung hier mit
>> UDP.
>
> deshalb ja, du verwendest aber die uip_appdata Adresse und die ist für
> den TCP Header.


Achso,

kannst Du mir sagen, wie ich an die Daten des UDPBUF drankomme.

Soll ich es einfach als Pointer benutzen?
Gast #4090515
Lesenswert?
• ▲
▼
ok, war nicht ganz richtig was ich schrieb. Wenn ein UDP Paket kommt 
wird uip_appdata auf den Anfang der UDP Daten gesetzt. Wenn 40 der 
richtige Offset ab Nutzdatenanfang ist sollte das richtig sein.
Das define UIP_UDP ist gesetzt? Ansonsten mit Wireshark mitlauschen was 
hin- und hergeht.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.