www.pudn.com > Net_apps.rar > sntp.c


/* 
********************************************************************************************************* 
* Copyright 2003 Service & Quality Technology CO., LTD. ALL RIGHTS RESERVED. 
* This software is provided under license and contains proprietary and 
* confidential material which is the property of SQ tech. 
* 
* FileName     : sntp.c 
* Description  : 
* 
* 
* Version control: 
*  $Revision: 0.1 $    Date: 2004/06/03 12:00:00  daniel 
*      first implemetation 
* 
********************************************************************************************************* 
*/ 
 
 
 
#include "..\include\L3\net_apps\sntp\sntp.h" 
#include "..\include\L1\lwip\api.h" 
#include "..\include\L1\lwip\sys.h" 
#include "..\include\L2\system\timer.h" 
#include "..\include\L3\net_apps\IoEnv.h" 
#include "..\include\L3\net_apps\httpd\HttpServer.h" 
#include "..\include\L3\net_apps\dns\dns.h" 
/*-----------------------------------------------------------------------------------*/ 
 
 
void sntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); 
 
void    set_time(u32_t sec); 
u32_t   check_year(u16_t year); 
u16_t   check_month(u16_t year ,u32_t *sec); 
u16_t   check_day(u16_t year,u16_t month ,u32_t *sec); 
u16_t   check_hour(u32_t *sec); 
u16_t   check_min(u32_t *sec); 
u16_t   sun_day(u16_t year,u16_t mon, u16_t day); 
u16_t   weekday(u16_t year,u16_t mon, u16_t day); 
void offset_time_sub(INT16U *year, INT8S *month, INT8S *day,INT8S *hour,INT8S *min,INT8S offset); 
void offset_time_add(INT16U *year ,INT8S *month, INT8S *day,INT8S *hour,INT8S *min,INT8S offset); 
 
static struct udp_pcb *sntp_udp; 
 
void sntp_thread(void *arg) 
{ 
    u8_t retry,retry1; 
    retry = 5; 
    retry1 = 0; 
 
    OSTimeDlyHMSM(0,0,15,0); //ÑÓ³Ù15ÃëÆô¶¯ 
    while(1) 
    { 
        if(1)                //sntp enable 
        { 
 
            while(retry--) 
            { 
                sntp_start(); 
                OSTimeDlyHMSM(0,0,3,0); 
                if(Sntp_Status == OK ) 
                { 
                    retry = 5; 
                    OSTimeDlyHMSM(1,0,0,0); 
                } 
             } 
             if(retry == 0) 
             { 
                OSTimeDlyHMSM(0,10,0,0); 
                retry = 5; 
                if((retry1++) == 3) 
                { 
                    retry1 = 0; 
                    OSTimeDlyHMSM(1,0,0,0); 
 
                } 
             } 
        } 
    } 
 
 
} 
 
 
 
 
void sntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) 
{ 
    SNTP_T *sntp_t; 
 
    sntp_t = p->payload; 
    set_time(HTONL(sntp_t->rx_time[0])); 
 
    Sntp_Status = OK; 
 
    udp_remove(pcb); 
    sntp_udp = NULL; 
 
} 
void sntp_start() 
{ 
 
 
    struct udp_pcb *sntp_msg; 
    struct ip_addr  ip_addr; 
    struct pbuf *p; 
 
    INT32U             *pIpaddressStr; 
    INT8U              *psntp_s; 
    INT8U               ip[4]; 
    INT8U               count=0; 
 
 
    Sntp_Status = ERROR; 
    p =  pbuf_alloc(PBUF_TRANSPORT, 48, PBUF_RAM); 
    memset((INT8U *)p->payload,0,48); 
    memset((INT8U *)p->payload,0x0b,1); 
    memcpy((INT8U *)p->payload+40,"\xc3\x9d\xe1\x80",4); 
 
    psntp_s = IoSntp("SNTP_SERVER", NULL, IOR, ROOT); 
    if(atoi(psntp_s) != 0) 
    { 
        inet_aton((const char*)psntp_s, &ip_addr); 
    } 
    else 
    { 
 
    memset(G_dns_table,0x00,sizeof(G_dns_table));///< add by jjl for clear dns buffer 
 
    while(1) 
    { 
        switch(dns_table(0, psntp_s , ip, DNS_LOOK_UP)) 
        { 
             case R_ER:  break; 
             case R_RU:  break; 
             case R_OK: 
                memcpy(&ip_addr.addr,ip,4); 
                goto SNTP_REQ; 
        } 
 
        count++ ; 
 
        if(count >= 5) 
        { 
            break; 
 
        } 
 
        OSTimeDlyHMSM(0, 0, 1, 0); 
    } 
 
    } 
 
SNTP_REQ: 
    if(sntp_udp == NULL) 
    { 
        sntp_msg = udp_new(); 
        sntp_udp = sntp_msg; 
        udp_recv(sntp_msg,sntp_recv,NULL); 
        udp_bind(sntp_msg, IP_ADDR_ANY, 3000); 
        udp_connect(sntp_msg, &ip_addr, SNTP_PORT); 
    } 
    else 
    { 
        sntp_msg = sntp_udp; 
    } 
    udp_send(sntp_msg, p); 
    pbuf_free(p); 
} 
 
 
 
 
 
