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 (×tamp, &(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_ */
SchallRauch schrieb: > aber ich bekomme bei jeder Abfrage keine korrekte Zeit zurück, sondern > ein konstant falsche Zeit, Beispiel?
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])
|
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.
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.
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?
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.