NTP.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2004 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
00010 //
00011 
00012 #include <stdio.h>
00013 #include <string.h>
00014 #include <OPENR/OSyslog.h>
00015 #include <OPENR/OPENRAPI.h>
00016 #include <OPENR/OTime.h>
00017 #include <OPENR/OCalendarTime.h>
00018 #include <ant.h>
00019 #include <EndpointTypes.h>
00020 #include <DNSEndpointMsg.h>
00021 #include <UDPEndpointMsg.h>
00022 #include "NTP.h"
00023 #include "entry.h"
00024 
00025 static bool
00026 is_ipv4addr_dotted_decimal_notation(const char* str)
00027 {
00028     int part[4];
00029     int index;
00030     char c;
00031 
00032     if (str == 0) return false;
00033 
00034     part[0] = part[1] = part[2] = part[3] = 0;
00035     for (index = 0; c = *str; *str++) {
00036         if ('.' == c) {
00037             /* we go to next part */
00038             if (++index >= 4) {
00039                 break;
00040             }
00041         } else if (isdigit(c)) {
00042             part[index] = part[index] * 10 + (c - '0');
00043         } else {
00044             return false;
00045         }
00046     }
00047     
00048     if (index == 3 &&
00049         part[0] < 256 && part[1] < 256 && part[2] < 256 && part[3] < 256) {
00050         return true;
00051     } else {
00052         return false;
00053     }
00054 }
00055 
00056 NTP::NTP ()
00057 {
00058 }
00059 
00060 OStatus
00061 NTP::DoInit(const OSystemEvent& event)
00062 {
00063     OSYSDEBUG(("NTP::DoInit()\n"));
00064     return oSUCCESS;
00065 }
00066 
00067 OStatus
00068 NTP::DoStart(const OSystemEvent& event)
00069 {
00070     OSYSDEBUG(("NTP::DoStart()\n"));
00071 
00072     ipstackRef = antStackRef("IPStack");
00073 
00074     OStatus result = InitUDPBuffer();
00075     if (result != oSUCCESS) return oFAIL;
00076 
00077     {
00078         FILE* fp = fopen(NTP_CONF_FILE, "r");
00079         if (fp == NULL) {
00080             OSYSLOG1((osyslogERROR, "Can't open %s", NTP_CONF_FILE));
00081             return oFAIL;
00082         }
00083 
00084         fgets(ntpserver, 128, fp);
00085         fclose(fp);
00086 
00087         char* p;
00088         if ((p = strchr(ntpserver, '\r')) != NULL) *p = '\0';
00089         if ((p = strchr(ntpserver, '\n')) != NULL) *p = '\0';
00090         if (ntpserver[strlen(ntpserver)-1] != '.') {
00091             strcat(ntpserver, ".");
00092         }
00093 
00094         OSYSDEBUG(("ntpserver %s\n", ntpserver));
00095     }
00096 
00097     antEnvCreateEndpointMsg createMsg(EndpointType_DNS, 16*1024);
00098     createMsg.Call(ipstackRef, sizeof(createMsg));
00099     if (createMsg.error != ANT_SUCCESS) {
00100         OSYSLOG1((osyslogERROR, "%s : %s %d",
00101                   "NTP::DoStart()",
00102                   "createMsg.Call() FAILED", createMsg.error));
00103         return oFAIL;
00104     }
00105 
00106     dnsEndpoint = createMsg.moduleRef;
00107     GetHostByName(ntpserver);
00108 
00109     return oSUCCESS;
00110 }    
00111 
00112 OStatus
00113 NTP::DoStop(const OSystemEvent& event)
00114 {
00115     OSYSDEBUG(("NTP::DoStop()\n"));
00116     return oSUCCESS;
00117 }
00118 
00119 OStatus
00120 NTP::DoDestroy(const OSystemEvent& event)
00121 {
00122     return oSUCCESS;
00123 }
00124 
00125 void
00126 NTP::GetHostByName(char* hostname)
00127 {
00128     antError error;
00129     DNSEndpointGetHostByNameMsg getHostMsg(dnsEndpoint, hostname);
00130     error = getHostMsg.Send(ipstackRef,
00131                             myOID_, Extra_Entry[entryGetHostByNameCont],
00132                             sizeof(getHostMsg));
00133     if (error != ANT_SUCCESS) {
00134         OSYSLOG1((osyslogERROR, "%s : %s %d",
00135                   "NTP::GetHostByName()",
00136                   "getHostMsg.Send() FAILED", error));
00137     }
00138 }
00139 
00140 void
00141 NTP::GetHostByNameCont(ANTENVMSG msg)
00142 {
00143     DNSEndpointGetHostByNameMsg* hostMsg
00144         = (DNSEndpointGetHostByNameMsg*)antEnvMsg::Receive(msg);
00145 
00146 #ifdef OPENR_DEBUG
00147     char addr[16];
00148     OSYSDEBUG(("hostMsg->error          %d\n", hostMsg->error));
00149     OSYSDEBUG(("hostMsg->name           %s\n", hostMsg->name));
00150     hostMsg->server_address.GetAsString(addr);
00151     OSYSDEBUG(("hostMsg->server_address %s\n", addr));
00152     hostMsg->host_address.GetAsString(addr);
00153     OSYSDEBUG(("hostMsg->host_address   %s\n", addr));
00154     OSYSDEBUG(("hostMsg->n_address      %d\n", hostMsg->n_address));
00155     OSYSDEBUG(("hostMsg->n_alias        %d\n", hostMsg->n_alias));
00156 #endif
00157 
00158     //
00159     // DNS Endpoint close : NOT YET
00160     //
00161 
00162     int len = strlen(hostMsg->name);
00163     if (hostMsg->name[len-1] == '.') hostMsg->name[len-1] = '\0';
00164 
00165     if (hostMsg->error == DNS_SUCCESS && hostMsg->n_address > 0) {
00166         
00167         connection.sendAddress = hostMsg->host_address.Address();
00168 
00169     } else if (is_ipv4addr_dotted_decimal_notation(hostMsg->name) == true) {
00170 
00171         OSYSDEBUG(("hostMsg->name %s is IPv4 address.\n", hostMsg->name));
00172         connection.sendAddress= IPAddress(hostMsg->name);
00173         
00174     } else {
00175 
00176         OSYSLOG1((osyslogERROR,
00177                   "GetHostByNameCont() : %s Non-existent host",
00178                   hostMsg->name));
00179         return;
00180     }
00181     
00182     OStatus result = CreateUDPEndpoint();
00183     if (result != oSUCCESS) return;
00184     
00185     SendNTPPacket();
00186 }
00187 
00188 OStatus
00189 NTP::SendNTPPacket()
00190 {
00191     byte* ptr = (byte*)connection.sendData;
00192     for (int i = 0; i < 48; i++) {
00193         ptr[i] = 0x00;
00194     }
00195     ptr[0] = 0x0b;
00196     connection.sendSize = 48;
00197     connection.sendPort = NTP_PORT;
00198 
00199     return Send();
00200 }
00201 
00202 OStatus
00203 NTP::Send()
00204 {
00205     OSYSDEBUG(("NTP::Send()\n"));
00206 
00207     UDPEndpointSendMsg sendMsg(connection.endpoint,
00208                                connection.sendAddress,
00209                                connection.sendPort,
00210                                connection.sendData,
00211                                connection.sendSize);
00212     sendMsg.continuation = (void*)0;
00213 
00214     sendMsg.Send(ipstackRef, myOID_,
00215                  Extra_Entry[entrySendCont],
00216                  sizeof(UDPEndpointSendMsg));
00217 
00218     connection.state = CONNECTION_SENDING;
00219     connection.sendSize = 0;
00220     return oSUCCESS;
00221 }
00222 
00223 void
00224 NTP::SendCont(ANTENVMSG msg)
00225 {
00226     OSYSDEBUG(("NTP::SendCont()\n"));
00227 
00228     UDPEndpointSendMsg* sendMsg = (UDPEndpointSendMsg*)antEnvMsg::Receive(msg);
00229 
00230     if (sendMsg->error != UDP_SUCCESS) {
00231         OSYSLOG1((osyslogERROR, "%s : %s %d",
00232                   "NTP::SendCont()",
00233                   "FAILED. sendMsg->error", sendMsg->error));
00234         CloseUDPEndpoint();
00235         return;
00236     }
00237 
00238     connection.state = CONNECTION_CONNECTED;
00239 
00240     connection.recvSize = 48;
00241     Receive();
00242 }
00243 
00244 OStatus
00245 NTP::Receive()
00246 {
00247     OSYSDEBUG(("NTP::Receive()\n"));
00248 
00249     UDPEndpointReceiveMsg receiveMsg(connection.endpoint,
00250                                      connection.recvData,
00251                                      connection.recvSize);
00252     receiveMsg.continuation = (void*)0;
00253 
00254     receiveMsg.Send(ipstackRef, myOID_,
00255                     Extra_Entry[entryReceiveCont], sizeof(receiveMsg));
00256 
00257     return oSUCCESS;
00258 }
00259 
00260 void
00261 NTP::ReceiveCont(ANTENVMSG msg)
00262 {
00263     OSYSDEBUG(("NTP::ReceiveCont()\n"));
00264 
00265     UDPEndpointReceiveMsg* receiveMsg
00266         = (UDPEndpointReceiveMsg*)antEnvMsg::Receive(msg);
00267 
00268     if (receiveMsg->error != UDP_SUCCESS) {
00269         OSYSLOG1((osyslogERROR, "%s : %s %d",
00270                   "NTP::ReceiveCont()",
00271                   "FAILconnectionED. receiveMsg->error", receiveMsg->error));
00272     }
00273 
00274     OSYSDEBUG(("recvSize %d\n", connection.recvSize));
00275     NTPMessage* ntpmsg = (NTPMessage*)connection.recvData;
00276     byte* p = (byte*)&(ntpmsg->data[10]);
00277     longword t0 = (longword)p[0];
00278     longword t1 = (longword)p[1];
00279     longword t2 = (longword)p[2];
00280     longword t3 = (longword)p[3];
00281     longword t = (t0<<24)|(t1<<16)|(t2<<8)|t3;
00282     OSYSDEBUG(("ntpmsg->data[10] %u t %u\n", ntpmsg->data[10], t));
00283 
00284     //
00285     // NTP  : relative seconds to 0h on 1 January 1900. See RFC2030.
00286     // AIBO : relative seconds to 0h on 1 January 2000.
00287     //
00288     t -= SECONDS_OF_100YEARS;
00289 
00290     sbyte d;
00291     OPENR::GetTimeDifference(&d);
00292     OTime time(t, d);
00293     OPENR::SetTime(time);
00294 
00295     char date[128];
00296     OCalendarTime ctime(time);
00297     ctime.RFC2822(date);
00298     OSYSPRINT(("%s\n", date));
00299 
00300     CloseUDPEndpoint();
00301 }
00302 
00303 OStatus
00304 NTP::InitUDPBuffer()
00305 {
00306     OSYSDEBUG(("NTP::InitUDPBuffer()\n"));
00307 
00308     connection.state = CONNECTION_CLOSED;
00309 
00310     // 
00311     // Allocate send buffer
00312     //
00313     antEnvCreateSharedBufferMsg sendBufferMsg(NTP_BUFFER_SIZE);
00314 
00315     sendBufferMsg.Call(ipstackRef, sizeof(sendBufferMsg));
00316     if (sendBufferMsg.error != ANT_SUCCESS) {
00317         OSYSLOG1((osyslogERROR, "%s : %s antError %d",
00318                   "NTP::InitUDPBuffer()",
00319                   "Can't allocate send buffer",
00320                   sendBufferMsg.error));
00321         return oFAIL;
00322     }
00323 
00324     connection.sendBuffer = sendBufferMsg.buffer;
00325     connection.sendBuffer.Map();
00326     connection.sendData
00327         = (byte*)(connection.sendBuffer.GetAddress());
00328 
00329     //
00330     // Allocate receive buffer
00331     //
00332     antEnvCreateSharedBufferMsg recvBufferMsg(NTP_BUFFER_SIZE);
00333 
00334     recvBufferMsg.Call(ipstackRef, sizeof(recvBufferMsg));
00335     if (recvBufferMsg.error != ANT_SUCCESS) {
00336         OSYSLOG1((osyslogERROR, "%s : %s antError %d",
00337                   "NTP::InitUDPBuffer()",
00338                   "Can't allocate receive buffer",
00339                   recvBufferMsg.error));
00340         return oFAIL;
00341     }
00342 
00343     connection.recvBuffer = recvBufferMsg.buffer;
00344     connection.recvBuffer.Map();
00345     connection.recvData
00346         = (byte*)(connection.recvBuffer.GetAddress());
00347     connection.recvSize = NTP_BUFFER_SIZE;
00348 
00349     return oSUCCESS;
00350 }
00351 
00352 OStatus
00353 NTP::CreateUDPEndpoint()
00354 {
00355     OSYSDEBUG(("NTP::CreateUDPEndpoint()\n"));
00356 
00357     if (connection.state != CONNECTION_CLOSED) return oFAIL;
00358 
00359     //
00360     // Create UDP endpoint
00361     //
00362     antEnvCreateEndpointMsg udpCreateMsg(EndpointType_UDP,
00363                                          NTP_BUFFER_SIZE * 2);
00364     udpCreateMsg.Call(ipstackRef, sizeof(udpCreateMsg));
00365     if (udpCreateMsg.error != ANT_SUCCESS) {
00366         OSYSLOG1((osyslogERROR, "%s : %s antError %d",
00367                   "NTP::CreateUDPEndpoint()",
00368                   "Can't create endpoint",
00369                   udpCreateMsg.error));
00370         return oFAIL;
00371     }
00372     connection.endpoint = udpCreateMsg.moduleRef;
00373 
00374     // 
00375     // Bind
00376     //
00377     UDPEndpointBindMsg bindMsg(connection.endpoint, 
00378                                IP_ADDR_ANY, IP_PORT_ANY);
00379     bindMsg.Call(ipstackRef,sizeof(antEnvCreateEndpointMsg));
00380     if (bindMsg.error != UDP_SUCCESS) {
00381         OSYSLOG1((osyslogERROR, "%s : %s antError %d",
00382                   "NTP::CreateUDPEndpoint()",
00383                   "Bind error", bindMsg.error));
00384         return oFAIL;
00385     }
00386 
00387     return oSUCCESS;
00388 }
00389 
00390 OStatus
00391 NTP::CloseUDPEndpoint()
00392 {
00393     OSYSDEBUG(("NTP::CloseUDPEndpoint()\n"));
00394 }

Generated on Sun Dec 2 23:04:30 2007 for openSDK by  doxygen 1.3.9.1