void set_time(u32_t sec) 
{ 
    OS_TIME time_set_inf; 
    u16_t year; 
    INT8S  month,day,hour,min,sum_day,week_day,offset; 
    u32_t temp; 
 
 
    if(sec < 0xc39de180UL) 
    { 
        printf("error"); 
        while(1); 
     } 
    else 
    { 
        sec -= 0xc39de180UL;             //1900/01/01 ~2004/01/01 total sec. 
        year = 2004; 
        month = 1; 
        day = 1; 
        hour = 0; 
        min = 0; 
    } 
 
    temp = check_year(year); 
 
    while(sec >= temp) 
    { 
        sec -=temp; 
        year++; 
        temp = check_year(year); 
 
    } 
 
 
    month = check_month(year ,&sec); 
    day = check_day(year,month,&sec); 
    hour =check_hour(&sec); 
    min = check_min(&sec); 
    sum_day = sun_day(year,month,day); 
    week_day = weekday(year,month,day); 
 
    IoSntp("SNTP_SELECT", &offset, IOR, ROOT); 
 
    if( offset < 0) 
    { 
        offset_time_sub(&year,&month ,&day, &hour ,&min ,offset); 
    } 
    else if( offset > 0) 
    { 
        offset_time_add(&year,&month ,&day, &hour ,&min ,offset); 
    } 
    time_set_inf.tm_year=year; 
    time_set_inf.tm_mon = month; 
    time_set_inf.tm_mday = day; 
    time_set_inf.tm_yday = sum_day; 
    time_set_inf.tm_wday = week_day; 
    time_set_inf.tm_hour = hour;                   //must add time zone 
    time_set_inf.tm_min = min; 
    time_set_inf.tm_sec = sec; 
 
    timer_settime(&time_set_inf); 
} 
void offset_time_add(INT16U *year ,INT8S *month, INT8S *day,INT8S *hour,INT8S *min,INT8S offset) 
{ 
    INT16S temp,temp1; 
 
    if( offset+*hour > 23 ) 
    { 
        *hour =(*hour + offset)-24; 
        switch (*month)                                    //change to next month 
        { 
 
            case 1: 
            case 3: 
            case 5: 
            case 7: 
            case 8: 
            case 10: 
            case 12: 
                    temp1 = 31; 
                    break; 
            case 2: 
                    temp1 =28; 
                    if(*year % 4 == 0) 
                    { 
                       temp1 = 29;            //29 days 
                       if(*year %100 == 0) 
                       { 
                            if (*year % 400 != 0) 
                            { 
                                temp1 = 28; 
                            } 
                       } 
                    } 
                 break; 
            default : 
                    temp1 = 30; 
             temp = *day; 
             *day = (temp == temp1)?1:*day+1; 
             *month =(temp == temp1)?*month+1:*month; 
             if( *month == 12) 
             { 
                *month = 1; 
                *year +=1; 
             } 
        } 
    } 
    else           //   if( offset+*hour > 23 ) 
    { 
        *hour += offset;                         //day no change 
    } 
} 
void offset_time_sub(INT16U *year ,INT8S *month, INT8S *day,INT8S *hour,INT8S *min,INT8S offset) 
{ 
    INT16S temp; 
        if(offset == -13 )                          //offset -3:30 
        { 
            temp = *min; 
            if( (*hour*60+*min) < 210 )            //3*60+30=210 min 
            { 
 
                *min +=(temp < 30)?30:-30; 
                *hour +=(temp < 30)?20:21; 
 
                 if(*day == 1)                          //change to last month 
                 { 
                    if( *month == 3) 
                    { 
                        temp =28; 
                        if(*year % 4 == 0) 
                        { 
                            temp = 29;            //29 days 
                            if(*year %100 == 0) 
                            { 
                                if (*year % 400 != 0) 
                                { 
                                    temp = 28; 
                                } 
                            } 
                        } 
 
                        *day = temp; 
                    } 
                    else   //if( month == 3) 
                    { 
                        if(*month ==12 || *month == 10 || *month == 7 ||*month == 5  ) 
                        { 
                            *day = 30; 
                        } 
                        else 
                        { 
                            *day = 31; 
                        } 
 
                    } 
                    if( *month == 1) 
                    { 
                        *month =12; 
                        *year  -=1; 
                    } 
                    else    // if( month == 1) 
                    { 
                        *month -=1; 
                    } 
 
                 } 
                 else     // if(day == 1) 
                 { 
                    *day -= 1; 
 
                 } 
 
 
            } 
            else         //if( (hour*60+min) < 210 ) 
            { 
                *min +=(temp < 30)?30:-30;                // day no change 
                *hour -=(temp < 30)?4:-3; 
 
            } 
 
 
        } 
        else if( abs(offset) > *hour )               //if(offset == -13 ) 
             { 
                *hour = 24 + (*hour + offset); 
                 if(*day == 1)                                     //change to last month 
                 { 
                    if( *month == 3) 
                    { 
                        temp =28; 
                        if(*year % 4 == 0) 
                        { 
                            temp = 29;            //29 days 
                            if(*year %100 == 0) 
                            { 
                                if (*year % 400 != 0) 
                                { 
                                    temp = 28; 
                                } 
                            } 
                        } 
 
 
                        *day = temp; 
                    } 
                    else    // if( month == 3) 
                    { 
                        if(*month ==12 || *month == 10 || *month == 7 ||*month == 5  ) 
                        { 
                            *day = 30; 
                        } 
                        else 
                        { 
                            *day = 31; 
                        } 
 
                    } 
                    if( *month == 1) 
                    { 
                        *month =12; 
                        *year  -=1; 
                    } 
                    else 
                    { 
                        *month -=1; 
                    } 
 
                 } 
                 else        // if(day == 1) 
                 { 
                    *day -= 1; 
 
                 } 
 
             } 
             else             //if( abs(offset) > hour ) 
             { 
                *hour += offset;                         //day no change 
             } 
 
} 
 
