Zeitabfrage (SNTP) periodisch ausführen



  • Hallo,

    ich habe als Anfänger einige Schwierigkeiten folgendes Programm periodisch als Schleife abzuarbeiten.
    Es handelt sich um ein tool des IPC@Chip von Beck und liefert diesem Zeit und Datum eines Zeitservers, allerdings im Normalfall eben nur einmal bei starten des Prgorammes.

    // Defines
    /*************************************************************************/
    #define _DEBUG_
    
    #define TIMEZONE 6
    #define CLOCK_OFFSET_1970 2208988800l
    
    /*************************************************************************/
    // NTP structure declaration
    /*************************************************************************/
    typedef struct _SNTPHDR
    {
    	unsigned char LI_VN_Mode;
       unsigned char Stratum;
       unsigned char Poll;
       unsigned char Precision;
       unsigned long Root_Delay;
       unsigned long Root_Dispersion;
       unsigned long Reference_Identifier;
       unsigned long Reference_Timestamp1;
       unsigned long Reference_Timestamp2;
       unsigned long Originate_Timestamp1;
       unsigned long Originate_Timestamp2;
       unsigned long Receive_Timestamp1;
       unsigned long Receive_Timestamp2;
       unsigned long Transmit_Timestamp1;
       unsigned long Transmit_Timestamp2;
    } SNTPHDR;
    
    /*************************************************************************/
    // Variables
    /*************************************************************************/
    SNTPHDR sntphdr, recvhdr;
    int error;
    int sd;
    struct sockaddr_in saddr, addr;
    unsigned long ip;
    unsigned long datetime, tmp;
    struct date dt;
    struct time tm;
    char *month[] = {"---", "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    union REGS inregs, outregs;
    int result;
    /*************************************************************************/
    // Set the version in the NTP structure
    /*************************************************************************/
    void setversion(unsigned char version, SNTPHDR *hdr)
    {
       if (hdr == NULL) return;
    	hdr->LI_VN_Mode |= ((version & 0x07) << 3);
    }
    
    /*************************************************************************/
    // Set the mode in the NTP structure
    /*************************************************************************/
    void setmode(unsigned char mode, SNTPHDR *hdr)
    {
       if (hdr == NULL) return;
    	hdr->LI_VN_Mode |= (mode & 0x07);
    }
    
    int main(int argc, char **argv)
    {
       while (1)
       {
       api_sleep (10000);
    
       if (argc != 2)
       {
       	printf("\nUsage: %s <server-ip>\n", argv[0]);
          return 0;
       }
    
       // prepare the structures
    	memset(&sntphdr, 0, sizeof(SNTPHDR));
    	memset(&recvhdr, 0, sizeof(SNTPHDR));
       setversion(3, &sntphdr);
       setmode(3, &sntphdr);
    
       // send request to NTP server and receive response
    
       sd = opensocket(SOCK_DGRAM, &error);
       if (sd == API_ERROR)
       {
          #ifdef _DEBUG_
          printf("\nOpen socket error: %d!!!\n", error);
          #endif
          return 0;
       }
       inet_addr(argv[1], &ip); // parameter 1 = server ip address
       saddr.sin_family      = AF_INET;
       saddr.sin_port        = htons(123); // NTP port 123
       saddr.sin_addr.s_addr = ip;
       result = sendto(sd, (char*)&sntphdr, sizeof(SNTPHDR), MSG_BLOCKING, (struct sockaddr*)&saddr, &error);
       if (result == API_ERROR)
       {
          #ifdef _DEBUG_
          printf("\nSend error: %d!!!\n", error);
          #endif
          return 0;
       }
       memset(&addr, 0, sizeof(struct sockaddr));
       addr.sin_family = AF_INET;
       result = recvfrom(sd, (char*)&recvhdr, sizeof(SNTPHDR), MSG_TIMEOUT, 10000l, (struct sockaddr*)&addr, &error);
       closesocket(sd, &error);
       if (result == 0)
       {
          #ifdef _DEBUG_
          printf("\nTimeout!!!\n");
          #endif
          return 0;
       }
    
       // date and time translation
       datetime = recvhdr.Transmit_Timestamp1;
       tmp = (datetime & 0xFF000000l) >> 24;  // *******************************
       tmp |= (datetime & 0x00FF0000l) >> 8;  //  translate it in the right
       tmp |= (datetime & 0x0000FF00l) << 8;  //  format
       tmp |= (datetime & 0x000000FFl) << 24; // *******************************
       datetime = tmp - CLOCK_OFFSET_1970;
       unixtodos(datetime, &dt, &tm);
       printf("Time: %02d:%02d:%02d\n", tm.ti_hour+TIMEZONE, tm.ti_min, tm.ti_sec);
       printf("Date: %d %s %d\n", dt.da_day, month[dt.da_mon], dt.da_year);
    
       // set date
       inregs.h.ah = 0x2B;
       inregs.x.cx = dt.da_year;
       inregs.h.dh = dt.da_mon;
       inregs.h.dl = dt.da_day;
       int86(0x21, &inregs, &outregs);
    
       // set time
       inregs.h.ah = 0x2D;
       inregs.h.ch = tm.ti_hour+TIMEZONE;
       inregs.h.cl = tm.ti_min;
       inregs.h.dh = tm.ti_sec;
       int86(0x21, &inregs, &outregs);
    
    	return 0;
       }
    }
    

    Die While (1) - Schleife in der main wurde von mir implementiert. Danach läuft das Programm wie gehabt einmal ordnungsgemäß, liefert aber bei den weiteren Durchläufen immer Error.

    Kann mir hier jemand weiterhelfen?

    Vielen Dank


Anmelden zum Antworten