Login

Subversion Repositories NedoOS

Rev

Rev 1394 | Rev 1654 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#include <stdio.h>
#include <string.h>
#include <oscalls.h>
#include <socket.h>
#include <intrz80.h>
int GMT=3;
no_init unsigned char   is_atm;
no_init unsigned char netbuf[4*1024];
no_init struct sockaddr_in ntp_ia;
union {unsigned long ul;unsigned char b[4];} secsUnix;
unsigned int hour, minute, second, day, month, year, weekday;
SOCKET s=0;
unsigned char inet=0;
const unsigned char monthDays[12] =
                {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const unsigned char ntpnead[48] =
                {0xdb, 0x00, 0x11, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0xfe,};
unsigned char * defntp = "2.ru.pool.ntp.org";
const unsigned char regaddr_ve[16]={0x10,0,0x50,0,0x90,0,0,0x12,0x52,0x92,0,0,0,0,0,0};

const unsigned char help[] = "\
-H help\r\n\
-T set time(-T17:59:38)\r\n\
-D set date(-D21-06-2019)\r\n\
-N ntp-server default: -N2.ru.pool.ntp.org\r\n\
-Z time-zone default: -Z3\r\n\
-i get datetime from internet"
;

extern void dns_resolve(void);

void exit(int e){
        if(s)closesocket(s,0);
        if(e!=0) {
                puts((char*)e);
                //puts("Press any key");
                //getchar();
        }
        ((void(*)(int))0x0000)(e);
}

extern void dns_resolve(void);

unsigned char readcmos(unsigned char r) {
    disable_interrupt();
    if(is_atm == 2 || is_atm == 3){
        r = regaddr_ve[r];
        if(r != 0){
            input(0x55FE);
            r = input((r << 8) | 0x00fe);
        }
    }else{
        output(0xdef7,r);
        r = input(0xbef7);
    }
    enable_interrupt();
    return r;

}

void writecmos(unsigned char r,unsigned char v) {
    disable_interrupt();
    if(is_atm == 2 || is_atm == 3){
        r = regaddr_ve[r] +1;           // ═р чряшё№ яюЁЄ + 1
        if(r != 0){
                input(0x55FE); 
                input((r << 8) | 0x00fe);
                input((v << 8) | 0x00fe);      
                }
    }else{
        output(0xdef7,r);
        r = input(0xbef7);
    }
    enable_interrupt();
}

void Unix_to_GMT(void)
{
 // ъюЁЁхъЄшЁютър ўрёютюую яю ёр ш ёшэїЁюэшчрЎш 
  unsigned char monthLength=0;
  int days=0;
  secsUnix.ul = secsUnix.ul + GMT * 3600;    

  second=secsUnix.ul%60;
  secsUnix.ul/=60; // now it is minutes
  minute=secsUnix.ul%60;
  secsUnix.ul/=60; // now it is hours
  hour=secsUnix.ul%24;
  secsUnix.ul/=24; // now it is days
  weekday=(secsUnix.ul+4)%7; // day week, 0-sunday
  year=70;
  while(days + ((year % 4) ? 365 : 366) <= secsUnix.ul) {
     days += (year % 4) ? 365 : 366;
     year++;
  }
  secsUnix.ul -= days; // now it is days in this year, starting at 0
 
  days=0;
  month=0;
  for (month=0; month<12; month++) {
    if (month==1) { // february
      if (year%4) monthLength=28;
      else monthLength=29;
    }
    else monthLength = monthDays[month];
    if (secsUnix.ul>=monthLength) secsUnix.ul-=monthLength;
    else break;  
  }
  month++;       // jan is month 1
  day=secsUnix.ul+1;  // day of month
}
void ntp_resolver(void){
        unsigned char i,j;
        signed char res;
        int len;
        ntp_ia.sin_port=123<<8;
        ntp_ia.sin_addr=*dns_resolver((void*)defntp);
        if(!ntp_ia.sin_addr.S_un.S_addr) exit((int)"error: domain name not resolved");                 
        i=10;
inetloop:
        YIELD();
        i--;
        if(i==0){
                exit((int)"inet error");
        }
        s=socket(AF_INET,SOCK_DGRAM,0);
        if(s<0){
                s=0;
                goto inetloop;
        }
        memcpy(netbuf,ntpnead,sizeof(ntpnead));
        /*res=connect(s, &ntp_ia, sizeof(ntp_ia));
        if(res<0){
                closesocket(s,0);
                s=0;
                goto inetloop;
        }*/

        len=sendto(s,netbuf,48, 0, &ntp_ia, sizeof(ntp_ia));
        if(res<0){
                closesocket(s,0);
                s=0;
                goto inetloop;
        }
        j=50;
        while(j){
                j--;
                len=recvfrom(s,netbuf,sizeof(netbuf), 0, &ntp_ia, sizeof(ntp_ia));
                if(len<0){
                        YIELD();
                        continue;
                }
                break;
        }
       
        closesocket(s,0);
        s=0;
        if(len<=0){
        exit((int)"server error");
        }
        secsUnix.b[3] = netbuf[40];
        secsUnix.b[2] = netbuf[41];
        secsUnix.b[1] = netbuf[42];
        secsUnix.b[0] = netbuf[43];
        secsUnix.ul-=2208988800UL;
        Unix_to_GMT();
}

void set_datetime(void){

        writecmos(0x0b,readcmos(0x0b)|6);
        writecmos(0x07,day);
        writecmos(0x08,month);
        writecmos(0x09,year-100);
        writecmos(0x00,second);
        writecmos(0x02,minute);
        writecmos(0x04,hour);
}
void get_datetime(void)
{
        writecmos(0x0b,readcmos(0x0b)|6);
        second          = readcmos(0x00);
        minute          = readcmos(0x02);
        hour            = readcmos(0x04);
        weekday         = readcmos(0x06)-1;
        day                     = readcmos(0x07);
        month           = readcmos(0x08);
        year            = readcmos(0x09)+100;  
}

C_task main (int argc, char *argv[])
{
        unsigned char i=1;
        os_initstdio();
        is_atm = (unsigned char)OS_GETCONFIG();

        if(argc==1) {
                get_datetime();
                puts(help);
        }
        while(i!=argc){
                char * p=argv[i];
                if(p[0]!='-') exit((int)"Wrong parameter. Use -H for help");
                switch (p[1]&0xdf){
                        case 'T':
                                get_datetime();
                                if(sscanf(p+2,"%d:%d:%d",&hour,&minute,&second)==3){
                                        disable_interrupt();
                                        set_datetime();
                                        enable_interrupt();
                                }
                                break;
                        case 'D':
                                get_datetime();
                                if(sscanf(p+2,"%d-%d-%d",&day,&month,&year)==3){
                                        disable_interrupt();
                                        year-=1900;
                                        set_datetime();
                                        enable_interrupt();
                                }
                                break;
                        case 'N':
                                defntp=p+2;
                                break;
                        case 'Z':
                                if(sscanf(p+2,"%d",&GMT)!=1){
                                        GMT=3;
                                }
                                break;
                        case 'H':
                                exit((int)help);
                                break;
                        case 'I':
                                inet=1;
                                break;
                        default:
                                exit((int)"Wrong parameter. Use -H for help");
                }
                i++;
        }
        if(inet){
                ntp_resolver();
                set_datetime();
                writecmos(0x06,weekday+1);
        }
        puts("Now time:");
        printf("%02u-%02u-%04u ",day,month,year+1900);
        printf("%02u:%02u:%02u\r\n",hour,minute,second);
        exit(0);
        return 0;
}