u16_t weekday(u16_t year,u16_t mon, u16_t day) 
{ 
    u16_t i,temp,y,sum; 
    y = year; 
    sum = 0; 
 
    if(year < 2004) 
    { 
        printf("error"); 
        return 7; 
    } 
 
    for(y--;y >= 2004;y--)                                    //start 2004/01/01 
    { 
         temp = 365; 
         if(y % 4 == 0) 
         { 
            temp = 366;            //29 days 
            if(y %100 == 0) 
            { 
                if (y % 400 != 0) 
                { 
                    temp = 365; 
                } 
            } 
         } 
         sum +=  temp; 
    } 
 
    sum += sun_day(year,mon,day); 
 
    return ((sum + 3) % 7); 
} 
 
 
u16_t sun_day(u16_t year,u16_t mon, u16_t day) 
{ 
    u8_t i,temp; 
    u16_t sum; 
    sum = 31; 
    temp = 0; 
 
    if(mon == 1) 
    { 
     return day; 
    } 
 
    for(i=2;i= 0x384UL) 
    { 
        *sec -=0x384UL; 
        i+=15; 
 
    } 
 
    for(j=0;j<=15;j++) 
    { 
        if(*sec >= 0x3cUL) 
        { 
            *sec -=0x3cUL; 
        } 
        else 
        { 
            return i+j; 
        } 
     } 
    printf("error"); 
 
} 
 
u16_t check_hour(u32_t *sec) 
{ 
    u8_t i; 
    for(i=0;i<=24;i++) 
    { 
         if(*sec >=0xe10UL) 
         { 
            *sec -= 0xe10UL; 
         } 
         else 
         { 
            return i; 
         } 
    } 
    printf("error"); 
 
} 
 
u16_t check_day(u16_t year,u16_t month ,u32_t *sec) 
{ 
    u8_t i,temp; 
 
    if(month==1 || month==3 || month==5 || month==7 || month==8  || month==10  || month==12 ) 
    { 
        temp = 31; 
    } 
    else 
    { 
        temp =30; 
        if(month == 2) 
        { 
            temp =28; 
            if(year % 4 == 0) 
            { 
                    temp = 29;            //29 days 
                    if(year %100 == 0) 
                    { 
                        if (year % 400 != 0) 
                        { 
                            temp = 28; 
                        } 
                    } 
            } 
        } 
     } 
    for(i=1;i <=temp;i++) 
    { 
        if(*sec >= 0x15180UL) 
        { 
            *sec -= 0x15180UL; 
        } 
        else 
        { 
            return i; 
        } 
 
    } 
    printf("error"); 
} 
 
u16_t check_month(u16_t year ,u32_t *sec) 
{ 
    u32_t temp; 
    int i; 
 
    for(i=1;i < 13 ;i++) 
    { 
        if(i==1 || i==3 || i==5 || i==7 || i==8  || i==10  || i==12 ) 
        { 
            temp = Day31; 
        } 
        else 
        { 
            temp = Day30; 
            if(i == 2 ) 
            { 
                temp = Day28; 
                if(year % 4 == 0) 
                { 
                    temp = Day29; 
                    if(year %100 == 0) 
                    { 
                        if (year % 400 != 0) 
                        { 
                            temp = Day28; 
                        } 
                    } 
                } 
 
            } 
 
        } 
        if(*sec >= temp) 
        { 
            *sec -= temp; 
        } 
        else 
        { 
            return i; 
        } 
    } 
 
    return 0;    ///error 
 
 
} 
 
u32_t check_year(u16_t year) 
{ 
    u32_t temp; 
    temp = Year365; 
 
    if(year % 4 == 0) 
    { 
        temp = Year366; 
        if(year %100 == 0) 
        { 
            if(year % 400 != 0) 
            { 
                temp =Year365; 
            } 
        } 
    } 
 
    return temp; 
} 
 
 
/*-----------------------------------------------------------------------------------*/ 
void 
sntp_init(void) 
{ 
  sys_thread_new(sntp_thread, NULL, DEFAULT_THREAD_PRIO,"sntp_thread"); 
}