Hi,
I post this for everyone who is interesting…
First open a GPRS bearer
- wip_bearerOpen
- wip_bearerSetOpts
- wip_bearerStart
after WIP_BEV_IP_CONNECTED event create an UDP socket:
udp_socket = wip_UDPCreateOpts((wip_eventHandler_f) Socket_Handler, NULL, WIP_COPT_PEER_STRADDR, SocketAddress, WIP_COPT_PEER_PORT, SocketPort, WIP_COPT_END);
where SocketPort must have value 123 and SocketAddress must be an NTP server address
I have test those :
ntp.eim.gr
ntp.univ-lyon1.fr
info.cyf-kr.edu.pl
biofiz.mf.uni-lj.si
not all NTP servers are working with UDP.
the following code does the main job :
void Socket_Handler(wip_event_t *ev)
{
int nRead; //bytes received
u8 buffer[200]; //receiving from socket
s32 sReturn = ERROR;
ascii NTPHeader[47]; //send this to NTP server
u32 Seconds1970 = 0x83aa7e80; //number of seconds from 1900 to 1970
u32 Seconds1900; //number of seconds from 1900
ascii strRsp[200];
adl_rtcTimeStamp_t * NTPTimeStamp; //structure to keep the data from NTP server
adl_rtcTime_t * NTPTime; //time structure
ascii CLK_command[30]="AT+CCLK= "; //command to update the time
ascii strDate[10]; //variable for date yy/mm/dd
ascii strTime[10]; //variable for time hh:mm:ss
switch (ev->kind)
{
case WIP_CEV_OPEN:
adl_atSendResponse( ADL_AT_UNS, "\r\nSocket Openned\r\n" );
//When the UDP channel is created, send a request to NTP Server
NTPHeader[0]=0x0b;
wip_write(udp_socket, NTPHeader, 48);
break;
case WIP_CEV_READ:
adl_atSendResponse( ADL_AT_UNS, "\r\nSocket Read\r\n" );
//The NTP server replies with a packet with length 48
//you can get the time with precision, network delay times, ...
//but in this case we use only the minimum time data
nRead = wip_read(udp_socket, buffer, sizeof(buffer));
//You can get the number of seconds that have passed from year 1900.
//This is a four byte information and store it to an u32 variable
Seconds1900 = (buffer[40] * 16777216) + (buffer[41] * 65536) + (buffer[42] * 256) + buffer[43];
//initialize variables
NTPTimeStamp = adl_memGet(sizeof(adl_rtcTimeStamp_t));
NTPTime = adl_memGet(sizeof(adl_rtcTime_t));
//Wavecom counts the seconds from year 1970
//So we must subtract the number of seconds that have passed till 1970
NTPTimeStamp->TimeStamp = Seconds1900 - Seconds1970;
NTPTimeStamp->SecondFracPart = 0;
//Convert to Date-Time structure
sReturn = adl_rtcConvertTime(NTPTime,NTPTimeStamp, ADL_RTC_CONVERT_FROM_TIMESTAMP);
//create date format "yy/mm/dd" and time format "hh:mm:ss"
wm_sprintf( strDate, "%02d/%02d/%02d", NTPTime->Year, NTPTime->Month, NTPTime->Day);
wm_sprintf( strTime, "%02d:%02d:%02d", NTPTime->Hour, NTPTime->Minute, NTPTime->Second);
// Create at+cclk command
wm_strcat(CLK_command,strDate);
wm_strcat(CLK_command,",");
wm_strcat(CLK_command,strTime);
wm_strcat(CLK_command," ");
CLK_command[8]='"';
CLK_command[26]='"';
//send the command to module
adl_atCmdCreate(CLK_command,ADL_AT_PORT_TYPE (ADL_AT_UART1,FALSE),Res_CLK_Handler,"*" ,NULL);
//free memory
adl_memRelease(NTPTimeStamp);
adl_memRelease(NTPTime);
break;
case WIP_CEV_WRITE:
adl_atSendResponse( ADL_AT_UNS, "\r\nSocket Write\r\n" );
break;
case WIP_CEV_ERROR:
SocketON=FALSE;
adl_atSendResponse( ADL_AT_UNS, "\r\nSocket Error\r\n" );
break;
case WIP_CEV_PEER_CLOSE:
SocketON=FALSE;
adl_atSendResponse( ADL_AT_UNS, "\r\nSocket Closed\r\n" );
break;
}
}
Note the before run at+cclk, you must add UTC Hour offset so the Hour is correct with your country
I wonder if there is any easiest way to move four bytes to u32
(I’m new to C++)
Seconds1900 = (buffer[40] * 16777216) + (buffer[41] * 65536) + (buffer[42] * 256) + buffer[43];
I can get the time with ± 5 seconds precision. You can do much more with NTP protocol.
Also I don’t have error checking code(e.g. if the NTP packet is wrong)