2016-09-01 2 views
0

저는 프로그래밍이되어있어 많은 C 라이브러리를 사용할 수 없습니다.NTP는 1900 년 1 월 1 일부터 현재까지의 초로 변환합니다.

저는 이제 NTP 프로토콜을 사용하여 1900 년 1 월 1 일 이후의 초 수를 갖습니다. 이제는 의미있는 타임 스탬프로 변환해야합니다. 나는 그것에 대해 조사 해왔고이 @R .. 구현을 발견했다.

http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c?h=v0.9.15

나는 그것을 사용하려했지만 나는 올바른 결과를받지 못했습니다.

누군가가 함수의 첫 번째 인수를 알고 있습니까? 저는 1900 년 1 월 1 일부터 1970 년 1 월 1 일 이후의 초 수를 전달하려고 시도했지만 아무도 예상대로 작동하지 않았습니다.

내가 실행 해요 코드는 다음과 같습니다

#define NTP_PACKET_SIZE   48 
uint8_t packetBuffer[ NTP_PACKET_SIZE]; 
typedef struct tempo{ 
    int tm_sec;   /* seconds, range 0 to 59   */ 
    int tm_min;   /* minutes, range 0 to 59   */ 
    int tm_hour;  /* hours, range 0 to 23    */ 
    int tm_mday;  /* day of the month, range 1 to 31 */ 
    int tm_mon;   /* month, range 0 to 11    */ 
    int tm_year;  /* The number of years since 1900 */ 
    int tm_wday;  /* day of the week, range 0 to 6 */ 
    int tm_yday;  /* day in the year, range 0 to 365 */ 
    int tm_isdst;  /* daylight saving time    */ 
} tim; 

tim * t; 

static returnTypes_t bsdUdpClient(uint16_t AddrSize){ 

    int16_t Status = (int16_t) ZERO; 

     memset(packetBuffer, 0, NTP_PACKET_SIZE); 

     // Initialize values needed to form NTP request 
      packetBuffer[0] = 0xE3; //0b11100011; // LI, Version, Mode 
      packetBuffer[1] = 0x00;  // Stratum, or type of clock 
      packetBuffer[2] = 0x06;  // Polling Interval 
      packetBuffer[3] = 0xEC; // Peer Clock Precision 
     // 8 bytes of zero for Root Delay & Root Dispersion 
      packetBuffer[12] = 49; 
      packetBuffer[13] = 0x4E; 
      packetBuffer[14] = 49; 
      packetBuffer[15] = 52; 

    SockID = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, (uint32_t) ZERO); 
    if (SockID < (int16_t) ZERO) 
     return (SOCKET_ERROR); 

    Status = sl_SendTo(SockID, packetBuffer, NTP_PACKET_SIZE * sizeof(uint8_t), (uint32_t) ZERO, (SlSockAddr_t *) &Addr, AddrSize); 

    /*Check if 0 transmitted bytes sent or error condition*/ 
    if (Status <= (int16_t) ZERO) { 
     sl_Close(SockID); 
     return (SEND_ERROR); 
    } 
    else 
     printf("request sent successfully\n\r"); 

    /* receive the reply from the server*/ 
    Status = sl_RecvFrom(SockID, packetBuffer, NTP_PACKET_SIZE * sizeof(uint8_t), (uint32_t) ZERO, (SlSockAddr_t *) &Addr, &AddrSize); 
    if (Status < (int16_t) ZERO){ 
     printf("error - no bytes received: %d\n\r", (int16_t)Status); 
     return SOCKET_ERROR; 
    } 
    else 
     printf("reply received\n\r"); 

    Status = sl_Close(SockID); 
    if (Status < 0) 
     printf("problem on sl_Close\n\r"); 

    uint8_t index3 = packetBuffer[40]; 
    uint8_t index2 = packetBuffer[41]; 
    uint8_t index1 = packetBuffer[42]; 
    uint8_t index0 = packetBuffer[43]; 

    uint16_t highWord = index3 << 8 | index2; 
    uint16_t lowWord = index1 << 8 | index0; 

    uint32_t secondsSince1900 = highWord << 16 | lowWord; 

    printf("Seconds since 1 Janeiro de 1900: %lu\n\r", secondsSince1900); 
    printf("Seconds since 1 Janeira de 1970: %lu\n\r", secondsSince1900 - 2208988800ul); 


    if(secs_to_date((secondsSince1900 - 2208988800ul) , t)!=0) 
     printf("impossible to convert\n\r"); 

    printf("year: %d; month: %d; day:%d; hour:%d; minuts: %d; seconds:%d\n\r", t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); 

    return (STATUS_OK); 

    } 

따라서, 예를 들어, 내가 결과를 기다리고 있었다, 몇 minuts 전에 코드를 runned

년 : 2016, 월 : 9; 일 : 1; 시간 : 9; minuts : 20; 초 : 56

(예를 들어)하지만 내가 가진이

년 : 32281; 월 : 32279; 하루 : 32277; 시간 : 32275; minuts : 32221; 초 : 537001984

+0

수 너는 [mcve]를 게시합니까? –

+0

일부 입력의 경우 예상 출력은 무엇이며 실제 출력은 무엇입니까? –

+0

그 @ JoachimPileborg에 대한 죄송합니다, 나는 예상/실제 출력을 추가했습니다. – lmbcerqueira

답변

2

t 어디에서나 유효한 지점을 지정합니까? 초기화되지 않은 전역 변수이므로 0으로 초기화되므로 포인터가 NULL으로 초기화됩니다. null 포인터를 역 참조하면 정의되지 않은 동작이됩니다.

대신 포인터로 선언의 단지 정상이 아닌 포인터 변수로 선언 : 당신이 변환 함수를 호출 할 때

tim t; 

그런 다음 운영자 & 주소의 사용

secs_to_date((secondsSince1900 - 2208988800ul) , &t) 
//            ^
//            | 
// Notice the use of the address-of operator here 
관련 문제