computer engineering department yarmouk university abstrat · 2018-09-07 · abstrat anwar hamdan...
TRANSCRIPT
Computer Engineering Department
Yarmouk University
ABSTRAT
Anwar Hamdan Al-assaf Abdel_ ellah noor Al-shabatat Khawla Ali Al-Zou’bi
2002971019 2002971009 2002971039
Network synchronization using GPS satellite
Receiver \UTC time
Computer engineering Embedded Systems, Dr.Faroq Al-
Omari, Aug/2004,
The need for synchronized time is critical for today’s network environment. Any event
that occurs at the network should be time tagged to make it as meaningful information. But on a
network environment there is no guarantee that any node’s (server/client) time will be correct
with respect to another node. The time will be different between any two nodes of the network
for various reasons ranging from user modified to real time clock drift (i.e. typically based on
inexpensive oscillator circuits or battery backed quartz crystals and can easily drift seconds per
day, accumulating significant errors over time). The need for a précised time source is a must to
ensure accurate network synchronization. GPS (Global Positioning System) is a stratum 1, light
weight, and cost effective time source solution .In this project the time is taken from the GPS,
given to a server, the server in turn will distribute it to other servers and clients to synchronize
with the GPS time. The whole project is implemented under LINUX operating system using the
serial port, where a serial application driver is written to capture the UTC (Universal Time
Coordinate) time, a server/client programs were implemented using the UDP (User Datagram
Protocol) socket programming and a SNTP (Simple Network Time Protocol) is implemented as
a second method to get the UTC time using RPC (Remote Procedure Call).
As a result of this project a sync server was built in both hardware and software under
Embedded Linux operating system, such that it takes the UTC time from the GPS and all clients
connected to it will synchronize their time to UTC time.
Preamble
This project has been proposed by Anwar Al_assaf from (RJAF), Abdel ellah
Alsahbatat (RJAF) and Khawla Alzou’bi (YU), and has been based on their research on
a high precision network synchronization using a global positioning system. Our
knowledge has been limited to basic Linux skills and fundamental knowledge of
networking, socket programming and RPC programming. During the first two weeks
after having read a few papers and more detailed references of Linux operating system
and socket programming we made our first experiment by sending the timestamp
through socket programming between two machines and setting the time of one machine
according to the time of the other machine. During the third and fourth week a serial
application driver for a Garmin GPS receiver was written to capture the raw data
received from the GPS on one of the machines. After succeeding in capturing the data
from the GPS, the driver was adjusted to capture the wanted raw data related to the UTC
time. During the fifth week the driver was modified more to adjust the time to the local
time (Jordan Time) also a server\client program was written ,the server adjusts its
system time according to the GPS time and the clients adjusts their time according to the
server time after adding the round trip time(communication time) and it was
implemented successfully .During the sixth week another method was used to
implement the procedure above by using RPC programming to implement the SNTP
and it was implemented successfully. During the seventh and eighth week a sync server
was built in both hardware and software under Embedded Linux operating system to
capture the UTC time from the GPS and all clients connected to this sync server adjust
their time to the UTC time.
ACKNOWLEDGMENTS
We would like to express our thanks and gratitude to Allah, the Most Beneficent, the Most
Merciful whom granted us the ability and willing to start and complete this project. We pray to his
greatness to inspire us the right path to his content and to enable us to continue the work started in
this project to the benefits of our country.
The work carried out in this project has the support and assistance advice of many people to whom we
are grateful:
Our supervisor Dr. Faroq Al-Omari for his invaluable support, ideas and
suggestions.
The royal Jordanian Air force /directorate of electronic communication
Mr.Sahu for his help in understanding the Linux programming.
Finally, to our families for their moral support.
Acronyms and Abbreviations
GPS Global Positioning System
RPC Remote Procedure Call
UTC Universal Time Coordinate
LAN Local Area Network
SNTP Simple Network Time Protocol
UDP User Datagram Protocol
NMEA National Marine Electronics Association
QoS Quality of Service
OCXO Oven Controlled Crystal Oscillator
TCXO temperature-compensated crystal oscillator
GIS Geographical Information Systems
TAI International Atomic Time
RJAF Royal Jordanian Air Force
NIST National Institute of Standards and Technology
UML Unified Modeling Language
LIST OF TABLES
Table # Name PAGE
1 comparison between different methods of atomic clocks 23
2 NMEA Settings 26
3 GPS Connection to PC serial port 30
4 SNTP Mode 36
5 Stratum Classification 36
6 Stratum Code Meaning 38
7 Time Sequence Between Server and Client 40
8 Results of Version 1 58
9 Results of Version 2 58
10 Results of Version 3 59
11 Results of Version4 64
12 Results of Version 5 70
13 Results of SNTP Package with Sync Server 78
LIST OF FIGURES
FIG. FIGURE DESCRIPTION PAGE
1 server/clients connection using the server's clock as time reference 16
2 Simple server/client synchronization algorithm. 17
3 Accuracy and Stability of an oscillator 18
4 Frequency Stability 18
5 Time reference Stratum 21
6 NIST Radio Station WWVB 22
7 GPS satellites 25
8 GPS messages in NMEA format via serial port on the HyperTerminal 27
9 GPS Serial Connection 29
10 UML Use Case 41
11 Sequence Diagram 41
12 Sequence Diagram For Time Synchronization in Distributed Systems. 42
13 Client/Server UDP Socket 44
14 Client_Server Communication Using RPC 45
15 Concurrent Server 45
16 Client /Server Client Protocol 46
17 SNTP protocol 46
18 Embedded System hardware 72
19 Power Supply Circuit 73
20 GPS Card 73
21 Interface Card 74
22 Embedded Trainer Kit 74
23 GPS Antenna 75
24 RS232 Serial Cable 75
25 Sync Server Front View 76
26 Sync Server Rear View 76
TABLE OF CONTENTS
PAGE
ABSTRACT……………………………………………………………………… ii
PREAMBLE……………………………………………………………………… iv
ACKNOWLEDMENTS…………………………………………………………… V
ACRONYMS AND ABBREVIATIONS ……………………………………… vi
LIST OF TABLES……………………………………………………………………. vii
LIST OF FIGURES ………………………………………………………………….. viii
CHAPTER I: INTRODUCTION
1.1 Motivation ……………………………………………………………….. 1
1.2 Statement of the problem ……………………………………………. 3
1.3 Purpose of the study ………………………………………………… 3
1.4 Problem task ……………………………………………………… 3
1.5 Structure of the project …………………………………………… 4
CHAPTER II: LITERATURE REVIEW ………………………………
2.1 INTRODUCTION …………………………………………. 6
2.2 The hardware and software clocks in Linux …………………. 7
2.2.1 Showing and setting time in Linux……………………. 7
2.2.2 When the clock is wrong……………………………….. 9
2.3 The simple synchronization algorithm and Linux
configuration……
10
2.3.1 gettimeofday, settimeofday…………………………… 10
2.3.2 Other time system functions in Linux…………………. 12
2.4 Technical approach of the simple algorithm…………………… 16
2.5 Time resources…………………………………………………. 17
2.5.1 Accuracy……………………………………………….. 17
2.5.2 Stability ………………………………………………………. 18
2.5.3 Aging …………………………………………………………. 18
2.6 Types of Time References………………………………………………. 19
2.6.1 conventional time sources…………………………………... 19
2.6.2 Atomic clocks ………………………………………………… 20
2.7 Techniques to use the atomic clocks as time reference ……………. 20
2.8 The Optimal Time resource…………………………………………. 23
2.9 Global positioning systems (GPS) …………………………………… 24
2.10 NMEA 0183…………………………………………………………. 25
CHAPTER III:DESIGN AND ARCHITECTURE……………………………..
3.1 Requirements ………………………………………………………………..
3.2 Analysis…………………………………………………………………………
3.2.1 Reference Time Selection……………………………………………
3.2.2 Taking The UTC Time from The GPS……………………………..
3.2.3 The GPS Voltage Source…………………………………………….
3.2.4 Extracting UTC Time from GPS…………………………………….
3.2.5 Synchronization Time Protocols……………………………………
3.2.6 Time Protocol ………………………………………………………..
3.2.7 SNTP (Simple Network Time Protocol)……………………………
28
28
29
29
30
30
33
33
35
3.2.8 SNTP Time Stamp Format…………………………………………..
3.2.9 SNTP Client Operation………………………………………………
3.2.10 SNTP Server Operation…………………………………………….
3.3 Design Phase………………………………………………………………………...
3.3.1 State Diagram for The Application Driver………………………...
3.3.2 Time Synchronization for Distributed Systems……………………
3.3.3 Concurrent Server……………………………………………………
3.3.4 Time Protocol………………………………………………………….
3.3.5 SNTP Protocol…………………………………………………………
CHAPTER IV : IMPLEMENTATION AND EXPERIMENTAL RESULTS ………
4.1 Coding Environment…………………………………………………………………
4.1.1 Operating System…………………………………………………….
4.1.2 Language………………………………………………………………
4.2 Application Driver for GPS…………………………………………………………
4.2.1 Accessing Serial Port………………………………………………
4.2.2 Opening Serial Port…………………………………………………
4.2.3 Setting the Serial Port…………………………………………….
4.2.4 Reading from the Serial Port……………………………………..
4.2.5 Testing of GPS Application Driver……………………………
4.3 Time Protocol Package Using the UDP Socket………………………………
4.3.1 Server Side…………………………………………………………
4.3.2 Client Side………………………………………………………
4.3.3 Testing UDP Time Protocol………………………………….
39
40
40
41
43
44
45
46
46
47
47
48
48
48
48
48
49
53
54
54
55
56
4.4 SNTP Package UDP Socket……………………………………………………..
4.4.1 SNTP Header File…………………………………………………
4.4.2 Server Side…………………………………………………………
4.4.3 Client Side………………………………………………………
4.4.4 Testing SNTP/UDP Package…………………………………
4.5 SNTP Package RPC………………………………………………………………….
4.5.1 SNTP.x Protocol Specification File……………………………..
4.5.2 Server Service …………………………………………………...
4.5.3 Client Program……………………………………………………
4.5.4 Testing SNTP/RPC Package…………………………………….
CHAPTER V: PACKAGING AND DEPLOYMENT ……………………………….
5.1 Introduction…………………………………………………………………………..
5.2 Embedded Systems Definition………………………………………………………
5.3 System Environment …………………………………………………………………
5.3.1 Embedded Operating System…………………………………
5.3.2 System Hardware………………………………………………..
5.4 Installing Embedded Linux and Application Programs…………………………
5.5 Testing of Sync Server……………………………………………………………….
CHAPTER VI: CONCLUSIONS AND FURTHER WORK…………………………
6.1 Introduction……………………………………………………………………………
6.2 Time Synchronization………………………………………………………………
6.3 Conclusions………………………………………………………………………….
59
59
59
61
63
64
64
66
67
68
71
71
71
71
72
76
77
79
79
80
6.4 Recommendation and further work ……………………………………………
Appendix A : Software Packages ……………………………………………………
Appendix B : Serial port …………………………………………………………….
Appendix C : NMEA protocol ……………………………………………………….
Appendix D : RPC …………………………………………………………………….
References ……………………………………………………………………………
80
82
124
129
134
141
CHAPTER I: INTRODUCTION
1.1 Motivation
A vast number of applications in distributed systems require local clocks to be precisely
synchronized to allow an action to be triggered at “exactly” the same time at different nodes.
The need for synchronized time is critical for today's network environment. Any Event that
occurs at the network should be time tagged to make it as meaningful information. But on a
network environment there is no guarantee that any node's time will be correct with respect to
another node. The time will be different between any two nodes of the network for various
reasons ranging from user modified to the Real Time clock drift (i.e. typically based on
inexpensive oscillator circuits or battery backed quartz crystals and can easily drift seconds per
day, accumulating significant errors over time), Every aspect of managing, securing, planning,
and debugging a network involves determining when events happen. Accurate time is therefore
the critical element [13].
Some of the applications that depend on the accurate and synched time information are:
Many of today’s PC based applications rely on the time provided by computer [14]. One
such application is the mail client used for sending emails. For some purpose the pc time
changed, and then there is no way that the PC automatically corrects itself. So next time when
the mail is sent from the same PC, the PC’s local time is taken as a reference and e-mail gets
transmitted. This creates confusion at the receiving end. To avoid that, the PC should be able to
correct itself automatically with respect to some stable time source (which may not be altered as
compared to the PC).
While debugging the network-based application, time synchronization plays an
important role. By time tagging and logging the event that occur during the execution of such
applications the cause for the problems can be easily tracked [16].
Distributed System – The various computers connected to the network shall be
considered as the different sub-processors of the server’s processor. In order to make them look
like they run from the same clock, the server synchronizes the time of all the computers on the
network.
Simulation Systems- Various complex systems can be simulated in a LAN environment
by dividing the task and distributing them over the network. The correct sequence of events is
maintained by assuring that all platforms have the same time.
Data Acquisition Systems - Data Acquisition systems collect the data at multiple
locations and tag them with their time of arrival. To analyze, the acquired data can be correlated
using the time tags.
Transaction processing - Time sensitive transactions (stock/money transfers, etc.), often
in different cities, can be correctly ordered by insuring that respective host computers maintain
correct time.
Security systems - Many Local Area Network (LAN) security systems are based on
accurate time tagging at each end of a communication path. Some measure time of transit to
lock out transactions with excessive delays and others issue authentication "tickets" that are only
valid within a tightly controlled time window.
Time Tagging – Sending of multimedia data (voice and pictures) is becoming very
popular over a LAN (for video conferencing kind of application), the network should be time
synched in order to get a better QoS [12].
Air traffic control systems: aircraft collision avoidance [15].
In general Precise time and frequency information is needed by electric power
companies, radio and television stations, telephone companies, air traffic control systems,
participants in space exploration, computer networks, scientists monitoring data of all kinds,
and navigators of ships and planes. These users need to compare their own timing equipment
to a reliable, internationally recognized standard.
1.2 Statement of the problem
Many distributed systems used in the Royal Jordanian Air force where synchronized to
UTC time through the use of HF link ,which lacks of losses due to free space losses and
requires special antennas and periodically maintenance .
1.3 Purpose of the study
To build an accurate (within milliseconds) and reliable sync server that is referenced to
UTC through the use of a GPS satellite receiver to replace the HF time reference used in the
Royal Jordanian Air Force
1.4 Problem task
The problem task has been defined as follows:
Implementation of simple server/client UDP socket programming to obtain
the timestamp of the server and set the client‘s time to the server’s time.
Create an application serial driver for the GPS to capture the GPS raw data ,
extract the UTC time and converts it to Jordan local time.
Create a server/client program, in which the server adjusts it’s time to the GPS
time and the clients adjust their time to the server time (GPS time) using UDP
socket programming.
Create an RPC server/client program that takes the GPS time that implements the
SNTP, adjusts the server’s time, and the server in turn adjusts the client’s time.
Build an embedded sync server that keeps the UTC time, such that to
synchronize the clients or servers connected to it.
1.5 Structure of this project
This is the documentation of the final project for the Master degree in Computer
Engineering /Embedded system Engineering at the Yarmouk University/ Hijjawi College. As
such, it provides you with the information we have gathered through out the project organized in
respect of contents rather than in a way representing our work–flow.
After giving an introduction we present:
In chapter two the Linux clock, a general introduction to GPS and the NMEA
protocol related to GPS ,also the conventional time references are mentioned with some
details, their Pros and Cons with respect to their accuracy .
In chapter three, Design and Architecture of the project will be demonstrated.
In chapter four, implementation of the problem task will be demonstrated, build
and tested.
In chapter five we present the package deployment on a special hardware in the
form of Embedded system, which results in design and build a sync server under
Embedded Linux operating system.
In chapter six, results, conclusions and future work will be demonstrated.
CHAPTER II: LITERATURE REVIEW
2.1 Introduction
In principle, the key elements of clock synchronization are the mean of communication
between nodes and the implementation of clocks. The former is done by sending timestamps from one
node to the other. This can be done by using different time sources depending on the accuracy needed
to be achieved ranging from conventional oscillators with limited accuracy to a highly précised
atomic clocks, which constitute the stratum 1 reference with time signals sent by satellite to receivers
each of which having set their local clocks accordingly or by a software approach. Again there exists
a variety of possibilities we don’t intend to elaborate on here. However it should be noted the
difference between internal and external synchronization: in the former case many (eventually all)
nodes are communicating with each other, trying to estimate the clocks of connected nodes and finally
adjusting their own clock to the most probable value. External synchronization defines a node as the
time–master with it’s clock becoming determinant for all other local clocks in the distributed system.
The topology of such a system can be a star with one master–node being connected to all
clients wishing to synchronize their clocks to or it can be implemented in the form of a tree with a
hierarchical structure. In this case the master of the tree acting as a time-server is determinant for a
number of clients who are time–servers themselves delivering their synchronized time down the tree.
2.2 The hardware and software clocks in Linux
A personal computer has a battery driven hardware clock [17]. The battery ensures that the
clock will work even if the rest of the computer is without electricity. The hardware clock can be set
from the BIOS setup screen or from whatever operating system is running. The Linux kernel keeps
track of time independently from the hardware clock. During the boot, Linux sets its own clock to the
same time as the hardware clock. After this, both clocks run independently. Linux maintains its own
clock because looking at the hardware is slow and complicated. The kernel clock always shows
universal time. This way, the kernel does not need to know about time zones at all. The simplicity
results in higher reliability and makes it easier to update the time zone information. Each process
handles time zone conversions itself (using standard tools that are part of the time zone package). The
hardware clock can be in local time or in universal time. It is usually better to have it in universal
time, because then you don't need to change the hardware clock when daylight savings time begins or
ends (UTC does not have DST). Unfortunately, some PC operating systems, including MS-DOS,
Windows, and OS/2, assume the hardware clock shows local time. Linux can handle either, but if the
hardware clock shows local time, then it must be modified when daylight savings time begins or ends
(otherwise it wouldn't show local time)
2.2.1 Showing and setting time in Linux
In the Debian system, the system time zone is determined by the symbolic link /etc/localtime.
This link points at a time zone data file that describes the local time zone. The time zone data files are
stored in /usr/lib/zoneinfo. Other Linux distributions may do this differently. A user can change his
private time zone by setting the TZ environment variable. If it is unset, the system time zone is
assumed. The syntax of the TZ variable is described in the tzset manual page [8].
The date command shows the current date and time. [13] For example:
$ date
Sun Jul 14 21:53:41 EEST DST 2004
$
That time is Sunday, 14th of July, 2004, at about ten before ten at the evening, in the time zone called
``EEST'' (which might be East Time).
date can also show the universal time:
$ date -u
Sun Jul 14 18:53:42 UTC 2004
Sun Jul 14 18:53:42 UTC 2004
$
date is also used to set the kernel's software clock:
# date 071421572004
Sun Jul 14 21:57:00 EEST 2004
# date
Sun Jul 14 21:57:02 EEST 2004
#
The date manual page gives more details; the syntax is a bit arcane. Only root can set the time. While
each user can have his own time zone, the clock is the same for everyone.
date only shows or sets the software clock. The clock commands synchronize the hardware and
software clocks. It is used when the system boots, to read the hardware clock and set the software
clock. If you one needs to set both clocks, he/she should first sets the software clock with date, and
then the hardware clock with clock -w.
The -u option to clock tells it that the hardware clock is in universal time. One must use the -u option
correctly. Otherwise, the computer will be quite confused about what the time is.
The clocks should be changed with care. Many parts of a UNIX system require the clocks to
work correctly. For example, the cron daemon runs commands periodically. If one changes the clock,
it can be confused of whether it needs to run the commands or not. On one early UNIX system,
someone set the clock twenty years into the future, and cron wanted to run all the periodic commands
for twenty years all at once. Current versions of cron can handle this correctly, but one should still be
careful. Big jumps or backward jumps are more dangerous than smaller or forward ones.
2.2.2 When the clock is wrong
The Linux software clock is not always accurate [8]. It is kept running by a periodic timer
interrupt generated by PC hardware. If the system has too many processes running, it may take too
long to service the timer interrupt, and the software clock starts slipping behind. The hardware clock
runs independently and is usually more accurate. If one boots his computer often (as is the case for
most systems that aren't servers). It will usually keep fairly accurate time.
If one needs to adjust the hardware clock, it is usually simplest to reboot, he should go into the
BIOS setup screen, and do it from there. This avoids all trouble that changing system time might
cause. If doing it via BIOS is not an option, he/she should set the new time with date and clock (in
that order), but he/she should be prepared to reboot, if some part of the system starts acting funny.
A networked computer (even if just over the modem) can check its own clock automatically,
by comparing it to some other computer's time. If the other computer is known to keep very accurate
time, then both computers will keep accurate time. This can be done by using the rdate and netdate
commands. Both check the time of a remote computer (netdate can handle several remote
computers), and set the local computer's time to that. By running one of these commands regularly,
the local computer will keep as accurate time as the remote computer.
2.3 The simple synchronization algorithm and Linux configuration
A networked computer can check its own clock automatically, by setting it to some other
computer's time. To do so a client /server programs were written, in which the client polls the
server’s time to synchronize with it. This is done by using UDP socket programming [4] and the
struct tm and timeval along with the functions gettimeofday () in the server side and
settimeofday () in the client side [Appendix A],
The following sections demonstrate those functions and structures and how we used them
in our programs.
2.3.1 gettimeofday, settimeofday - gets / sets time description [11]
#include <sys/time.h>
#include <unistd.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv , const struct
timezone *tz);
Description
gettimeofday () and settimeofday() can set the time as well as a timezone. tv is a timeval
struct, as specified in /usr/include/sys/time.h:
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
and tz is a timezone :
struct timezone {
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
The use of the timezone struct is obsolete; the tz_dsttime field has never been used under Linux -
it has not been and will not be supported by libc or glibc. Each and every occurrence of this field
in the kernel source (other than the declaration) is a bug. Thus, the following is purely of historic
interest.
Return Values
gettimeofday() and settimeofday() return 0 for success, or -1 for failure (in which case errno is
set appropriately).
Errors
EPERM settimeofday is called by someone other than the superuser.
EINVAL Timezone (or something else) is invalid.
EFAULT One of tv or tz pointed outside your accessible
address space.
2.3.2 Other time system functions
asctime, ctime, gmtime, localtime, mktime - transform date and time to broken-down time or ASCII
Synopsis
#include <time.h>
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
time_t mktime(struct tm *tm);
Description
The ctime (), gmtime () and localtime () functions all take an argument of data type time_t
which represents calendar time. When interpreted as an absolute time value, it represents the number
of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
The asctime () and mktime () functions both take an argument representing broken-down time which
is a representation separated into year, month, day, etc.
Broken-down time is stored in the structure tm which is defined in <time.h> as follows:
struct tm {
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};
The members of the tm structure are:
tm_sec
The number of seconds after the minute, normally in the range 0 to 59, but can be up to 61 to
allow for leap seconds.
tm_min
The number of minutes after the hour, in the range 0 to 59.
tm_hour
The number of hours past midnight, in the range 0 to 23.
tm_mday
The day of the month, in the range 1 to 31.
tm_mon
The number of months since January, in the range 0 to 11.
tm_year
The number of years since 1900.
tm_wday
The number of days since Sunday, in the range 0 to 6.
tm_yday
The number of days since January 1, in the range 0 to 365.
tm_isdst
A flag that indicates whether daylight saving time is in effect at the time described. The value
is positive if daylight saving time is in effect, zero if it is not, and negative if the information is
not available.
The call ctime (t) is equivalent to asctime (localtime (t)). It converts the calendar time t into a string
of the form
"Wed Jun 30 21:49:08 2004\n"
The abbreviations for the days of the week are `Sun', `Mon', `Tue', `Wed', `Thu', `Fri', and `Sat'. The
abbreviations for the months are `Jan', `Feb', `Mar', `Apr', `May', `Jun', `Jul', `Aug', `Sep', `Oct', `Nov',
and `Dec'. The return value points to a statically allocated string which might be overwritten by
subsequent calls to any of the date and time functions. The function also sets the external variable
tzname with information about the current time zone. The re-entrant version ctime_r() does the same,
but stores the string in a user-supplied buffer of length at least 26. It need not set tzname.
The gmtime () function converts the calendar time timep to broken-down time representation,
expressed in Coordinated Universal Time (UTC). It may return NULL when the year does not fit into
an integer. The return value points to a statically allocated struct which might be overwritten by
subsequent calls to any of the date and time functions. The gmtime_r() function does the same, but
stores the data in a user-supplied struct.
The localtime () function converts the calendar time timep to broken-time representation, expressed
relative to the user's specified time zone. The function sets the external variables tzname with
information about the current time zone, timezone with the difference between Coordinated Universal
Time (UTC) and local standard time in seconds, and daylight to a non-zero value if daylight savings
time rules apply during some part of the year. The return value points to a statically allocated struct
which might be overwritten by subsequent calls to any of the date and time functions. The
localtime_r() function does the same, but stores the data in a user-supplied struct. It need not set
tzname.
The asctime () function converts the broken-down time value tm into a string with the same
format as ctime (). The return value points to a statically allocated string which might be overwritten
by subsequent calls to any of the date and time functions. The asctime_r () function does the same,
but stores the string in a user-supplied buffer of length at least 26.
The mktime () function converts a broken-down time structure, expressed as local time, to
calendar time representation. The function ignores the specified contents of the structure members
tm_wday and tm_yday and recomputes them from the other information in the broken-down time
structure. If structure members are outside their legal interval, they will be normalized (so that, e.g.,
40 October is changed into 9 November). Calling mktime () also sets the external variable tzname
with information about the current time zone. If the specified broken-down time cannot be represented
as calendar time (seconds since the epoch), mktime () returns a value of (time_t)(-1) and does not
alter the tm_wday and tm_yday members of the broken-down time structure.
Return value
Each of these functions returns the value described, or NULL (-1) in case of mktime ()) in
case an error was detected.
2.4 Technical approach of the simple algorithm
The simple synchronization algorithm was developed just to show the ability of Linux
operating system to manipulate time synchronization using the time functions and structures available
under Linux mentioned above, that means the accuracy of the time reference was not taken into
consideration .The server/client programs were written and had been tried successfully [Appendix A]
.Fig (1) shows the architecture of this connection.
Ethernet
Client 1 Client 2 Client 3 … Client n
Fig (1) server/clients connection using the server's clock as time reference
The server and each client in the LAN, each has its own time reference produced by it’s
crystal, a method is needed to synchronize their times to a reference. The reference here is the server
time (Ts) (i.e. at any given time every client has local time Tn different from other clients T1,
T2…Tn), Ts-Ti should be maintained to be equal to zero(ideal case).Fig (2) shows the simple
synchronization algorithm between the sever and client.
Server
Server Client
Fig (2) simple server/client synchronization algorithm.
Since in the simple synchronization algorithm the server’s clock was used as a time reference
for the clients ,which is in real a conventional oscillator with a very low accuracy[18] ,the
synchronization is done ,but with the accuracy of the local oscillator of the server ,which doesn’t
meet our aim to get a précised time reference that we can rely on it. The following flowchart
demonstrates the process
2.5 Time resources
There are many time resources available nowadays; the factors that determine which one to
choose as a standard are the stability, accuracy and aging.
2.5.1 Accuracy
Accuracy is the degree of conformity of a measured or calculated value to its definition. Accuracy is
related to the offset from an ideal value. In the world of time and frequency, accuracy is used to refer
to the time offset or frequency offset of a device. For example, time offset is the difference between a
Maintains time.
Gettimeofday()
Polls the server
time
Adjusts its time to
server time.
Settimeofday()
UDP socket
Server Client
measured on-time pulse and an ideal on-time pulse that coincides exactly with UTC. Fig (3) illustrates
what is meant by accuracy and stability.
Fig (3) Accuracy and Stability of an oscillator
2.5.2 Stability
Stability is an inherent characteristic of an oscillator that determines how well it can produce
the same frequency over a given time interval. Stability doesn't indicate whether the frequency is right
or wrong, but only whether it stays the same. The stability of an oscillator doesn't necessarily change
when the frequency offset changes. You can adjust an oscillator and move its frequency either further
away from or closer to its nominal frequency without changing its stability at all. The graphic below
Fig (4) illustrates this by displaying two oscillating signals that are of the same frequency between t1
and t2. However, it’s clear that signal 1 is unstable and is fluctuating in frequency between t2 and t3.
Fig (4) Frequency Stability
2.5.3 Aging
Aging is the change in frequency with time due to internal changes in an oscillator. Aging is
usually a nearly linear change in the resonance frequency that can be either positive or negative, and
occasionally, a reversal in direction of aging occurs. Aging occurs even when factors external to the
oscillator, such as environment and power supply, are kept constant. Aging has many possible causes,
including a buildup of foreign material on the crystal, changes in the oscillator circuitry, or changes in
the quartz material or crystal structure. A high quality OCXO might age at a rate of < 5 x 10-9
per
year, while a TCXO might age 100 times faster.
2.6 Types of Time References
Time references are divided into two types according to their accuracy those are conventional
ones (crystal oscillators) and atomic clocks, below is a brief description of both kinds:
2.6.1 Conventional (Crystal Oscillator)
An oscillator circuit is one that delivers an ac output voltage, usually having a definite desired
waveform and frequency, without the use of an external input signal. The operation of an oscillator
circuit depends on a special application of the principles of amplifier circuits.
Hardware PC’s timer chip is one of the applications of the crystal oscillator, which suffering as
mentioned previously from aging and lack of stability and accuracy.
2.6.2 Atomic clocks
An atomic clock is a type of clock that uses an atomic frequency standard as its counter. Early
atomic clocks were masers with attached equipment. Today's best atomic frequency standards (or
clocks) are based on more advanced physics involving cesium or rubidium beams and fountains.
Very accurate clocks can be constructed by locking an electronic oscillator to the frequency of an
atomic transition.
Cesium Atomic Clock
The principle underlying the cesium clock is that all atoms of cesium-133 are identical, and
when they absorb or release energy, the radiation produced by individual atoms has exactly the same
frequency, which makes the atoms perfect timepieces.
Whereas seconds counted by the Earth's rotation are never identical, atomic seconds are--always. In
1967, the 13th General Conference of Weights and Measures formally redefined the second as
"9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine
levels of the ground state of the cesium-133 atom."
The frequency of this atomic clock is in the microwave region of the electromagnetic spectrum
and is a convenient one for locking a microwave oscillator. Cesium clocks have demonstrated stability
to 1 part in 10^13, or one second in 300,000 years.
Rubidium Atomic Clock
The rubidium clock has had the advantage of portability, achieving an accuracy of about 1 in
10^12 in a transportable instrument. This has made it useful for carrying from one cesium clock to
another to synchronize the clocks.
Ever more precise timekeeping is not simply a pet project of science. Without the atomic clock, the
vast, complex networks coordinating electrical power distribution, communications, and
transportation throughout the world would not be possible.
2.7 Techniques to use the atomic clocks as time reference
Portable primary reference clock (rubidium) which is Stand-alone frequency
standard with high precision but lacks the referenced UTC.
Internet synchronization web pages/ NTP Time Synchronization Server .The NIST
Internet Time Service (ITS) allows users to synchronize computer clocks via the Internet
according to UTC time. The NIST service responds to time requests from any Internet
client in several formats including the DAYTIME, TIME, and NTP protocols. The NIST
Internet Time Service uses multiple stratum-1 timeservers. NTP Time Synchronization
Server, Links to NTP servers, hardware and software.
As a result of multiple stratums the accuracy lessens a bit gradually as the stratum
number increased, this is illustrated in Fig (5).
Fig (5) Time reference Stratum
Radio Station in which a specified frequency is transmitted from an atomic
clock located in different places (ex. Colorado / USA) and received by using
special antennas in the receiver side [9]. Fig (6) shows one of those stations.
Fig (6) NIST Radio Station WWVB
Telephone Time-of-Day Service: The audio portions of the WWV and
WWVH broadcasts can also be heard by telephone. The time announcements
are normally delayed by less than 30 ms when using land lines from within
the continental United States, and the stability (delay variation) is generally <
1 ms. When mobile phones are used, the delays are often more than 100 ms
due to the multiple access methods used to share cell channels. In rare
instances when the telephone connection is made by satellite, the time is
delayed by 250 to 500 ms.
The following table (1) shows the strengths and weakness of the above
techniques:
Technique Strengths Weakness
Internet synchronization web
pages/NTP Time Synchronization
Server
1.Easy to connect to
2. Use atomic clocks with high precision.
1. Full time connection to Internet.
2. Suffers of delay time.
3. Unreliable (risk of disconnection
without notification)
Radio Stations Use atomic clocks with high precision. 1.receiver should implement special
type of antenna
2. Costly.
3. Free space loss.
Telephone Time-of-Day Service
Audio Suffers of high delay.
Rubidium /cesium High precision 1.costly
2. Not referenced to UTC (stand-alone)
Table (1) comparison between different methods of atomic clocks
2.8 The Optimal Time resource
Due to the con’s of the methodologies mentioned above, and after a concentrated search and
study of the problem, we find that the implementation of a time sync using a global positioning
system directly connected to it will give an accurate, stable and cost effective time reference.
2.9 Global positioning systems (GPS)
A Global Positioning System (GPS) is a set of hardware and software designed by the
U.S.[32] Department of Defense for navigation. It comprises some 24 satellites fig (7), each of which
has an atomic clock synchronized to UTC Time (offset by a constant from International Atomic Time
(TAI)) and transmitting time codes. At any moment on any point on Earth at least 4 satellites can be
seen. A signal from one satellite is enough to determine the time accurately; however, signals from
four satellites are necessary to calculate time and positional information for navigation. The accuracy
of time signals from GPS is limited to ±340 nanoseconds (where 1 nanosecond = 0.000 000 001
seconds) by a deliberate distortion of the satellite signal (for military security) called Selective
Availability [11]. Also it determines accurate locations on the earth using signals received from
selected satellites. Location data and associated attribute data can be transferred to mapping and
Geographical Information Systems (GIS). GPS will collect individual points, lines and areas in any
combination necessary for a mapping or GIS project. More importantly, with GPS you can create
complex data dictionaries to accurately and efficiently collect attribute data. This makes GPS is a very
effective tool for simultaneously collecting spatial and attribute data for use with GIS. GPS is also an
effective tool for collecting control points for use in registering base maps when known points are not
available.
Fig (7) GPS satellites
Most of the GPS devices obtain a serial interface used to read the raw data received by it .The
format of this raw data is generally in the NMEA 0183 format[Appendix C].
2.10 NMEA 0183
The NMEA (National Marine Electronics Association) 0183 Standard for Interfacing
Marine Electronics Devices is a voluntary industry standard, first released in March of 1983.
The NMEA 0183 Standard defines electrical signal requirements, data transmission protocol,
timing and specific sentence formats for a 4800 baud serial data bus.
NMEA has become a standard protocol for interfacing navigational devices, e.g. GPS
and DGPS receivers. It is based on the RS232 interface. NMEA settings for the RS232 are as
shown in table (2):
Baudrate 4800
Data bits 8 (Bit 7 set to 0)
Stop bits 1 or 2
Parity none
Handshake none
Table (2) NMEA Settings
NMEA information is transmitted from a 'talker' device to a 'listener' device in 'sentences'.
Each NMEA sentence starts with '$' and ends with [CR][LF]. Example:
$GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,N,x.x,xxxx*hh [CR][LF]
The first 5 characters following the '$' are called the address field. The rest of the line consists
of the comma-delimited data fields. The first 2 characters of the address are the so called Talker-ID, in
our example the sender identifies as a GPS device (GP = GPS device).
The received raw data from the GPS in NMEA format can be displayed on the screen through
the serial port using the hyper terminal after setting the COM1 to the same setting as the NMEA
settings through RS232 cable. Fig (8) shows the captured raw data from the GPS in NMEA format.
Fig (8) GPS messages in NMEA format via serial port on the HyperTerminal
CHAPTER III DESIGN AND ARCHITECTURE
3.1 Requirement
Synchronizing the time of a computer client or server to another server or reference time source,
such as a radio or satellite receiver. It provides client accuracy typically within a millisecond on LANs
and up to a few tens of milliseconds on WANs relative to a primary server synchronized to
Coordinated Universal Time (UTC) via a Global Positioning Service (GPS) receiver.
3.2 Analysis
To achieve the above requirement we will implement an SNTP suite package to auto
synchronize a LAN /WAN networks using a precise time source with a high precision ,reliable
and low cost time source, such that to be used in synchronizing special networks used in
operating centers for air traffic control systems.
To achieve the requirement of our project ,we subdivide it into three tasks
,those are
Select a précised time reference that is reliable ,accurate and cost effective.
Write a driver or application driver to extract the time from the time
reference.
Implement a time protocol package to synchronize distributed systems.
The following sections will analyze the three tasks in details.
3.2.1 Reference time selection
Firstly after a lot of research and study of the differences among the various UTC time
resources , and while keeping in mind the required accuracy, stability and cost ,we decided to use
the GPS (Global Positioning System) as our primary reference of the UTC Time for its high accuracy
,reliability and its low cost.
3.2.2 Taking the UTC time from the GPS
The National Marine Electronics Association (NMEA) defined as RS_232 communication
standard for devices that include GPS receivers. The GPS receivers can output geo spatial location,
time, headings and navigation relevant information in the form of ASCII comma delimited message
strings.
The GPS has 9 pin series connector that is the same type used on PC COM interface .The
digital interface between the GPS and the computer is in RS_232 serial cable.
Fig (9) GPS serial connection
By tying the computer DB9 connector pins 2,3,5 to the GPS connector pins 3,2,5 respectively as
shown in table(3) , we obtain the GPS raw data
RS-232 Line In Null Modem Pin Cross RS-232 Line Out
2 CROSS TO 3
Receive Data RD/RX/RXD 3
3 CROSS TO 2
Transmitted Data TD/TX/TXD 2
5 STRAIGHT THRU
Signal Ground GND 5
Table (3) GPS connection to PC serial port.
3.2.3 The GPS voltage source
Internal source : battery .
External source : DC power supply.
3.2.4 Extracting the UTC time from the GPS.
the GPS is connected to the computer through the serial port so that we need to know how to
Opening the serial port
Each serial port has a "file" associated with it in the /dev directory. It isn't really a file but it
seems like one. For newer versions of Linux which use the Device File System (devfs) an ordinary
serial port is for example: /dev/tts/0. Formerly (before the devfs) this port was called /dev/ttyS0. Other
serial ports are /dev/tts/1, /dev/tts/2, etc. But ports on the USB bus, multiport cards, etc. have different
names[ Appendix B ].
Setting the serial port to GPS
To communicate through the serial port with the GPS ,the serial port setting should be the
same as the settings of the GPS, those are Buadrate ,parity ,stop bits ,start bit and number of bits
.Under Linux those variables are located in the library <termios.h>,so the setting were adjusted to the
required ones in this library.
Reading the serial port data
Receiving bytes by a serial port is similar to sending them only it's in the opposite direction. It's
also interrupt driven. For the obsolete type of serial port with 1-byte buffers, when a byte is fully
received from the external cable it goes into the 1-byte receive buffer. Then the port gives the CPU an
interrupt to tell it to pick up that byte so that the serial port will have room for storing the next byte
which is currently being received. For newer serial ports with 16-byte buffers, this interrupt (to fetch
the bytes) may be sent after 14 bytes are in the receive buffer. The CPU then stops what it was doing,
runs the interrupt service routine, and picks up 14 to 16 bytes from the port. For an interrupt sent
when the 14th byte has been received, there could be 16 bytes to get if 2 more bytes have arrived
since the interrupt. But if 3 more bytes should arrive (instead of 2), then the 16-byte buffer will
overrun. It also may pick up less than 14 bytes by setting it that way or due to timeouts.
We've talked about small 16-byte serial port hardware buffers but there are also much larger
buffers in main memory. When the CPU takes some bytes out of the receive buffer of the hardware, it
puts them into a much larger (up to 8k-byte) receive buffer in main memory. Then a program that is
getting bytes from the serial port takes the bytes it's receiving out of that large buffer (using a "read"
statement in the program). A similar situation exists for bytes that are to be transmitted. When the
CPU needs to fetch some bytes to be transmitted it takes them out of a large (8k-byte) transmit buffer
in main memory and puts them into the small 16-byte transmit buffer in the hardware.
Extracting the the desired data (UTC Time).
The data received from the GPS contains different frames ,each of them contains different data ,to
extract the UTC time [Appendix C] ,the frame started with $GPGGA should be first captured ,and
then the UTC time will be extracted from it as shown below.
$GPGGA,hhmmss.ss,ddmm.mmmm,n,dddmm.mmmm,e,q,ss,y.y,a.a,z,g.g,z,t.t,iii*CC
where,
GPGGA : GPS fixed data identifier
hhmmss.ss : Coordinated Universal Time (UTC), also known as GMT
ddmm.mmmm,n : Latitude in degrees, minutes and cardinal sign
dddmm.mmmm,e : Longitude in degrees, minutes and cardinal sign
q : Quality of fix. 1 = there is a fix
ss : Number of satellites being used
y.y : Horizontal dilution of precision
a.a,M : GPS antenna altitude in meters
g.g,M : geoidal separation in meters
t.t : Age of the differential correction data
iiii : Deferential station's ID
*CC : checksum for the sentence
This data will be updated every one second when using PPS GPS, and as a result the
system time will be updated accordingly.
3.2.5 Synchronization Time Protocols
To synchronize a machine to UTC time we can connect this machine to GPS using the
application driver that can get the UTC Time and set the system clock to UTC time, but it is costly to
connect a GPS to each individual machine for the purpose of synchronization to UTC time.
For this reason ,there is a need to create a server application or a time service that will be
installed at the machine (PC) connected directly to GPS ,this application responds to the request from
other machines that need to synchronize to UTC Time, without connecting them directly to GPS.
Thus Time is distributed through a hierarchy of servers (can be called SNTP servers),with each server
adopting a stratum which indicates how far a way from the external source of UTC Time , the server
that takes UTC Time directly from the external source of UTC Time (GPS in our case) called Stratum
1 ,a stratum 2 server is one which is currently obtaining time from a stratum 1 server ,a stratum 3
server gets its time from a stratum 2 server , and so on. To a void long lived synchronization loops the
number of strata is limited to 15 .Since the server can also takes its time from another source it is
preferable to be called Peer.
Any machine that needs to synchronize with a higher accuracy stratum should implement a client
program to poll the time service . The client runs in continuous mode to request the time of server
,while the server is polled at a specified intervals .
3.2.6 Time protocol
In many cases accuracies of the order of one second, is sufficient[27]. In such cases simple
protocols such as the Time Protocol can be used. This protocol may be used either above the
Transmission Control Protocol (TCP) or above the User Datagram Protocol (UDP).
Time protocol Using TCP socket
The time service works as follows: : ( S : server ,U : client)
S: Listen on port 37 (45 octal).
U: Connect to port 37.
S: Send the time as a 32 bit binary number.
U: Receive the time.
U: Close the connection.
S: Close the connection.
The server listens for a connection on port 37. When the connection is established, the server
returns a 32-bit time value and closes the connection. If the server is unable to determine the time at
its site, it should either refuse the connection or close it without sending anything.
Time protocol Using UDP socket
The time service works as follows: ( S : server ,U : client)
S: Listen on port 37 (45 octal).
U: Send an empty datagram to port 37.
S: Receive the empty datagram.
S: Send a Datagram containing the time as a 32 bit binary number.
U: Receive the time datagram.
The server listens for a datagram on port 37. When a datagram arrives, the server returns a
datagram containing the 32-bit time value. If the server is unable to determine the time at its site, it
should discard the arriving datagram and make no reply.
The Time
The time is the number of seconds since 00:00 (midnight) 1 January 1970 GMT, such that
the time 1 is 12:00:01 am on 1 January 1970 GMT; this base will serve until the year 2036.
3.2.7 SNTP (Simple Network Time Protocol)
For more accuracy than simple time protocol , we use the SNTP[26] (simple network time
protocol) ,the messages that exchange between the client and the time service/server program are in
SNTP header
SNTP Message Format
The description of the SNTP message format, which follows the IP and UDP headers is
shown in fig(4 )below.
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
Mode | Stratum | Poll | Precision
Root Delay
Root Dispersion
Reference Identifier
Reference Timestamp (64)
Originate Timestamp (64)
Receive Timestamp (64)
Transmit Timestamp (64)
Fig (4) SNTP message format
In SNTP most of these fields are initialized with pre specified data. the function of each field
is briefly summarized below.
Mode: This is an eight-bit integer indicating the mode, with values defined as
follows:
Mode Meaning
0 reserved
1 symmetric active
2 symmetric passive
3 client
4 server
5 broadcast
6 reserved for NTP control message
7 reserved for private use
Table (4) SNTP mode
Stratum: This is an eight-bit integer indicating the stratum level of the local clock
with values defined as follows:
Stratum function
0 unspecified or unavailable
1 primary reference (e.g., radio clock)
2-15 secondary reference (via NTP or SNTP)
16-255 reserved
Table (5) Stratum Classification
Poll Interval: This is an eight-bit signed integer indicating the maximum interval
between successive messages, in seconds .
Precision: This is an eight-bit signed integer indicating the precision of the local
clock, in seconds to the nearest power of two.
Root Delay: This is a 32-bit signed fixed-point number indicating the total roundtrip
delay to the primary reference source, The values that normally appear in this field
range from negative values of a few milliseconds to positive values of several hundred
milliseconds.
Root Dispersion: This is a 32-bit unsigned fixed-point number indicating the
maximum error relative to the primary reference source, The values that normally
appear in this field range from zero to several hundred milliseconds.
Reference Clock Identifier: This is a 32-bit code identifying the particular reference
clock. In the case of stratum 0 (unspecified) or stratum 1 (primary reference), this is a
four-octet, the following are representative ASCII identifiers:
Stratum Code Meaning
Table(6) below shows the stratum Code meaning.
0 ASCII generic time service other than NTP, such as ACTS (Automated Computer Time
Service), TIME (UDP/Time Protocol), TSP (TSP Unix time protocol), DTSS
(Digital Time Synchronization Service), etc.
1 ATOM calibrated atomic clock
1 VLF VLF radio (OMEGA, etc.)
1 call sign Generic radio
1 LORC LORAN-C radio navigation system
1 GOES Geostationary Operational Environmental Satellite
1 GPS Global Positioning Service
2 address secondary reference (four-octet Internet address of the NTP
server)
Table (6) stratum code meaning
Reference Timestamp: This is the local time at which the local clock was last set or
corrected, in 64-bit timestamp format.
Originate Timestamp: This is the local time at which the request departed the client
for the server, in 64-bit timestamp format.
Receive Timestamp: This is the local time at which the request arrived at the server,
in 64-bit timestamp format.
Transmit Timestamp: This is the local time at which the reply departed the server
for the client, in 64-bit timestamp format.
3.2.8 SNTP Timestamp Format
SNTP uses the standard NTP timestamp format described in RFC-1305[28] and previous
versions of that document. In conformance with standard Internet practice, NTP data are specified as
integer or fixed-point quantities, with bits numbered in big-endian fashion from zero starting at the
left, or high-order, position. Unless specified otherwise, all quantities are unsigned and may occupy
the full field width with an implied zero preceding bit zero.
Since NTP timestamps are cherished data and, in fact, represent the main product of the protocol, a
special timestamp format has been established. NTP timestamps are represented as a 64-bit unsigned
fixed-point number, in seconds relative to 0 h on 1 January 1900. The integer part is in the first 32 bits
and the fraction part in the last 32 bits. This format allows convenient multiple-precision arithmetic
and conversion to Time Protocol representation (seconds), but does complicate the conversion to
ICMP Timestamp message representation (milliseconds). The precision of this representation is about
200 picoseconds, which should be adequate for even the most exotic requirements.
Note that since some time in 1968 the most significant bit (bit 0 of the integer part) has been set and
that the 64-bit field will overflow some time in 2036. Should NTP or SNTP be in use in 2036,some
external means will be necessary to qualify time relative to1900 and time relative to 2036 (and other
multiples of 136 years).
Timestamp data requiring such qualification will be so precious that appropriate means should be
readily available. There will exist a 200-picosecond interval, hence forth ignored, every 136 years
when the 64-bit field will be zero, which by convention is interpreted as an invalid timestamp.[26]
3.2.9 SNTP Client Operations
The client initializes the SNTP message header, sends the message to the server and strips
the time of day from the reply.
3.2.10 SNTP Server Operations
The SNTP server ignores all header fields except the first octet, modifies certain fields and
returns the message to the sender. To support the highest quality service, it is recommended that an
SNTP server be operated only in conjunction with a source of outside synchronization, such as GPS.
In this case the server always operates at stratum 1.When the server reply is received, the client
determines Destination Timestamp variable as the time of arrival according to its clock in SNTP
timestamp format. The following table(7 ) summarizes the four timestamps.
Timestamp Name ID When Generated
Originate Timestamp T1 time request sent by client
Receive Timestamp T2 time request received by server
Transmit Timestamp T3 time reply sent by server
Destination Timestamp T4 time reply received by client
Table (7) time sequence between server and client
The roundtrip delay is equal to t = ((T4 - T1) )/2
3.3 Design Phase
In this design phase we used the UML (Unified Modeling Language)[20] to describe the
functionality of the whole system .The UML Use Case model is shown in Fig (10)
Client
Fig (10) UML Use Case
Sequence diagram for GPS System , where the Actor initiates a flow of events and
messages that correspond to the Use Case Scenario .
Fig(11) Sequence diagram
Server
system GPS
System
GPS
Analyzer
Serial port to
GPS
Get UTC Time
Get GPS
raw data
GPS raw data
Processin
g
Set to UTC
Time
Sequence Diagram for Time Synchronization in Distributed Systems, where the
Actor initiates a flow of events and messages that correspond to the Use Case Scenario
.
Request time
Reply time
Processing
Client Server
Open the
serial port
open
Setting the serial port
To NMEA Setting
Read the byte
of data
sucess
$
Read from the serial
port
GPGGA
The frame contains UTC
Time analyze it and extract
the UTC Time
Read from the
Serial port
End of
frame
start
End
Fig (12) Sequence Diagram for Time Synchronization in Distributed Systems
3.3.1 The state diagram for the application driver that extract data from the GPS through
the serial port.
3.3.2 Time Synchronization For Distributed Systems
We will demonstrate time synchronization for distributed systems using two methods [9].
Using UDP socket .Fig (13) demonstrates the sequence between client and server
,where the client requests the server’s time.
Fig (13) client /server UDP socket.
CREATE socket
BIND"well_kno
wn” port number
RECEIVE
Datagram
SEND Datagram
BIND to port
number
CREATE socket
RECEIVE
Datagram
SEND Datagram
Server Client
Using RPC . In this method the client requests the service time through the use of client stub, this
is shown in Fig (14) below.
Fig(14) Client _ Server Communication using RPC
3.3.3 Concurrent Server
As we talked about time synchronization for distributed system ( sub net) that synchronize to the
machine with lower stratum number (reference Time server ) then the server must be Concurrent
Server[21] to serve multi clients at the same time , so that Each incoming request is handled by
spawning a new thread Fig (15) shows the method of concurrent server. Concurrent server can be
implemented in UDP socket mode or RPC mode.
S
e
r
v
e
r
Clients
Main program
(Client)
Client Stub
XDR filters
Network
interface
Server wrapper
XDR Server
Proced
ure Netwo
rk
interfa
ce
The
Network
Fig (15) concurrent server
3.3.4 Time Protocol
As mentioned previously for accuracy within one second the message just contains the 32
bit, time in seconds between client and server as shown in fig (16 ) .
Client Server
Fig (16) client /server Time protocol
3.3.4 SNTP Protocol
SNTP Protocol provides accuracy up to 50 milliseconds by exchanging the message in SNTP
header format between client and server the fig (17) shows the SNTP algorithm.
Maintain
s time.
Gettimeo
fday()
Polls the
server time
Adjusts its
time to
server
time.
Request time
Reply time in seconds
Maintains
time.
Receive the
SNTP request
manipulates it
Gettimeofday()
Fill the SNTP
reply
Fill SNTP
request
Polls the server
time
Receive the
SNTP reply and
manipulates it
Calculate the
round trip, added it to
SNTP reply time.
Adjusts its time
to server time.
SNTP request
SNTP reply
Fig (17) SNTP protocol
CHAPTER IV
Implementation and Experimental Results
4.1 Coding Environment
The coding Environment includes the operating system and the programming language
4.1.1 Operating System: The model of this project is basically an application driver program written
in C-language and runs under Linux operating system environment. Linux OS [29]was selected for
many reasons among which are:
The vast capabilities of Linux O/S especially for networking purposes, Linux comes
with built in network support and most of the drivers, modules and libraries are
included with the base-line software.
Linux is an open source, i.e. users can alter, modify or enhance the code without
worrying about licensing issues, besides; most of the developing tools such as
compilers and debuggers are available for free.
Linux is multi-tasking, multi-user and hardware independent operating system that
makes it preferable for majority of applications that require inter-process
communications and distributed systems.
Linux is used for embedded system for the reason that a selected libraries and function
with a limited size can be downloaded on the limited size hardware.
Linux utilization is increasing in the military field, and soon there will be a number of
Linux experts who can get benefit of such attempts in Linux programming .
4.1.2 Language:
The code of this model is written in C language under Linux The C language[ ] is selected to
afford commonality for Linux users since a great portion of the source codes for Linux O/S is
written in C. The C language is a higher programming language yet relatively simple and provides
a wide spectrum of capabilities for the programmers; the C compiler is part of commercially
available Linux software, which adds to the mentioned advantages.
4.2 Application driver for GPS
GPS Program runs at Server side as daemon that read the data from the GPS through the
serial port and then analyze these data to get the UTC time frame hour : min : ss after getting these
data it calculates the local time updates the system time of server and writes the GPS data to a log file.
4.2.1 Accessing Serial Ports:
Like all devices, Linux provides access to serial ports via device files. To access a serial port
simply we open the corresponding device file.
Linux Serial Port Files are /dev/ttyS0 and /dev/ttyS1.
4.2.2 Opening The Serial Port.
The serial port is opened in non-blocking mode (read will return immediately) by the using
the following system call:
fd = open(“/dev/ttyS0”, O_RDWR | O_NOCTTY/* | O_NONBLOCK*/);
if (fd <0) {perror(“/dev/ttyS0”); exit(-1); }
4.2.3 Setting The serial port
The serial port settings should be changed in a way such that they compromise with the
NMEA settings and the termios.h library should be included
#include <termios.h>
#define BAUDRATE 4800
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
#define maxsize 100
#define LF 0x0a
#define CR 0x0d
#define COMMA 0x2c
struct termios oldtio,newtio;
After that the new port settings for raw input processing were set as following:
newtio.c_cflag = B4800/* | CRTSCTS*/ | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR|IGNBRK;
newtio.c_oflag = 0;
newtio.c_lflag =0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
Then the port is set to the new setting using the following instruction
tcsetattr(fd,TCSANOW,&newtio);
4.2.4 Reading data from the serial port
By using the read() function , the program will read char by char until the $ sign is read ,which
indicates a new frame of GPS data and continuing the read process until it reads the <LF> as in the
listing code (1).
do
{res=read(fd,charread,1);
if(charread[0]=='$')
{ i=0;
numlinesread++;
stringread[i]=charread[0];
do
{ res=read(fd,charread,1);
if((charread[0]!='\0')
&&(isalnum(charread[0])||isspace(charread[0])||ispunct(charread[0])));
i++;
stringread[i]=charread[0];
} while(charread[0]!=LF);
stringread[i+1]='\0';
Listing Code (1)
analyze the frame to get the GPGGA
$GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,N,x.x,xxxx*hh [CR][LF]
as in the listing code(2)
j=0;
pchar=stringread;
while(*(pchar+j) !=COMMA)
{ tempstring[j]= *(pchar+j);
j++;
}
tempstring[j]='\0';
Listing code (2)
check if string is $GPGGA ,it has 14 commas total
if((tempstring[3]=='G') && (tempstring[4]=='G') &&(tempstring[5]=='A'))
{ pchar=stringread;
get UTC Time
j=7; //start of time field
k=0;
while(*(pchar+j) != COMMA)
{timestring[k]= *(pchar+j);
j++;
k++;
}
timestring[k] ='\0';
convert the string stored in the timesring variable to long integer in utctime variable by using
sscanf function as following:
sscanf(timestring,"%ld",&utctime);
After getting the UTC Time in a long integer format ,some calculation done to extract the
utchour,utcminutes , and utcseconds as shown in the following list of code ().
utchour = (utctime/10000);
utcminutes =(utctime - (utchour * 10000))/ 100;
utcseconds =utctime - (utchour * 10000) - (utcminutes *100);
convert the UTC Time to local time ( Jordan time) by adding 3 to UTC hours if the UTC
hours is between 0 and 20, otherwise subtracting 21 from the UTC hours , while keeping the
UTC minutes and seconds the same as in listing code ().
if(utchour>=0 && utchour<= 20)
jorhour=utchour+3;
jorminutes = utcminutes;
jorseconds = utcseconds;
}
else
{
jorhour = utchour-21;
jorminutes = utcminutes;
jorseconds = utcseconds;
}
Getting the system time and adjusting it according to the local time received from GPS as in
the listing code (3).
gettimeofday(&t,NULL);
xx = t.tv_sec;
y=localtime(&xx);
y->tm_sec=jorseconds;
y->tm_min=jorminutes;
y->tm_hour=jorhour;
y->tm_mon=y->tm_mon;
y->tm_year=y->tm_year;
s=mktime(y);
t.tv_sec=s;
t.tv_usec=0;
settimeofday(&t,NULL);
gettimeofday(&t,NULL);
yy=t.tv_sec;
Listing Code (3)
4.2.5 Testing of GPS application Driver
The GPS was connected to the serial port using the RS232 serial cable ,and by
using the HyperTerminal ,the raw data was shown on the pc to ensure that the GPS
is capturing data under windows operating system.
The program was compiled using the gcc compiler under Linux as the following
#gcc gps.c –o gps
The GPS was connected to the PC ,the system time was changed manually to a
wrong time ,then the program was run .
As a result the system time was adjusted to the correct local time.
4.3 Time protocol package using the UDP Socket
This will include both server side and client side
4.3.1 server side.
This program runs at the Server side as daemon that reads the server’s time and sends it in
seconds as a reply to any client that requests it ,it is a concurrent server that spawn a thread for each
client connected to it and this time is referenced to the GPS time ,the following steps illustrate the
implementation of the program:
socket creation
int sd, rc, n;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0)
{printf("Failed to open socket \n");
exit(1);
}
Binding the socket to a fixed port number
struct sockaddr_in cliAddr, servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
Thread creation to handle each client connection.
pthread_create(&pthread,NULL,(void*)udp_serm,0);
Message reception from the client
int cliLen;
cliLen = sizeof(cliAddr);
n = recvfrom(sd,&request,sizeof(request), 0,
(struct sockaddr *) &cliAddr, &cliLen);
Getting the server’s time and store it in reply
gettimeofday(&time,0);
reply = time.tv_sec;
Sending the time in seconds to clients
n = sendto(sd,&reply, sizeof(reply), 0,
(struct sockaddr *) &cliAddr,sizeof(cliAddr));
4.3.2 Client side.
The client program polls the server periodically and updates it's time accordingly to the
server’s time through the following steps:
open the server.conf file to read the server’s IP address
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
socket creation
int sd, rc, n;
sd = socket(AF_INET, SOCK_DGRAM, 0);
Binding the socket to a fixed port number
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
Requesting the time in seconds from the server
n = rc = sendto(sd,&request,sizeof(request), 0,
(struct sockaddr *) &remoteServAddr,
sizeof(remoteServAddr));
Receiving the server’s time in seconds
rc = recvfrom(sd,&reply,sizeof(reply), 0,
(struct sockaddr *) &remoteServAddr,
&serv);
Setting it’s time to the server’s time .
time.tv_sec= reply;
settimeofday(&time,0);
Setup the configuration (server.conf) file
This file contains the IP address that the client will synchronize it’s time to it.
4.3.3 Testing UDP time protocol
Compile the Time protocol package for the server side that consist of TP_server.c and
gps.c files by writing Makefile that contains the following command:
gps:gps.o TP_server.o
gcc -o gps gps.o TP_server.o -lpthread
gps.o:gps.c
gcc -c gps.c
TP_server.o:TP_server.c
gcc -c TP_server.c
so when running the make command the executable file gps will be generated .
Compile the TP_client.c file using gcc compiler as shown below.
TP_client.o:TP_client.c
gcc –c TP_client.c
Install the gps file at the server .
Install Time protocol package files for the client side ( TP_client and server.conf) at
three PCs for testing.
Run the gps at the server side .
Run the TP_client at the clients.
As a result the three clients adjusted their time to server’s time with accuracy within
one second.
The software for Time Protocol package was developed in three stages ,those are :
Stage 0ne
In this stage a simple client /server program was written for the
purpose that the client will get the server’s time within the accuracy of one
second since the time reference is the server’s local oscillator . As shown in
time package version 1 in Appendix A.
After running this package between two machines the results were as shown in table(8).
Server time Client time
Wed Aug 4 10:10:37 EEST 2004 Wed Aug 4 10:10:37 EEST 2004
Wed Aug 4 10:15:40 EEST 2004 Wed Aug 4 10:15:40 EEST 2004
Wed Aug 4 10:20:45 EEST 2004 Wed Aug 4 10:20:45 EEST 2004
Wed Aug 4 10:27:40 EEST 2004 Wed Aug 4 10:20:45 EEST 2004
Table(8) Results of version 1
Stage two
In this stage a concurrent server was implemented ,in which a multi clients were
synchronized to the server’s time within one second accuracy. The time reference is
the server’s local oscillator .As shown in time package version 2 in Appendix A .
When running this package multi clients can synchronize their time to server’s
time , the results were as shown in table (9).
Server time Wed Aug 4 11:10:67
EEST 2004
Wed Aug 4 12:10:37
EEST 2004
Wed Aug 4 12:15:37
EEST 2004
Client 1 time Wed Aug 4 11:10:67
EEST 2004
Wed Aug 4 12:10:37
EEST 2004
Wed Aug 4 12:15:37
EEST 2004
Client 2 time Wed Aug 4 11:10:67
EEST 2004
Wed Aug 4 12:10:37
EEST 2004
Wed Aug 4 12:15:37
EEST 2004
Client 3 time Wed Aug 4 11:10:67
EEST 2004
Wed Aug 4 12:10:37
EEST 2004
Wed Aug 4 12:15:37
EEST 2004
Client 4 time Wed Aug 4 11:10:67
EEST 2004
Wed Aug 4 12:10:37
EEST 2004
Wed Aug 4 12:15:37
EEST 2004
Table(9) Results of version 2
Stage three
In this stage the time reference is the GPS Time, where the server takes this time
and the clients synchronize their time to the server’s time within an accuracy of one
second . As shown in time package version 3 in Appendix A.
When running this package multi clients can synchronize their time to server’s time
shown in table(10).
GPS time 10:32:45 10:35:23 10:37:45 10:40:39
Server time 10:32:45 10:35:23 10:37:45 10:40:39
Client 1 time 10:32:45 10:35:23 10:37:45 10:40:39
Client 2 time 10:32:45 10:35:23 10:37:45 10:40:39
Client 3 time 10:32:45 10:35:23 10:37:45 10:40:39
Table(10) Results of Version 3
4.4 SNTP package UDP socket
This package was implemented for accuracy within milliseconds
4.4.1 SNTP header file
That contains SNTP message format, this file must be included at the server program and the
client program so that the messages are exchanged between the client and the server in the format
of SNTP.
4.4.2 Server Side.
This program runs at the Server side as daemon that reads the server’s time and sends it in
useconds as a reply to any client that requests it ,it is a concurrent server that spawn a thread for each
client connected to it and this time is referenced to the GPS time ,the following steps illustrate the
implementation of the program:
socket creation
int sd, rc, n;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0)
{printf("Failed to open socket \n");
exit(1);
}
Binding the socket to a fixed port number
struct sockaddr_in cliAddr, servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
Thread creation to handle each client connection.
pthread_create(&pthread,NULL,(void*)udp_serm,0);
Message reception from the client
The message receipted in SNTP format stored at the request structure .
int cliLen;
cliLen = sizeof(cliAddr);
n = recvfrom(sd,&request,sizeof(request), 0,
(struct sockaddr *) &cliAddr, &cliLen);
Getting the server’s time and store it in reply ( SNTP Format)
gettimeofday(&t2,NULL);
reply.ReceiveTime.tv_sec=t2.tv_sec;
reply.ReceiveTime.tv_usec=t2.tv_usec;
reply.Stratum=1;
reply.ReferenceId=1; /* GPS*/
gettimeofday(&time1,0);
reply.TransmitTime.tv_sec = time1.tv_sec;
reply.TransmitTime.tv_usec = time1.tv_usec;
Sending the a reply structure to clients
n = sendto(sd,&reply, sizeof(reply), 0,
(struct sockaddr *) &cliAddr,sizeof(cliAddr));
4.4.3 client program
The client program polls the server periodically and updates it's time according to the
server’s time through the following steps:
open the server.conf file to read the server’s IP address
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
socket creation
int sd, rc, n;
sd = socket(AF_INET, SOCK_DGRAM, 0);
Binding the socket to a fixed port number
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
Requesting the time through the request message(SNTP format) from the server
n = rc = sendto(sd,&request,sizeof(request), 0,
(struct sockaddr *) &remoteServAddr,
sizeof(remoteServAddr));
Receiving the server’s time in reply message (SNTP format)
rc = recvfrom(sd,&reply,sizeof(reply), 0,
(struct sockaddr *) &remoteServAddr,
&serv);
calculating the roundtrip and store it in the RootDelay field and then adding it to the
reply.TimeTransmit.tv_usec.
Setting it’s time to the server’s time.
time.tv_sec= reply.TimeTransmit.tv_usec;
time.tv_sec= reply.TimeTransmit.tv_usec;
settimeofday(&time,0);
server.conf file for configuration.
This file contains the IP address that the client will synchronize it’s time to it.
4.4.4 Testing SNTP/UDP package
Compile the SNTP package for the server side that consist of SNTP_server.c and gps.c
files by writing Makefile that contains the following command:
gps:gps.o SNTP_server.o
gcc -o gps gps.o SNTP_server.o -lpthread
gps.o:gps.c
gcc -c gps.c
SNTP_server.o:SNTP_server.c
gcc -c SNTP_server.c
so when running the make command the executable file gps will be generated .
Compile the SNTP_client.c file using gcc compiler as shown below.
SNTP_client.o:SNTP_client.c
gcc –c SNTP_client.c
Install the gps file at the server .
Install SNTP package files for the client side ( SNTP_client and server.conf) at three
PCs for testing.
Run the gps at the server side .
Run the SNTP_client at the clients.
As a result the three clients adjusted their time to server’s time with accuracy within
1-50 e seconds.
SNTP package was implemented ,such that the clients synchronize their time to the
server’s time which is referenced to GPS time ,as a result all LAN clients will be
synchronized to local time within an accuracy of 1-50 milliseconds. As shown in time
package version 4 in Appendix A.
When running this package multi clients can synchronize their time to server’s
time(referenced to GPS) shown in table(11).
Table(11) Results of Version(4)
4.5 SNTP package RPC (Remote Procedure Call)
This package was implemented for accuracy within milliseconds
4.5.1 SNTP.x Protocol Specification File.
Time µsec sec µsec
Server time 1127307656
090334 1127307656
094011
Client1 time 1127307656
092944 1127307656 096960
Client2 time 1127307656 091332 1127307656 104794
This file written using XDR language, contains the SNTP protocol specification by declaring
the SNTP message format, and gives a server a program number and a version number, and
specify the service procedures which make up the server, along with their input and output data
types. The SNTP.x file contains the following:
struct timeval{
long tv_sec;
long tv_usec; };
struct NTPProtocol{
char Mode;
char Stratum;
int Poll;
int Precision ;
long int RootDelay;
long int RootDispersion;
long int Referenced;
struct timeval ReferenceTime;
struct timeval OriginateTime;
struct timeval ReceiveTime;
struct timeval TransmitTime;
};
/* the Program Definition +++++++++++++++++++++++++++++*/
program NTPPROG {
version NTPVERS {
NTPProtocol get_ntptime( NTPProtocol ) = 1;
} = 1; /*the version number */
} = 0x2000003a; /* the program number */
This file will be used by the rpcgen utility to generate four files, those are :
SNTP_clnt.c : source code of the client stub.
This file defined access to server services and handle the socket communication with server.
SNTP_svc.c : source code of the server wrapper.
This file wraps the server procedure and handles the connection of the client at the socket level ,
it was edited for the purpose of making the sever capable to handle multiclients at the same time.
The code for the SNTP_svc.c illustrated in SNTP package version 5 in Appendix A
SNTP_xdr.c : source code of the XDR filters for any user_defined data types.
The code for the SNTP_xdr.c illustrated in SNTP package version 5 in Appendix A
SNTP.h : a header file containing structure declarations and typedefs corresponding to
the XDR data types defined in SNTP.x ( header file for SNTP message format).
4.5.2 Server Service (Server Procedure) .
The RPC service will be accessed by the RPC client through the server stub. This service will
get the server’s time at the arrival of the request from the client and stores it in reply. The Received
Time ( in timestamp format in seconds and µsecond ) ,as shown in the listing code(4) .
NTPProtocol *get_ntptime_1(NTPProtocol * request,CLIENT *cl)
{static NTPProtocol reply;
static struct timeval time1,t2;
gettimeofday(&t2,NULL);
reply.ReceiveTime.tv_sec=t2.tv_sec;
reply.ReceiveTime.tv_usec=t2.tv_usec;
gettimeofday(&time1,0);
reply.TransmitTime.tv_sec = time1.tv_sec;
reply.TransmitTime.tv_usec = time1.tv_usec;
reply.Stratum=1;
reply.ReferenceId=1; /* GPS*/
return &reply;} Code List (4)
4.5.3 Client Program.
The RPC client will access the RPC service through the client stub .The client program polls the
server periodically and updates it's time accordingly to the server’s time through the following
steps:
Open the server.conf file to read the IP address of the server to access it.
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
Connect to the server through UDP by the clnt_create() which is Generic client
creation. The program tells clnt_create() where the server is located and the type of
transport to use.
cl=clnt_create(buf,NTPPROG,NTPVERS,"udp");
if(cl==NULL) {
clnt_pcreateerror(buf);
exit(2);
}
Fill the SNTP struct (packet) as follows:
gettimeofday(&t1,NULL);
request.OriginateTime.tv_sec= t1.tv_sec;
request.OriginateTime.tv_usec= t1.tv_usec;
equest.Stratum=2;
request.ReferenceId=2;
request.Poll=10;
request.Mode=2; /*client*/
Call the remote service
reply=get_ntptime_1(&request,cl);
if ( reply==NULL)
{ clnt_perror(cl,buf);
exit(3);
}
Read the system time of client for calculation of the roundtrip time as follows:
gettimeofday(&t1,NULL);
request.ReferenceTime.tv_sec=t1.tv_sec;
request.ReferenceTime.tv_usec=t1.tv_usec;
request.RootDelay=((request.ReferenceTime.tv_usec) - (request.OriginateTime.tv_usec))/2;
Add the roundtrip time to the time received in SNTP reply packet and set the system
time accordingly as follows :
t1.tv_sec=reply->TransmitTime.tv_sec;
t1.tv_usec=reply->TransmitTime.tv_usec+request.RootDelay;
settimeofday(&t1,NULL);
server.conf file
Contains the name of server (IP address) that the services registered there.
4.5.4 Testing SNTP/RPC package
Compile the server side programs and link them as in the Makefile written below :
gps_server:sntp_server.o gps.o
gcc -o gps_server sntp_server.o gps.o sntp_svc.c sntp_xdr.c –lnsl lthread
gps.o:gps.c
gcc -c gps.c
sntp_server.o:sntp_server.c
gcc -c sntp_server.c
Compile the client side programs and link them as in the Makefile written below :
Sntp_client: sntp_client.o
gcc -o sntp_client sntp_client.o sntp_clnt.c sntp_xdr.c –lnsl
sntp_client.o:sntp_client.c
gcc -c sntp_client.c
Install the SNTP package for server side at server
Install the SNTP package for the client side and the server.conf file at three clients.
Run the gps_server at the server
Run the sntp_client at each client.
As a result the time of each client was adjusted to the server’s time with an accuracy within
milliseconds
SNTP package was implemented ,such that the clients synchronize their time to the
server’s time which is referenced to GPS time ,as a result all LAN clients will be synchronized
to local time within an accuracy of 1-50 milliseconds. As shown in SNTP package version 5 in
Appendix A .When running this package multi clients can synchronize their time to server’s
time(referenced to GPS) shown in table(12).
Table (12) Results of Version 5
Time sec µsec sec µsec
Server time 1127307656
090334 1127307656
094011
Client1 time 1127307656
092944 1127307656 096960
Client2 time 1127307656 091332 1127307656 104794
CHAPTER V
Packaging and deployment
5.1 Introduction
portable sync servers has become an efficient method for network synchronization ,for its ease
in implementation ,high accuracy and high reliability, but they suffer relatively from their high cost .For
this reason we decided to extend our project to be a portable sync server using embedded systems
techniques.
5.2 Embedded system definition
A specialized computer system that is part of a larger system or machine. Typically, an embedded
system is housed on a single microprocessor board with the programs stored in ROM. Virtually all
appliances that have a digital interface -- watches, microwaves, VCRs, cars -- utilize embedded systems.
Some embedded systems include an operating system, but many are so specialized that the entire logic
can be implemented as a single program [22].
5.3 System Environment
The system environment consists of Embedded operating system and special purpose system
hardware
5.3.1 Embedded operating system
An embedded operating system is an operating system for embedded systems. These
operating systems are designed to be very compact and efficient, for saking many functionalities that
non-embedded computer operating systems provide which may not be used by the specialized
applications they run. They are frequently also real-time operating systems[23].
Embedded Linux was selected for many reasons some of them are described below[10]:
The Linux distribution includes kernel support for all of the technologies required for modern
32-bit processors, increasingly found in embedded systems designs.
This includes support for memory management, process and thread creation, interprocess
communications mechanisms, interrupt handling, execute-in-place ROM filesystems, RAM
filesystems, flash management, and TCP/IP networking.
Open source software development brings high reliability and performance to the Linux
operating system.
The presence of configuration software installation (Emedix Linux) by which the selected
libraries ,kernel, Linux service and application, Linux device drivers …etc .
5.3.2 System hardware
The system hardware consists of the following parts:
Power supply
GPS card.
Interface card between the GPS card and the serial port.
Embedded trainer kit.
GPS antenna.
Fig (18) shows a block diagram that illustrates the connections between those components.
Fig (18) Embedded System Hardware
Power supply
To Supply the GPS card with 5 volts Fig (19)
Fig (19) power supply circuit
Power
supply
GPS card
Trainer kit
Interface
card RS232
GPS card.
To extract the NMEA messages received from the satellite. Fig (20)
Fig (20) GPS card
Interface card between the GPS card and the serial port.
To convert the 5 volts output from the GPS card to 12 volts for the entry of the serial port. Fig(21).
Fig(21) Interface card
Embedded trainer kit.
To install the embedded Linux merged with our programs on it. Fig(22).
Fig(22) Embedded trainer kit
GPS antenna.
To capture 4 satellites such that to enable the GPS card to capture the required data.
Fig(23)
Fig(23) GPS antenna
RS232 serial cable
To connect the GPS card to the trainer kit. Fig(24)
Fig(24) RS232 serial cable
Display
To monitor the data received from the satellite
Keyboard
Used as user interface with the sync server.
The built sync server in both front view and rear view is shown in Fig(25) and Fig(26).
Fig(25) Sync server front view
Fig (26) Sync Server Rear View
5.4 Installing Embedded Linux and Application programs
Using the Embedix tool[31] , the kernel Linux and the needed libraries ,system
functions, and driver models for Ethernet card were built ,deployed on the pc along
with the minicom utility .
The lilo.conf file was edited appropriately .
The application programs were merged with the kernel and root file system
Using the minicom utility at the PC side and the VTERM utility at the kit side the
embedded Linux along with the application programs where downloaded into the kit
through the serial port .
5.5 Testing Sync server
After turn on the sync server and connecting the display and keyboard to it , from the
dos prompt we run the embedded Linux.
Install the network model and run the network script.
Run the sync server executable file
As a result the local time referenced to UTC time was displayed on the screen.
The sync server was given an IP address “192.168.0.3” and connected to the LAN.
The client package was installed in three clients.
The server package was run in the sync server side
The client package was run in the three clients.
As a result all three clients were adjust their time to the sync server time within an
accuracy of 1-50 milliseconds.
An embedded sync server was built in a special hardware and under embedded Linux
operating system, with a result of time accuracy of 1-50 milliseconds.
When running this package multi clients can synchronize their time to the sync server’
time as shown in table(13).
Table (13) Results of SNTP package with Sync server
Time sec µsec Sec µsec
Sync Server 1127307656
090334 1127307656
094011
Client1 time 1127307656
092944 1127307656 096960
Client2 time 1127307656 091332 1127307656 104794
CHAPTER VI
Conclusions and Further Work
6.1 Introduction
The telecommunications industry acknowledges the importance of good network
synchronization, the growing number of hybrid (packet- and circuit-switched) network
architectures makes clear the requirement to maintain synchronization quality as a means of
guaranteeing quality of service (QoS).
6.2 Time synchronization
In general time synchronization is a process of bringing two clocks into phase so that their
difference is zero. A typical time synchronization process may be divided into these steps:
1. Client software receives the correct time from a time server.
2. Then it compares the received time value to the time setting of the host computer.
3.
If there is any difference, the computers time is automatically adjusted to reflect the correct
time.
The accuracy of time synchronization depends on the time protocol used and the limits of the
underlying computer hardware and operating system.
6.3 Conclusions:
1. Network synchronization plays a vital role in nowadays systems.
2. There are many techniques to achieve network synchronization depending on the time
resource accuracy available and the application environment.
3. The accuracy of the time resource is depending on the method that produces the time
signal in the resource .
4. Conventional time resources suffer of instability and aging.
5. Atomic time resources are high precision ,stable resources but they are very expensive
6. GPS is able to capture the time from atomic resources located in the satellites ,within
the accuracy of 340 nanoseconds making it cost effective to reference to UTC time.
7. In this project ,all clients were synchronized to the level of milliseconds using the UTC
time received from the GPS.
8. Commercial sync servers are costly and they use the same reference used in this
project(GPS).
9. The sync server built in this project is cost effective and gives the accuracy needed .
6.4 Recommendation and Future work
The team recommends a number of improvements to the system ,those are making the clients
polling the server’s time intervals starting from 64 sec and increased in steps until it reaches 1024
seconds ,except if an unexpected change in the system time happens (user change) by running a script
that detect this unexpected change in time to reduce the network traffic.
Secondly ,as sync server turned on the daemon for the server and GPS should run without
configuration, that means running embedded Linux directly without going to dos .
Thirdly ,many other applications can get benefit of GPS data such as tracking systems,
position, forecasting …etc and they can use the GPS application driver we implemented with some
modifications. Also this project can expanded to cover wireless networks like mobile communication
centers to distribute UTC time to their customers.
Appendix A: Software Packages
1. Time Protocol Package Version ‘1’
Client Side
/* Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : TP_client.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : Sample UDP Client Program
-----------------------------------------------------------------------
Notes
How To Compile : On command prompt give"gcc -o client udp_client.c",
*************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/time.h>
#define MAX_SIZE 100
#define SERVER "192.168.0.3"
#define REMOTE_SERVER_PORT 37
#define MAX_MSG 100
int main(int argc,char *argv)
{struct timeval t;
int sd, rc, i,serv,request;
struct sockaddr_in cliAddr, remoteServAddr;
struct hostent *h;
char msg[100];
unsigned long tdata;
/* command line args */
/* get server IP address */
h = gethostbyname(SERVER);
if( h == NULL )
{
printf("%s: unknown host \n", argv[0]);
exit(1);
}
remoteServAddr.sin_family = h->h_addrtype;
memcpy((char *) &remoteServAddr.sin_addr.s_addr,
h->h_addr_list[0], h->h_length);
remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);
/* socket creation */
sd = socket(AF_INET,SOCK_DGRAM,0);
if( sd < 0 )
{
printf("Failed to open socket \n");
exit(1);
}
/* bind any port */
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
if( rc < 0 )
{
printf("%s: cannot bind port\n", argv[0]);
exit(1);
}
/* sending data */
while(1)
{
request=1;/* to request the server's time in seconds */
rc = sendto(sd,&request,sizeof(request), 0,
(struct sockaddr *) &remoteServAddr,
sizeof(remoteServAddr));
if( rc < 0 )
{
printf("Failed to send data \n");
close(sd);
exit(1);
}
serv=sizeof(remoteServAddr);
rc = recvfrom(sd,&tdata,5, 0,
(struct sockaddr *) &remoteServAddr,
&serv);
printf("the utc time in seconds %ld \n",tdata);
if(rc<0)
{
printf("Failed to receive data \n");
exit(1);
}
t.tv_sec=tdata;
t.tv_usec=0;
settimeofday(&t,0);
sleep(10);
}
return 0;
}
Server Side
/**********************************************************************
Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : udp_client.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : Sample UDP Server Program
this server just reply one client at a time
****************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
struct timeval t;
#define LOCAL_SERVER_PORT 37
#define MAX_MSG 100
int main(int argc, char *argv[])
{
unsigned long timedata;
int sd, rc, n, cliLen,request;
struct sockaddr_in cliAddr, servAddr;
/* socket creation */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0)
{
printf("Failed to open socket \n");
exit(1);
}
/* bind local server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0)
{
printf(" Failed to bind port number %d \n", LOCAL_SERVER_PORT);
exit(1);
}
printf(" Server waiting for data on port %u\n", LOCAL_SERVER_PORT);
while(1)
{
/* function for receiving messages */
cliLen = sizeof(cliAddr);
n = recvfrom(sd,&request,2, 0,
(struct sockaddr *) &cliAddr, &cliLen);
if(n<0)
{
printf("Failed to receive data \n");
continue;
}
gettimeofday( &t, NULL);
timedata = t.tv_sec;
/* sending Time in seconds to client that requested it */
n = sendto(sd,&timedata, sizeof(timedata), 0,
(struct sockaddr *) &cliAddr,sizeof(cliAddr));
if(n<0)
{
printf("Failed to sende data \n");
exit(1);
}
}//while
return 0;
}
2. Time Protocol Package Version ‘2’
Client Side
Client program
/* Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : TP_client.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : Sample UDP Client Program
that polls the server every 10 seconds
*---------------------------------------------------------------------
Notes
* How To Compile : On command prompt give"gcc -o client TP_client.c", *
* *
*****************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/time.h>
#define REMOTE_SERVER_PORT 37
int main(int argc,char *argv)
{ struct timeval t;
int sd, rc, i,serv,request;
struct sockaddr_in cliAddr, remoteServAddr;
struct hostent *h;
unsigned long tdata;
FILE * peer1;
char buf[100];
/* To read the server IP address from the server.conf file */
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
/* command line args */
/* get server IP address */
h = gethostbyname(buf);
if( h == NULL )
{
printf("%s: unknown host \n", buf);
exit(1);
}
remoteServAddr.sin_family = h->h_addrtype;
memcpy((char *) &remoteServAddr.sin_addr.s_addr,
h->h_addr_list[0], h->h_length);
remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);
/* socket creation */
sd = socket(AF_INET,SOCK_DGRAM,0);
if( sd < 0 )
{
printf("Failed to open socket \n");
exit(1);
}
/* bind any port */
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
if( rc < 0 )
{
printf("%s: cannot bind port\n", argv[0]);
exit(1);
}
/* sending data */
while(1)
{
request=1;/* to request the server's time in seconds */
rc = sendto(sd,&request,sizeof(request), 0,
(struct sockaddr *) &remoteServAddr,
sizeof(remoteServAddr));
if( rc < 0 )
{
printf("Failed to send data \n");
close(sd);
exit(1);
}
serv=sizeof(remoteServAddr);
rc = recvfrom(sd,&tdata,5, 0,
(struct sockaddr *) &remoteServAddr,
&serv);
printf("the utc time in seconds %ld \n",tdata);
if(rc<0)
{
printf("Failed to receive data \n");
exit(1);
}
t.tv_sec=tdata;
t.tv_usec=0;
settimeofday(&t,0);
sleep(10);
}
return 0;
}
Server.conf
192.169.0.3
Server Side
/**********************************************************************
Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : TP_server.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : Sample UDP Server Program
This server is concurrent server that reply multiclients at the same time .By spawned a thread to
handle each one
Compiled it by typing the following command line:
gcc TP_server.c -lpthread -o server
**********************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <pthread.h>
struct timeval t;
#define LOCAL_SERVER_PORT 37
int udp_serm();
int main()
{
pthread_t pthread;
pthread_create(&pthread,NULL,&udp_serm,0);
return 0;
}
int udp_serm()
{ unsigned long timedata;
int sd, rc, n, cliLen,request;
struct sockaddr_in cliAddr, servAddr;
/* socket creation */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0)
{
printf("Failed to open socket \n");
exit(1);
}
/* bind local server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0)
{
printf(" Failed to bind port number %d \n", LOCAL_SERVER_PORT);
exit(1);
}
printf(" Server waiting for data on port %u\n", LOCAL_SERVER_PORT);
while(1)
{
/* function for receiving messages */
cliLen = sizeof(cliAddr);
n = recvfrom(sd,&request,2, 0,
(struct sockaddr *) &cliAddr, &cliLen);
if(n<0)
{
printf("Failed to receive data \n");
continue;
}
gettimeofday( &t, NULL);
timedata = t.tv_sec;
/* sending Time in seconds to client that requested it */
n = sendto(sd,&timedata, sizeof(timedata), 0,
(struct sockaddr *) &cliAddr,sizeof(cliAddr));
if(n<0)
{
printf("Failed to sende data \n");
exit(1);
}
}//while
return 0;
}
3.Time Protocol Package Version ‘3’
Client Side
Client Program
/* Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : TP_client.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : Sample UDP Client Program
that polls the server every 10 seconds
*---------------------------------------------------------------------
* Notes
* How To Compile : On command prompt give"gcc -o client TP_client.c", *
**********************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/time.h>
#define REMOTE_SERVER_PORT 37
int main(int argc,char *argv)
{ struct timeval t;
int sd, rc, i,serv,request;
struct sockaddr_in cliAddr, remoteServAddr;
struct hostent *h;
unsigned long tdata;
FILE * peer1;
char buf[100];
/* To read the server IP address from the server.conf file */
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
/* command line args */
/* get server IP address */
h = gethostbyname(buf);
if( h == NULL )
{
printf("%s: unknown host \n", buf);
exit(1);
}
remoteServAddr.sin_family = h->h_addrtype;
memcpy((char *) &remoteServAddr.sin_addr.s_addr,
h->h_addr_list[0], h->h_length);
remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);
/* socket creation */
sd = socket(AF_INET,SOCK_DGRAM,0);
if( sd < 0 )
{
printf("Failed to open socket \n");
exit(1);
}
/* bind any port */
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
if( rc < 0 )
{
printf("%s: cannot bind port\n", argv[0]);
exit(1);
}
/* sending data */
while(1)
{
request=1;/* to request the server's time in seconds */
rc = sendto(sd,&request,sizeof(request), 0,
(struct sockaddr *) &remoteServAddr,
sizeof(remoteServAddr));
if( rc < 0 )
{
printf("Failed to send data \n");
close(sd);
exit(1);
}
serv=sizeof(remoteServAddr);
rc = recvfrom(sd,&tdata,5, 0,
(struct sockaddr *) &remoteServAddr,
&serv);
printf("the utc time in seconds %ld \n",tdata);
if(rc<0)
{
printf("Failed to receive data \n");
exit(1);
}
t.tv_sec=tdata;
t.tv_usec=0;
settimeofday(&t,0);
sleep(10);
}
return 0;
}
Server.conf
192.168.0.3
Server Side
Server program
/**********************************************************************
Yarmouk Uinversity
Hijjawi College
Embedded Engineering Graduate
SourceName : TP_server.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : Sample UDP Server Program
This server concurrent server that reply multiclients at the same time by spawned a thread to
handle each one
**********************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
struct timeval t;
#define LOCAL_SERVER_PORT 37
int udp_serm()
{
unsigned long timedata;
int sd, rc, n, cliLen,request;
struct sockaddr_in cliAddr, servAddr;
/* socket creation */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0)
{
printf("Failed to open socket \n");
exit(1);
}
/* bind local server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0)
{
printf(" Failed to bind port number %d \n", LOCAL_SERVER_PORT);
exit(1);
}
printf(" Server waiting for data on port %u\n", LOCAL_SERVER_PORT);
while(1)
{
/* function for receiving messages */
cliLen = sizeof(cliAddr);
n = recvfrom(sd,&request,2, 0,
(struct sockaddr *) &cliAddr, &cliLen);
if(n<0)
{
printf("Failed to receive data \n");
continue;
}
gettimeofday( &t, NULL);
timedata = t.tv_sec;
/* sending Time in seconds to client that requested it */
n = sendto(sd,&timedata, sizeof(timedata), 0,
(struct sockaddr *) &cliAddr,sizeof(cliAddr));
if(n<0)
{
printf("Failed to sende data \n");
exit(1);
}
}//while
return 0;
}
GPS Application Driver
/
***********************************************************************
Yarmouk University
Hijjawi College
Embedded engineering graduate
SourceName : udp_server.c
Programmers : Anwar
Abdel-ellah
Khawla
Supervisor :Dr.AL_Omari
Date : 18/07/2004
*---------------------------------------------------------------------
Description
GPS Program : This program run at Server side as daemon that
read the data from the GPS through the serial port and then analyze
it to get the UTC time frame day : hour : min : ss then after get these
Data update the system time of server and also write the GPS data to
logfile
**************************************************************************/
/*+++++++++++++++++++The header files used in this program+++++++++++*/
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <signal.h>
#include <ctype.h>
#include <sys/time.h>
#include <time.h>
#define BAUDRATE 4800
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 // POSIX compliant source
#define maxsize 100
#define LF 0x0a
#define CR 0x0d
#define COMMA 0x2c
void INThandler(int); // Ctrl-C handler
extern udp_serm(void);
main()
{
pthread_t pthread;
struct termios oldtio,newtio;
int fd,res;
unsigned int i,j,k;
unsigned int numlinesread;
unsigned char charread[maxsize];
unsigned char stringread[maxsize];
unsigned char *pchar;
unsigned char dummychar;
unsigned char tempstring[maxsize];
unsigned char timestring[maxsize];
unsigned long utctime;
unsigned long utchour;
unsigned long utcminutes;
unsigned long utcseconds;
unsigned long jorhour;
unsigned long jorseconds;
unsigned long jorminutes;
time_t xx;
struct timeval t;
struct tm *y;
time_t yy;
time_t s;
FILE *log;
FILE *log1;
signal(SIGINT, INThandler); // install Ctrl-C handler
pthread_create(&pthread,NULL,&udp_serm,0);
dummychar = 'A';
pchar = &dummychar;
log = fopen("GPS.txt","w+");
log1 = fopen("GPS1.txt","w+");
numlinesread = 0;
// open the device to be non-blocking (read will return immediatly)
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY/* | O_NONBLOCK*/);
if (fd <0)
{
perror(MODEMDEVICE);
exit(-1);
}
// save current port settings
tcgetattr(fd,&oldtio);
bzero(&newtio,sizeof(newtio));
// set new port settings for raw input processing
// zero(&newtio, sizeof(newtio));
newtio.c_cflag = B4800/* | CRTSCTS*/ | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR|IGNBRK;
newtio.c_oflag = 0;
newtio.c_lflag =0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
// getting data from serial port
do
{
res=read(fd,charread,1);
if(res== -1)
{
printf("Please connect your GPS\n");
exit(0);
}
if(charread[0]=='$')
{
i=0;
numlinesread++;
stringread[i]=charread[0];
do
{
res=read(fd,charread,1);
if((charread[0]!='\0') &&
(isalnum(charread[0])||isspace(charread[0])||ispunct(charread[0])));
{
i++;
stringread[i]=charread[0];
}
} while(charread[0]!=LF);
stringread[i+1]='\0'; //append null terminator to the string read
//************* analyze string*************************************************
j=0;
pchar=stringread;
while(*(pchar+j) !=COMMA)
{
tempstring[j]= *(pchar+j);
j++;
}
tempstring[j]='\0';
//check if sting is $GPGGA ,it has 14 comms total
if((tempstring[3]=='G') && (tempstring[4]=='G') && (tempstring[5]=='A'))
{
pchar=stringread;
// get UTC time*****************************************************************
j=7; //start of time field
k=0;
while(*(pchar+j) != COMMA)
{
timestring[k]= *(pchar+j);
j++;
k++;
}
timestring[k] ='\0';
sscanf(timestring,"%ld",&utctime);
utchour = (utctime/10000);
utcminutes =(utctime - (utchour * 10000))/ 100;
utcseconds =utctime - (utchour * 10000) - (utcminutes * 100);
printf("THIS IS THE UTC TIME RECIEVED\n");
printf(" hh=%02ld :mm=%02ld :ss=%02ld\n",utchour,utcminutes,
utcseconds);
printf("THIS IS THE LOCAL JORDAN TIME\n");
if(utchour>=0 && utchour<= 20)
{
jorhour=utchour+3;
jorminutes = utcminutes;
jorseconds = utcseconds;
}
else
{
jorhour = utchour-21;
jorminutes = utcminutes;
jorseconds = utcseconds;
}
printf(" hh=%02ld :mm=%02ld :ss=%02ld\n",jorhour,jorminutes,
jorseconds);
//getting the system time and adjusting it according to the local time received
from GPS
gettimeofday(&t,NULL);
printf("systemtime: %lu.%06lu\n",t.tv_sec,t.tv_usec);
xx = t.tv_sec;
printf("no ofseconds since 1/1/1970 = %lu\n",xx);
printf("the system time before adjusting is %s\n",ctime(&xx));
y=localtime(&xx);
y->tm_sec=jorseconds;
y->tm_min=jorminutes;
y->tm_hour=jorhour;
y->tm_mon=y->tm_mon;
y->tm_year=y->tm_year;
printf("jorseconds %d\n",y->tm_sec);
printf("jorminutes %d\n",y->tm_min);
printf("jorhour %d\n",y->tm_hour);
printf("jorday %d\n",y->tm_mday);
printf("jormonth %d\n",y->tm_mon+1);
printf("joryear %d\n",y->tm_year+1900);
printf("jorwday %d\n",y->tm_wday);
printf("joryday %d\n",y->tm_yday);
s=mktime(y);
printf("no of sec %lu\n",s);
t.tv_sec=s;
t.tv_usec=0;
settimeofday(&t,NULL);
printf("the adjusted new time is: %s\n",ctime(&s));
gettimeofday(&t,NULL);
yy=t.tv_sec;
printf("%lu\n",yy);
fprintf(log1,"system time adjusted at : %s\n",ctime(&s));
// not a GPGGA sentencs
}
fprintf(log , "%d : (%d) %s\n" , numlinesread , i , stringread);
}
// otherwise not a $ character ..so loop until one arrives
}while(1);
// restore old port setting ************************************
tcsetattr(fd,TCSANOW,&oldtio);
fclose(log);
fclose(log1);
close(fd);
return 0 ;
}
void INThandler(int sig)
{
char c;
signal(sig, SIG_IGN); // disable Ctrl-C
printf("WAIT, did you hit Ctrl-C?\n" // print something
"Do you really want to quit? [y/n] ");
c = getchar(); // read an input character
if (c == 'y' || c == 'Y') // if it is y or Y, then
exit(0); // exit. Otherwise,
else
signal(SIGINT, INThandler); // reinstall the handler
}
Makefile
gps:gps.o TP_server.o
gcc -o gps gps.o TP_server.o -lpthread
gps.o:gps.c
gcc -c gps.c
TP_server.o:TP_server.c
gcc -c TP_server.c
GPS File After run this package this file will Contain Contains the GPS captured data
GPS1 File
After run this package this file will Contain the UTC Time got it from the GPS data.
4. SNTP Package Version ‘4’
Client Side
Client Program
/**********************************************************************
Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : SNTP_client.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : UDP Client Program
*---------------------------------------------------------------------
* the client program polling the server every a specific polling interval second and update it's time
accordingly**********************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/times.h>
#include<time.h>
#include "sntp.h"
#define REMOTE_SERVER_PORT 1533
int main()
{
NTPProtocol request,reply;
struct timeval time1;
struct tm *ptr;
time_t c_time;
unsigned long msec;
int sd, rc, i,serv;
struct sockaddr_in cliAddr, remoteServAddr;
struct hostent *h;
int peer;
FILE * peer1;
char buf[100];
int childpid;
/* To read the server IP address from the server.conf file */
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
/* command line args */
/* get server IP address */
h = gethostbyname(buf);
if( h == NULL )
{
printf("%s: unknown host \n", buf);
exit(1);
}
remoteServAddr.sin_family = h->h_addrtype;
memcpy((char *) &remoteServAddr.sin_addr.s_addr,
h->h_addr_list[0], h->h_length);
remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);
/* socket creation */
sd = socket(AF_INET,SOCK_DGRAM,0);
if( sd < 0 )
{
printf("Failed to open socket \n");
exit(1);
}
/* bind any port */
cliAddr.sin_family = AF_INET;
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
cliAddr.sin_port = htons(0);
rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
if( rc < 0 )
{
printf("%s: cannot bind port\n", buf);
exit(1);
}
/* sending data */
if((childpid = fork()) > 0) //if return value greater than
{ //it is parent process
printf("I am in Parent Process\n");
printf("Self process id=%d,Child process id=%d\n",getpid(),childpid);
printf("Parent Process exits..\n");
}
else if(childpid == 0) //child process
{
while (1)
{
printf("I am in Child Process\n");
printf("Parent process id=%d,Child process id=%d\n",getppid(),getpid());
/* build the request NTPProtocol 'packet', taking the ReferenceTime ,OriginateTime and
TransmitTime*/
gettimeofday(&time1,NULL);
request.OriginateTime.tv_sec= time1.tv_sec;
request.OriginateTime.tv_usec= time1.tv_usec;
request.Stratum=2;
request.ReferenceId=2;
request.Poll=10;
request.Mode=2; /*client*/
rc = sendto(sd,&request,sizeof(request), 0,
(struct sockaddr *) &remoteServAddr,
sizeof(remoteServAddr));
if( rc < 0 )
{
printf("Failed to send data \n");
close(sd);
exit(1);
}
serv=sizeof(remoteServAddr);
rc = recvfrom(sd,&reply,sizeof(reply), 0,
(struct sockaddr *) &remoteServAddr,
&serv);
gettimeofday(&time1,NULL);
request.ReferenceTime.tv_sec=time1.tv_sec;
request.ReferenceTime.tv_usec=time1.tv_usec;
request.RootDelay=((request.ReferenceTime.tv_sec) - (request.OriginateTime.tv_sec))/2;
/** get the time from the reply message and add to it the RootDelay and set the time*/
time1.tv_sec=reply.TransmitTime.tv_sec+request.RootDelay;
time1.tv_usec=reply.TransmitTime.tv_usec+((request.ReferenceTime.tv_usec) -
(request.OriginateTime.tv_usec))/2;
settimeofday(&time1,NULL);
c_time=time(NULL);
ptr=localtime(&c_time);
gettimeofday(&time1,NULL);
printf("the UTC time get it from the GPS server hour=%d min =%d second=%d
usecond=%06lu\n",ptr->tm_hour,ptr->tm_min, ptr->tm_sec,time1.tv_usec);
sleep(10);
}
}
return 0;
}
Server.conf
192.168.0.3
SNTP.h
#include <sys/times.h>
/* this is the protocol specification for SNTP Protocol */
/*defination of the SNTP protocol according to RFC 1361 */
/* the following struct contains the SNTP fields that */
/* must be exchange it between the client and the server */
/*( RPC client and RPC services) */
struct NTPProtocol{
char Mode; /*to indicate mode */
char Stratum; /*indicating the stratum level of the local clock */
int Poll; /* indicating the max interval between the successive message in seconds to the nearest
power of two*/
int Precision; /*indicating the precision of the local clock*/
long int RootDelay; /* indicating the total roundtrip delay to the primary refernce source*/
long int RootDispersion; /* indicating the max error relative to the primary reference source */ long
int ReferenceId; /*identifying the particular referce clock*/struct timeval ReferenceTime; /* local
time at which clock was set or corrected */
struct timeval OriginateTime; /*local time at which the request departed the client for the server */
struct timeval ReceiveTime; /*local time at which the request arrived at the server */
struct timeval TransmitTime; /* local time at which the reply departed the server for the for the client
*/
}; typedef struct NTPProtocol NTPProtocol;
Server Side
Server program
/**********************************************************************
Yarmouk University
Hijjawi College
Embedded engineering graduate
Source Name : SNTP_server.c
Programmers : Anwar
Abdel-ellah
Khawla
Supervisor :Dr.AL_Omari
Date : 18/07/2004
*---------------------------------------------------------------------
Description
SNTP_server Program : This program run at Server side as daemon that read the time of server
and reply it to any client that requests it through UDP server ,on the other hand the GPS program take
the UTC time through the serial port from the GPS and set the system time
accordingly **********************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include "sntp.h"
/*+++++++++++++++++++++++++++ SNTP server implementation+++++++++++++*/
#define LOCAL_SERVER_PORT 1533
int udp_srv()
{
NTPProtocol request,reply;
struct timeval time;
int sd, rc, n, cliLen;
struct sockaddr_in cliAddr, servAddr;
/* socket creation */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0)
{
printf("Failed to open socket \n");
exit(1);
}
/* bind local server port */
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(LOCAL_SERVER_PORT);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0)
{
printf(" Failed to bind port number %d \n", LOCAL_SERVER_PORT);
exit(1);
}
printf(" Server waiting for data on port %u\n", LOCAL_SERVER_PORT);
while(1)
{
/* function for receiving messages */
cliLen = sizeof(cliAddr);
n = recvfrom(sd,&request,sizeof(request), 0,
(struct sockaddr *) &cliAddr, &cliLen);
if(n<0)
{
printf("Failed to receive data \n");
continue;
}
gettimeofday(&time,NULL);
reply.ReceiveTime.tv_sec=time.tv_sec;
reply.ReceiveTime.tv_usec=time.tv_usec;
reply.Stratum=1;
reply.ReferenceId=1; /* GPS*/
/* sending data */
gettimeofday(&time,0);
reply.TransmitTime.tv_sec = time.tv_sec;
reply.TransmitTime.tv_usec = time.tv_usec;
n = sendto(sd,&reply, sizeof(reply), 0,
(struct sockaddr *) &cliAddr,sizeof(cliAddr));
if(n<0)
{
printf("Failed to sende data \n");
exit(1);
}
}//while
return 0;
}
SNTP.h
Same as in the client side
GPS Application Driver
/**********************************************************************
Yarmouk University
Hijjawi College
Embedded engineering graduate
Source Name : GPS.c
Programmers : Anwar
Abdel-ellah
Khawla
Supervisor : Dr.AL_Omari
Date : 18/07/2004
Description
GPS Program: This program run at Server side as daemon that
read the data from the GPS through the serial port and then analyze
it to get the UTC time frame day : hour : min : ss then after get these data update the system time of
server and also write the GPS data to GPS file */
********************************************************************/
/*++++++++++++++The header files used in this program+++++++++++++*/
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <signal.h>
#include <ctype.h>
#include <sys/time.h>
#include <time.h>
#define BAUDRATE 4800
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 // POSIX compliant source
#define maxsize 100
#define LF 0x0a
#define CR 0x0d
#define COMMA 0x2c
void INThandler(int); // Ctrl-C handler
extern udp_serm(void);
main()
{
pthread_t pthread;
struct termios oldtio,newtio;
int fd,res;
unsigned int i,j,k;
unsigned int numlinesread;
unsigned char charread[maxsize];
unsigned char stringread[maxsize];
unsigned char *pchar;
unsigned char dummychar;
unsigned char tempstring[maxsize];
unsigned char timestring[maxsize];
unsigned long utctime;
unsigned long utchour;
unsigned long utcminutes;
unsigned long utcseconds;
unsigned long jorhour;
unsigned long jorseconds;
unsigned long jorminutes;
time_t xx;
struct timeval t;
struct tm *y;
time_t yy;
time_t s;
FILE *log;
FILE *log1;
signal(SIGINT, INThandler); // install Ctrl-C handler
pthread_create(&pthread,NULL,&udp_serm,0);
dummychar = 'A';
pchar = &dummychar;
log = fopen("GPS.txt","w+");
log1 = fopen("GPS1.txt","w+");
numlinesread = 0;
// open the device to be non-blocking (read will return immediatly)
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY/* | O_NONBLOCK*/);
if (fd <0)
{
perror(MODEMDEVICE);
exit(-1);
}
// save current port settings
tcgetattr(fd,&oldtio);
bzero(&newtio,sizeof(newtio));
// set new port settings for raw input processing
// zero(&newtio, sizeof(newtio));
newtio.c_cflag = B4800/* | CRTSCTS*/ | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR|IGNBRK;
newtio.c_oflag = 0;
newtio.c_lflag =0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
// getting data from serial port
do
{
res=read(fd,charread,1);
if(res== -1)
{
printf("Please connect your GPS\n");
exit(0);
}
if(charread[0]=='$')
{
i=0;
numlinesread++;
stringread[i]=charread[0];
do
{
res=read(fd,charread,1);
if((charread[0]!='\0') &&
(isalnum(charread[0])||isspace(charread[0])||ispunct(charread[0])));
{
i++;
stringread[i]=charread[0];
}
} while(charread[0]!=LF);
stringread[i+1]='\0'; //append null terminator to the string read
//************* analyze string*************************************************
j=0;
pchar=stringread;
while(*(pchar+j) !=COMMA)
{
tempstring[j]= *(pchar+j);
j++;
}
tempstring[j]='\0';
//check if sting is $GPGGA ,it has 14 comms total
if((tempstring[3]=='G') && (tempstring[4]=='G') && (tempstring[5]=='A'))
{
pchar=stringread;
// get UTC time*****************************************************************
j=7; //start of time field
k=0;
while(*(pchar+j) != COMMA)
{
timestring[k]= *(pchar+j);
j++;
k++;
}
timestring[k] ='\0';
sscanf(timestring,"%ld",&utctime);
utchour = (utctime/10000);
utcminutes =(utctime - (utchour * 10000))/ 100;
utcseconds =utctime - (utchour * 10000) - (utcminutes * 100);
printf("THIS IS THE UTC TIME RECIEVED\n");
printf(" hh=%02ld :mm=%02ld :ss=%02ld\n",utchour,utcminutes,
utcseconds);
printf("THIS IS THE LOCAL JORDAN TIME\n");
if(utchour>=0 && utchour<= 20)
{
jorhour=utchour+3;
jorminutes = utcminutes;
jorseconds = utcseconds;
}
else
{
jorhour = utchour-21;
jorminutes = utcminutes;
jorseconds = utcseconds;
}
printf(" hh=%02ld :mm=%02ld :ss=%02ld\n",jorhour,jorminutes,
jorseconds);
//getting the system time and adjusting it according to the local time received
from GPS
gettimeofday(&t,NULL);
printf("systemtime: %lu.%06lu\n",t.tv_sec,t.tv_usec);
xx = t.tv_sec;
printf("no ofseconds since 1/1/1970 = %lu\n",xx);
printf("the system time before adjusting is %s\n",ctime(&xx));
y=localtime(&xx);
y->tm_sec=jorseconds;
y->tm_min=jorminutes;
y->tm_hour=jorhour;
y->tm_mon=y->tm_mon;
y->tm_year=y->tm_year;
printf("jorseconds %d\n",y->tm_sec);
printf("jorminutes %d\n",y->tm_min);
printf("jorhour %d\n",y->tm_hour);
printf("jorday %d\n",y->tm_mday);
printf("jormonth %d\n",y->tm_mon+1);
printf("joryear %d\n",y->tm_year+1900);
printf("jorwday %d\n",y->tm_wday);
printf("joryday %d\n",y->tm_yday);
s=mktime(y);
printf("no of sec %lu\n",s);
t.tv_sec=s;
t.tv_usec=0;
settimeofday(&t,NULL);
printf("the adjusted new time is: %s\n",ctime(&s));
gettimeofday(&t,NULL);
yy=t.tv_sec;
printf("%lu\n",yy);
fprintf(log1,"system time adjusted at : %s\n",ctime(&s));
// not a GPGGA sentencs
}
fprintf(log , "%d : (%d) %s\n" , numlinesread , i , stringread);
}
// otherwise not a $ character ..so loop until one arrives
}while(1);
// restore old port setting ************************************
tcsetattr(fd,TCSANOW,&oldtio);
fclose(log);
fclose(log1);
close(fd);
return 0 ;
}
void INThandler(int sig)
{
char c;
signal(sig, SIG_IGN); // disable Ctrl-C
printf("WAIT, did you hit Ctrl-C?\n" // print something
"Do you really want to quit? [y/n] ");
c = getchar(); // read an input character
if (c == 'y' || c == 'Y') // if it is y or Y, then
exit(0); // exit. Otherwise,
else
signal(SIGINT, INThandler); // reinstall the handler
}
Makefile
gps:gps.o SNTP_server.o
gcc -o gps gps.o SNTP_server.o -lpthread
gps.o:gps.c
gcc -c gps.c
SNTP_server.o:SNTP_server.c
gcc -c SNTP_server.c
GPS File
After run this package this file will Contain Contains the GPS captured data
GPS1 File
After run this package this file will Contain the UTC Time got it from the GPS data.
5. SNTP Package Version ‘5’
Client Side
Client Program
/*****************************************************************/
Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : SNTP_client.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004
Description : RPC Client Program
the client program polling the server every specific polling interval in seconds and update it's time
accordingly*********************/
/* this file contains the RPC client which will be accessed the RPC service through the stub
client */
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/times.h>
#include <rpc/rpc.h>
#include <string.h>
#include <time.h>
#include "SNTP.h" /* header file from the rpcgen utililty */
main()
{ struct tm *ptr;
time_t c_time;
int i;
int childpid;
FILE * peer1;
CLIENT *cl;
NTPProtocol request,*reply;
char buf[100];
struct timeval t1;
peer1=fopen("server.conf","r+");
fscanf(peer1,"%s",buf);
/* connect to the server specified in the server.conf file*/
cl=clnt_create(buf,NTPPROG,NTPVERS,"udp");
if(cl==NULL) {
clnt_pcreateerror(buf);
exit(2);
}
if((childpid = fork()) > 0) //if return value greater than zero
{ //it is parent process
printf("I am in Parent Process\n");
printf("Self process id=%d,Child process id=%d\n",getpid(),childpid);
printf("Parent Process exits..\n");
}
else if(childpid == 0) //child process
{
printf("I am in Child Process\n");
printf("Parent process id=%d,Child process id=%d\n",getppid(),getpid());
while(1)
{
/* build the request NTPProtocol 'packet', taking the ReferenceTime ,OriginateTime and
TransmitTime*/
gettimeofday(&t1,NULL);
request.OriginateTime.tv_sec= t1.tv_sec;
request.OriginateTime.tv_usec= t1.tv_usec;
request.Stratum=2;
request.ReferenceId=2;
request.Poll=10;
request.Mode=2; /*client*/
/* Call the remote service */
reply=get_ntptime_1(&request,cl);
if ( reply==NULL)
{ clnt_perror(cl,buf);
exit(3);
}
gettimeofday(&t1,NULL);
request.ReferenceTime.tv_sec=t1.tv_sec;
request.ReferenceTime.tv_usec=t1.tv_usec;
request.RootDelay=((request.ReferenceTime.tv_sec) - (request.OriginateTime.tv_sec))/2;
/****************** get the time from the reply message and add to it the RootDelay and set the
time*/
t1.tv_sec=reply->TransmitTime.tv_sec+request.RootDelay;
t1.tv_usec=reply->TransmitTime.tv_usec+((request.ReferenceTime.tv_usec) -
(request.OriginateTime.tv_usec))/2;
settimeofday(&t1,NULL);
c_time=time(NULL);
ptr=localtime(&c_time);
gettimeofday(&t1,NULL);
printf("the UTC time get it from the GPS server hour=%d min =%d second=%d
usecond=%06lu\n",ptr->tm_hour,ptr->tm_min, ptr->tm_sec,t1.tv_usec);
sleep(10);
}//while loop
}
}
Client Stub
/* Please do not edit this file.It was generated using rpcgen.*/
#include <memory.h> /* for memset */
#include "SNTP.h"
/* Default timeout can be changed using clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
NTPProtocol *
get_ntptime_1(NTPProtocol *argp, CLIENT *clnt)
{
static NTPProtocol clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call (clnt, get_ntptime,
(xdrproc_t) xdr_NTPProtocol, (caddr_t) argp,
(xdrproc_t) xdr_NTPProtocol, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) {
return (NULL);
}
return (&clnt_res);
}
XDR filter
/*Please do not edit this file. It was generated using rpcgen.*/
#include "SNTP.h"
bool_t
xdr_timeval (XDR *xdrs, timeval *objp)
{
register int32_t *buf;
if (!xdr_long (xdrs, &objp->tv_sec))
return FALSE;
if (!xdr_long (xdrs, &objp->tv_usec))
return FALSE;
return TRUE;
}
bool_t
xdr_NTPProtocol (XDR *xdrs, NTPProtocol *objp)
{
register int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
if (!xdr_char (xdrs, &objp->Mode))
return FALSE;
if (!xdr_char (xdrs, &objp->Stratum))
return FALSE;
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->Poll))
return FALSE;
if (!xdr_int (xdrs, &objp->Precision))
return FALSE;
if (!xdr_long (xdrs, &objp->RootDelay))
return FALSE;
if (!xdr_long (xdrs, &objp->RootDispersion))
return FALSE;
if (!xdr_long (xdrs, &objp->ReferenceId))
return FALSE;
} else {
IXDR_PUT_LONG(buf, objp->Poll);
IXDR_PUT_LONG(buf, objp->Precision);
IXDR_PUT_LONG(buf, objp->RootDelay);
IXDR_PUT_LONG(buf, objp->RootDispersion);
IXDR_PUT_LONG(buf, objp->ReferenceId);
}
if (!xdr_timeval (xdrs, &objp->ReferenceTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->OriginateTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->ReceiveTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->TransmitTime))
return FALSE;
return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
if (!xdr_char (xdrs, &objp->Mode))
return FALSE;
if (!xdr_char (xdrs, &objp->Stratum))
return FALSE;
buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->Poll))
return FALSE;
if (!xdr_int (xdrs, &objp->Precision))
return FALSE;
if (!xdr_long (xdrs, &objp->RootDelay))
return FALSE;
if (!xdr_long (xdrs, &objp->RootDispersion))
return FALSE;
if (!xdr_long (xdrs, &objp->ReferenceId))
return FALSE;
} else {
objp->Poll = IXDR_GET_LONG(buf);
objp->Precision = IXDR_GET_LONG(buf);
objp->RootDelay = IXDR_GET_LONG(buf);
objp->RootDispersion = IXDR_GET_LONG(buf);
objp->ReferenceId = IXDR_GET_LONG(buf);
}
if (!xdr_timeval (xdrs, &objp->ReferenceTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->OriginateTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->ReceiveTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->TransmitTime))
return FALSE;
return TRUE;
}
if (!xdr_char (xdrs, &objp->Mode))
return FALSE;
if (!xdr_char (xdrs, &objp->Stratum))
return FALSE;
if (!xdr_int (xdrs, &objp->Poll))
return FALSE;
if (!xdr_int (xdrs, &objp->Precision))
return FALSE;
if (!xdr_long (xdrs, &objp->RootDelay))
return FALSE;
if (!xdr_long (xdrs, &objp->RootDispersion))
return FALSE;
if (!xdr_long (xdrs, &objp->ReferenceId))
return FALSE;
if (!xdr_timeval (xdrs, &objp->ReferenceTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->OriginateTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->ReceiveTime))
return FALSE;
if (!xdr_timeval (xdrs, &objp->TransmitTime))
return FALSE;
return TRUE;
}
SNTP.h header
/*Please do not edit this file.It was generated using rpcgen.*/
#ifndef _NTP_H_RPCGEN
#define _NTP_H_RPCGEN
#include <rpc/rpc.h>
#include <sys/times.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct timeval timeval;
/* this is the protocol specification for SNTP Protocol */
/*defination of the SNTP protocol according to RFC 1361 */
/* the following struct contains the SNTP fields that */
/* must be exchange it between the client and the server */
/*( RPC client and RPC services)
*/
struct NTPProtocol{
char Mode; /*to indicate mode */
char Stratum; /*indicating the stratum level of the local clock*/
int Poll; /* indicating the max interval between the sucessive message in seconds */
int Precision; /*indicating the precision of the local clock*/
long int RootDelay; /* indicating the total roundtrip delay to the primary refernce source*/
long int RootDispersion; /* indicating the max error relative to the primary reference source */
long int ReferenceId; /*identifying the particular referce clock*/
struct timeval ReferenceTime; /* local time at which clock was set or corrected */
struct timeval OriginateTime; /*local time at which the request departed the client for the server */
struct timeval ReceiveTime; /*local time at which the request arrived at the server */
struct timeval TransmitTime; /* local time at which the reply departed the server for the for the client
*/
};typedef struct NTPProtocol NTPProtocol;
#define NTPPROG 0x2000003a
#define NTPVERS 1
#if defined(__STDC__) || defined(__cplusplus)
#define get_ntptime 1
extern NTPProtocol * get_ntptime_1(NTPProtocol *, CLIENT *);
extern NTPProtocol * get_ntptime_1_svc(NTPProtocol *, struct svc_req *);
extern int ntpprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#define get_ntptime 1
extern NTPProtocol * get_ntptime_1();
extern NTPProtocol * get_ntptime_1_svc();
extern int ntpprog_1_freeresult ();
#endif /* K&R C */
/* the xdr functions */
#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_timeval (XDR *, timeval*);
extern bool_t xdr_NTPProtocol (XDR *, NTPProtocol*);
#else /* K&R C */
extern bool_t xdr_timeval ();
extern bool_t xdr_NTPProtocol ();
#endif /* K&R C */
#ifdef __cplusplus
}
#endif
#endif /* !_NTP_H_RPCGEN */
Makefile
SNTP_client: SNTP_client.o
gcc -o SNTP_client SNTP_client.o SNTP_clnt.c SNTP_xdr.c -lnsl
SNTP_client.o:SNTP_client.c
gcc -c SNTP_client.c
Server Side
GPS Application Driver
Same s in Time Protocol version ‘4’
Server Service
/**********************************************************************
Yarmouk University
Hijjawi College
Embedded Engineering Graduate
Source Name : SNTP_server.c
Programmers : Anwar
Abdel-ellah
Khawla
Date : 14/07/2004 Description : RPC Client Program
*****************************************************************/
/*===================== SNTP Protocol Implementation========== */
/*++++++++++++++++++++++SNTP Server+++++++++++++++++++++++ */
/*+++++++++++++++ this file contains the RPC services */
/* that will be accessed by the RPC client through the server stub*/
/*--------------------------------------------------------------*/
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <rpc/rpc.h>
#include <time.h>
#include "SNTP.h" /* header file from the rpcgen utility */
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <signal.h>
NTPProtocol *get_ntptime_1(NTPProtocol * request,CLIENT *cl)
{static NTPProtocol reply;
static struct timeval time1,t2;
printf("Thread id = '%ld' started\n",pthread_self());
sleep(5);
gettimeofday(&t2,NULL);
reply.ReceiveTime.tv_sec=t2.tv_sec;
reply.ReceiveTime.tv_usec=t2.tv_usec;
gettime1(&time1);
reply.TransmitTime.tv_sec = time1.tv_sec;
reply.TransmitTime.tv_usec = time1.tv_usec;
reply.Stratum=1;
reply.ReferenceId=1; /* GPS*/
return &reply;
}
int gettime1(struct timeval*t1)
{
struct tm *ptr;
time_t c_time;
int hour,min,sec,msec;
gettimeofday(t1,0);
return 0;
}
Server Wrapper
/*.It was generated using rpcgen there is some modification added by us.*/
#include "SNTP.h"
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif
pthread_t p_thread;
pthread_attr_t attr;
/* Procedure to be run by thread */
void *
serv_request(void *data)
{
struct thr_data
{
struct svc_req *rqstp;
SVCXPRT *transp;
} *ptr_data;;
union {
NTPProtocol get_ntptime_1_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
ptr_data = (struct thr_data *)data;
struct svc_req *rqstp = ptr_data->rqstp;
register SVCXPRT *transp = ptr_data->transp;
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
case get_ntptime:
_xdr_argument = (xdrproc_t) xdr_NTPProtocol;
_xdr_result = (xdrproc_t) xdr_NTPProtocol;
local = (char *(*)(char *, struct svc_req *)) get_ntptime_1;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
exit (1);
}
return;
}
static void
ntpprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
struct data_str
{
struct svc_req *rqstp;
SVCXPRT *transp;
} *data_ptr=(struct data_str*)malloc(sizeof(struct data_str));
{data_ptr->rqstp = rqstp;
data_ptr->transp = transp;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&p_thread,&attr,serv_request,(void *)data_ptr);
}
}
int main (int argc, char **argv)
{
register SVCXPRT *transp;
int childpid;
if((childpid = fork()) > 0) //if return value greater than zero
{ //it is parent process
printf("I am in Parent Process\n");
printf("Self process id=%d,Child process id=%d\n",getpid(),childpid);
printf("Parent Process exits..\n");
}
else if(childpid == 0) //child process
{
printf("I am in Child Process\n");
printf("Parent process id=%d,Child process id=%d\n",getppid(),getpid());
pmap_unset (NTPPROG, NTPVERS);
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create udp service.");
exit(1);
}
if (!svc_register(transp, NTPPROG, NTPVERS, ntpprog_1, IPPROTO_UDP)) {
fprintf (stderr, "%s", "unable to register (NTPPROG, NTPVERS, udp).");
exit(1);
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create tcp service.");
exit(1);
}
if (!svc_register(transp, NTPPROG, NTPVERS, ntpprog_1, IPPROTO_TCP)) {
fprintf (stderr, "%s", "unable to register (NTPPROG, NTPVERS, tcp).");
exit(1);
}
svc_run ();
fprintf (stderr, "%s", "svc_run returned");
exit (1);
/* NOTREACHED */
}
}
XDR filter
Same as in client side in this package
SNTP.h header
Same as in client side in this package
SNTP.x protocol specification
/*++++++++++++++++++++++NTP Protocol+++++++++++++++++++++++*/
/*+++++++++++++++ this file will be used by the rpcgen */
/*utility to generate three files the header file and stub */
/* client and stub server files */
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*---------------------------------------------------------*/
/* programmers : Anwar/abdallah/khawla
Date : 9/7/2004
Name :SNTP.x
*/
/* this is the protocol specification for SNTP Protocol */
/*definition of the SNTP protocol according to RFC 1361 */
/* the following struct contains the SNTP fields that */
/* must be exchange it between the client and the server */
/*( RPC client and RPC services)
*/
struct timeval{
long tv_sec;
long tv_usec;
};
struct NTPProtocol{
char Mode; /*to indicate mode */
char Stratum; /*indicating the stratum level of the local clock*/
int Poll; /* indicating the max interval between the sucessive message in seconds */
int Precision; /*indicating the precision of the local clock*/
long int RootDelay; /* indicating the total roundtrip delay to the primary refernce source*/
long int RootDispersion; /* indicating the max error relative to the primary reference source */
long int ReferenceId; /*identifying the particular referce clock*/
struct timeval ReferenceTime; /* local time at which clock was set or corrected */
struct timeval OriginateTime; /*local time at which the request departed the client for the server */
struct timeval ReceiveTime; /*local time at which the request arrived at the server */
struct timeval TransmitTime; /* local time at which the reply departed the server for the for the client
*/
};
/* the Program Definition +++++++++++++++++++++++++++++*/
program NTPPROG {
version NTPVERS {
NTPProtocol get_ntptime( NTPProtocol ) = 1;
} = 1; /*the version number */
} = 0x2000003a; /* the program number */
Makefile
gps_server: SNTP_server.o gps.o
gcc -o gps_server SNTP_server.o gps.o SNTP_svc.c SNTP_xdr.c - lnsl -lpthread
gps.o:gps.c
gcc -c gps.c
SNTP_server.o:SNTP_server.c
gcc -c SNTP_server.c
GPS File
After run this package this file will Contain Contains the GPS captured data
GPS1 File
After run this package this file will Contain the UTC Time got it from the GPS data.
Appendix B: Serial Port
The conventional serial port (not the newer USB port, or HSSI port) is a very old I/O port.
Almost all PC's have them. Macs (Apple Computer) after mid-1998 only have the USB port.
However, it's possible, to put a conventional serial port device on the USB.
Each serial port has a "file" associated with it in the /dev directory. It isn't really a file but it seems
like one. For newer versions of Linux which use the Device File System (devfs) an ordinary serial
port is for example: /dev/tts/0. Formerly (before the devfs) this port was called /dev/ttyS0. Other serial
ports are /dev/tts/1, /dev/tts/2, etc. But ports on the USB bus, multiport cards, etc. have different
names.
The common specification for the conventional serial port is RS-232 (or EIA-232). The connector for
the serial port is often seen as one or two 9-pin connectors (in some cases 25-pin) on the back of a PC. But the
serial port is more than just that. It includes the associated electronics which must produce signals conforming
to the EIA-232 specification. One pin is used to send out data bytes and another to receive data bytes. Another
pin is a common signal ground. The other "useful" pins are used mainly for signaling purposes with a steady
negative voltage meaning "off" and a steady positive voltage meaning "on”. Table ()shows the Serial Pin outs
(D25 and D9 Connectors),while table () shows the pin functions.
D-Type-25 Pin
No. D-Type-9 Pin No. Abbreviation Full Name
Pin 2 Pin 3 TD Transmit Data
Pin 3 Pin 2 RD Receive Data
Pin 4 Pin 7 RTS Request To Send
Pin 5 Pin 8 CTS Clear To Send
Pin 6 Pin 6 DSR Data Set Ready
Pin 7 Pin 5 SG Signal Ground
Pin 8 Pin 1 CD Carrier Detect
Pin 20 Pin 4 DTR Data Terminal Ready
Pin 22 Pin 9 RI Ring Indicator
Table 1 : D Type 9 Pin and D Type 25 Pin Connectors
Pin Function
Abbreviation Full Name Function
TD Transmit Data Serial Data Output (TXD)
RD Receive Data Serial Data Input (RXD)
CTS Clear to Send This line indicates that the Modem is ready to exchange data.
DCD Data Carrier
Detect
When the modem detects a "Carrier" from the modem at the
other end of the phone line, this Line becomes active.
DSR Data Set
Ready
This tells the UART that the modem is ready to establish a
link.
DTR Data Terminal
Ready
This is the opposite to DSR. This tells the Modem that the
UART is ready to link.
RTS Request To
Send
This line informs the Modem that the UART is ready to
exchange data.
RI Ring Indicator Goes active when modem detects a ringing signal from the
PSTN.
2.1 Transmitting
Transmitting is sending bytes out of the serial port away from the computer. Once one
understands transmitting, receiving is easy to understand since it's similar. The first explanation given
here will be grossly oversimplified. Then more detail will be added in later explanations. When the
computer wants to send a byte out the serial port (to the external cable) the CPU sends the byte on the
bus inside the computer to the I/O address of the serial port. The serial port takes the byte, and sends it
out one bit at a time (a serial bit-stream) on the transmit pin of the serial cable connector. For what a
bit (and byte) look like electrically.
Here's a replay of the above in a little more detail (but still very incomplete). Most of the work at the
serial port is done by the UART chip (or the like). To transmit a byte, the serial device driver program
(running on the CPU) sends a byte to the serial port’s I/O address. This byte gets into a 1-byte
"transmit shift register" in the serial port. From this shift register bits are taken from the byte one-by-
one and sent out bit-by-bit on the serial line. Then when the last bit has been sent and the shift register
needs another byte to send it could just ask the CPU to send it another byte. Thus would be simple but
it would likely introduce delays since the CPU might not be able to get the byte immediately. After
all, the CPU is usually doing other things besides just handling the serial port.
A way to eliminate such delays is to arrange things so that the CPU gets the byte before the shift
register needs it and stores it in a serial port buffer (in hardware). Then when the shift register has sent
out its byte and needs a new byte immediately, the serial port hardware just transfers the next byte
from its own buffer to the shift register. No need to call the CPU to fetch a new byte.
The size of this serial port buffer was originally only one byte, but today it is usually 16 bytes (more
in higher priced serial ports). Now there is still the problem of keeping this buffer sufficiently
supplied with bytes so that when the shift register needs a byte to transmit it will always find one there
(unless there are no more bytes to send). This is done by contacting the CPU using an interrupt.
First we'll explain the case of the old fashioned one-byte buffer, since 16-byte buffers work similarly
(but are more complex). When the shift register grabs the byte out of the buffer and the buffer needs
another byte, it sends an interrupt to the CPU by putting a voltage on a dedicated wire on the
computer bus. Unless the CPU is doing something very important, the interrupt forces it to stop what
it was doing and start running a program which will supply another byte to the port's buffer. The
purpose of this buffer is to keep an extra byte (waiting to be sent) queued in hardware so that there
will be no gaps in the transmission of bytes out the serial port cable.
Once the CPU gets the interrupt, it will know who sent the interrupt since there is a dedicated
interrupt wire for each serial port (unless interrupts are shared). Then the CPU will start running the
serial device driver which checks registers at I/0 addresses to find out what has happened. It finds out
that the serial's transmit buffer is empty and waiting for another byte. So if there are more bytes to
send, it sends the next byte to the serial port's I/0 address. This next byte should arrive when the
previous byte is still in the transmit shift register and is still being transmitted bit-by-bit.
In review, when a byte has been fully transmitted out the transmit wire of the serial port and the
shift register is now empty the following 3 things happen almost simultaneously:
1. The next byte is moved from the transmit buffer into the transmit shift register
2. The transmission of this new byte (bit-by-bit) begins
3. Another interrupt is issued to tell the device driver to send yet another byte to the
now empty transmit buffer
Thus we say that the serial port is interrupt driven. Each time the serial port issues an interrupt, the
CPU sends it another byte. Once a byte has been sent to the transmit buffer by the CPU, then the CPU
is free to pursue some other activity until it gets the next interrupt. The serial port transmits bits at a
fixed rate which is selected by the user (or an application program). It's sometimes called the baud
rate. The serial port also adds extra bits to each byte (start, stop and perhaps parity bits) so there are
often 10 bits sent per byte. At a rate (also called speed) of 19,200 bits per second (bps), there are thus
1,920 bytes/sec (and also 1,920 interrupts/sec).
Doing all this is a lot of work for the CPU. This is true for many reasons. First, just sending one 8-bit
byte at a time over a 32-bit data bus (or even 64-bit) is not a very efficient use of bus width. Also,
there is a lot of overhead in handing each interrupt. When the interrupt is received, the device driver
only knows that something caused an interrupt at the serial port but doesn't know that it's because a
character has been sent. The device driver has to make various checks to find out what happened. The
same interrupt could mean that a character was received, one of the control lines changed state, etc.
A major improvement has been the enlargement of the buffer size of the serial port from 1-byte to 16-
bytes. This means that when the CPU gets an interrupt it gives the serial port up to 16 new bytes to
transmit. This is fewer interrupts to service but data must still be transferred one byte at a time over a
wide bus. The 16-byte buffer is actually a FIFO (First In First Out) queue and is often called a FIFO.
2.2 Receiving
Receiving bytes by a serial port is similar to sending them only it's in the opposite direction. It's also
interrupt driven. For the obsolete type of serial port with 1-byte buffers, when a byte is fully received
from the external cable it goes into the 1-byte receive buffer. Then the port gives the CPU an interrupt
to tell it to pick up that byte so that the serial port will have room for storing the next byte which is
currently being received. For newer serial ports with 16-byte buffers, this interrupt (to fetch the bytes)
may be sent after 14 bytes are in the receive buffer. The CPU then stops what it was doing, runs the
interrupt service routine, and picks up 14 to 16 bytes from the port. For an interrupt sent when the
14th byte has been received, there could be 16 bytes to get if 2 more bytes have arrived since the
interrupt. But if 3 more bytes should arrive (instead of 2), then the 16-byte buffer will overrun. It also
may pick up less than 14 bytes by setting it that way or due to timeouts.
The Large Serial Buffers
We've talked about small 16-byte serial port hardware buffers but there are also much larger buffers in
main memory. When the CPU takes some bytes out of the receive buffer of the hardware, it puts them
into a much larger (say 8k-byte) receive buffer in main memory. Then a program that is getting bytes
from the serial port takes the bytes it's receiving out of that large buffer (using a "read" statement in
the program). A similar situation exists for bytes that are to be transmitted. When the CPU needs to
fetch some bytes to be transmitted it takes them out of a large (8k-byte) transmit buffer in main
memory and puts them into the small 16-byte transmit buffer in the hardware.
Appendix C: NMEA Protocol
The National Marine Electronics Association in USA establishes the NMEA standards.
NMEA 0183 Data Format
The NMEA 0183 data format conforms to the ASCII protocol. The broad array of navigational data is
formatted into sentences. Each sentence conveys a specific set of information. Each electronic
equipments NMEA 0183 library contains a number of sentences. Below is list of the most common
sentences, which are described later in this report. NMEA is a standard protocol, used by GPS
receivers to transmit data. NMEA output is EIA-422A but for most purposes you can consider it RS-
232 compatible. Use 4800 bps, 8 data bits, no parity and one stop bit ( 8N1 ). NMEA 0183 sentences
are all ASCII. Each sentence begins with a dollar sign ($) and ends with a carriage return linefeed
(<CR><LF>). Data is comma delimited. All commas must be included as they act as markers. Some
GPS do not send some of the fields. A checksum is optionally added (in a few cases it is mandatory).
Following the $ is the address field aaccc. aa is the device id. GP is used to identify GPS data.
Transmission of the device ID is usually optional. ccc is the sentence formatter, otherwise known as
the sentence name.
NMEA 0183 data sentences are structured as follows:
$TTSSS,Dl,D2,D3,D4,......,DN*CS[CR] [LF]
$ Sentence Start.
TT Talker ID.
SSS Sentence ID.
, Data Field Delimiter.
Dn Data Field.
* Checksum Identifier.
CS Checksum.
[CR][LF] Sentence Terminator.
NMEA 0183 sentences must be 79 characters or less. This 1imit excludes the "$" and the
"[CR][LF]". The Talker ID the source of the data (GPS, Loran C, Sounder, etc.). The NMEA 0183
standard defines 35 Talker IDs. The Sentence ID is a three character mnemonic, which describes the
data type, the number of data fields, and the order of the data fields.
All $GPxxx sentence codes and short descriptions
$GPAAM - Waypoint Arrival Alarm
$GPALM - GPS Almanac Data
$GPAPA - Autopilot format "A"
$GPAPB - Autopilot format "B"
$GPASD - Autopilot System Data
$GPBEC - Bearing & Distance to Waypoint, Dead Reckoning
$GPBOD - Bearing, Origin to Destination
$GPBWC - Bearing & Distance to Waypoint, Great Circle
$GPBWR - Bearing & Distance to Waypoint, Rhumb Line
$GPBWW - Bearing, Waypoint to Waypoint
$GPDBT - Depth Below Transducer
$GPDCN - Decca Position
$GPDPT - Depth
$GPFSI - Frequency Set Information
$GPGGA - Global Positioning System Fix Data
$GPGLC - Geographic Position, Loran-C
$GPGLL - Geographic Position, Latitude/Longitude
$GPGRS - GPS Range Residuals
$GPGSA - GPS DOP and Active Satellites
$GPGST - GPS Pseudo range Noise Statistics
$GPGSV - GPS Satellites in View
$GPGXA - TRANSIT Position
$GPHDG - Heading, Deviation & Variation
$GPHDT - Heading, True
$GPHSC - Heading Steering Command
$GPLCD - Loran-C Signal Data
$GPMSK - Control for a Beacon Receiver
$GPMSS - Beacon Receiver Status
$GPMTA - Air Temperature (to be phased out)
$GPMTW - Water Temperature
$GPMWD - Wind Direction
$GPMWV - Wind Speed and Angle
$GPOLN - Omega Lane Numbers
$GPOSD - Own Ship Data
$GPR00 - Waypoint active route (not standard)
$GPRMA - Recommended Minimum Specific Loran-C Data
$GPRMB - Recommended Minimum Navigation Information
$GPRMC - Recommended Minimum Specific GPS/TRANSIT Data
$GPROT - Rate of Turn
$GPRPM - Revolutions
$GPRSA - Rudder Sensor Angle
$GPRSD - RADAR System Data
$GPRTE - Routes
$GPSFI - Scanning Frequency Information
$GPSTN - Multiple Data ID
$GPTRF - Transit Fix Data
$GPTTM - Tracked Target Message
$GPVBW - Dual Ground/Water Speed
$GPVDR - Set and Drift
$GPVHW - Water Speed and Heading
$GPVLW - Distance Traveled through the Water
$GPVPW - Speed, Measured Parallel to Wind
$GPVTG - Track Made Good and Ground Speed
$GPWCV - Waypoint Closure Velocity
$GPWNC - Distance, Waypoint to Waypoint
$GPWPL - Waypoint Location
$GPXDR - Transducer Measurements
$GPXTE - Cross-Track Error, Measured
$GPXTR - Cross-Track Error, Dead Reckoning
$GPZDA - UTC Date / Time and Local Time Zone Offset
$GPZFO - UTC & Time from Origin Waypoint
$GPZTG - UTC & Time to Destination Waypoint
The GPS message that we used in our project is $GPGGA ,which is illustrated below:
$GPGGA Sentence (Fix data)
Example (signal not acquired):
$GPGGA,235947.000,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,,,,0000*00
Example (signal acquired):
$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F
Field Example Comments
Sentence ID $GPGGA
UTC Time 092204.999 hhmmss.sss
Latitude 4250.5589 ddmm.mmmm
N/S Indicator S N = North, S = South
Longitude 14718.5084 dddmm.mmmm
E/W Indicator E E = East, W = West
Position Fix 1 0 = Invalid, 1 = Valid SPS, 2 = Valid DGPS, 3 = Valid PPS
Satellites Used 04 Satellites being used (0-12)
HDOP 24.4 Horizontal dilution of precision
Altitude 19.7 Altitude in meters according to WGS-84 ellipsoid
Altitude Units M M = Meters
Geoid Separation Geoid separation in meters according to WGS-84 ellipsoid
Separation Units M = Meters
DGPS Age Age of DGPS data in seconds
DGPS Station ID 0000
Checksum *1F
Terminator CR/LF
Appendix D: A Remote Procedure Calls (RPC)
What Is RPC
RPC is a powerful technique for constructing distributed, client-server based applications. It is
based on extending the notion of conventional, or local procedure calling, so that the called procedure
need not exist in the same address space as the calling procedure. The two processes may be on the
same system, or they may be on different systems with a network connecting them. By using RPC,
programmers of distributed applications avoid the details of the interface with the network. The
transport independence of RPC isolates the application from the physical and logical elements of the
data communications mechanism and allows the application to use a variety of transports.
RPC makes the client/server model of computing more powerful and easier to program. When
combined with the ONC RPCGEN protocol compiler ,clients transparently make remote calls through
a local procedure interface.
How RPC Works
An RPC is analogous to a function call. Like a function call, when an RPC is made, the calling
arguments are passed to the remote procedure and the caller waits for a response to be returned from
the remote procedure. The Figure below shows the flow of activity that takes place during an RPC
call between two networked systems. The client makes a procedure call that sends a request to the
server and waits. The thread is blocked from processing until either a reply is received, or it times out.
When the request arrives, the server calls a dispatch routine that performs the requested service, and
sends the reply to the client. After the RPC call is completed, the client program continues. RPC
specifically supports network applications.
A remote procedure is uniquely identified by the triple: (program number, version number,
procedure number) The program number identifies a group of related remote procedures, each of
which has a unique procedure number. A program may consist of one or more versions. Each version
consists of a collection of procedures which are available to be called remotely. Version numbers
enable multiple versions of an RPC protocol to be available simultaneously. Each version contains a a
number of procedures that can be called remotely. Each procedure has a procedure number.
Remote Procedure Calling Mechanism
To develop an RPC application the following steps are needed:
Specify the protocol for client server communication
Develop the client program
Develop the server program
The programs will be compiled separately. The communication protocol is achieved by
generated stubs and these stubs and rpc (and other libraries) will need to be linked in.
Defining the Protocol
The easiest way to define and generate the protocol is to use a protocol compiler such as
rpcgen.
For the protocol you must identify the name of the service procedures and data types of parameters
and return arguments.
The protocol compiler reads a definition and automatically generates client and server stubs.
rpcgen uses its own language (RPC language or RPCL) which looks very similar to preprocessor
directives.
rpcgen exists as a standalone executable compiler that reads special files denoted by a .x prefix.
So to compile a RPCL file you simply do
rpcgen rpcprog.x
This will generate possibly four files:
rpcprog_clnt.c -- the client stub
rpcprog_svc.c -- the server stub
rpcprog_xdr.c -- If necessary XDR (external data representation) filters
rpcprog.h -- the header file needed for any XDR filters.
The external data representation (XDR) is an data abstraction needed for machine independent
communication. The client and server need not be machines of the same type.
Defining Client and Server Application Code
Client and application code must communicate via procedures and data types specified in the
Protocol.
The service side will have to register the procedures that may be called by the client and receive and
return any data required for processing.
The client application call the remote procedure pass any required data and will receive the returned
data.
There are several levels of application interfaces that may be used to develop RPC applications.
Compiling and running the application
Let us consider the full compilation model required to run a RPC application. Makefiles are
useful for easing the burden of compiling RPC applications but it is necessary to understand the
complete model before one can assemble a convenient makefile.
Assume the client program is called rpcprog.c, the service program is rpcsvc.c and that the
protocol has been defined in rpcprog.x and that rpcgen has been used to produce the stub and
filter files: rpcprog_clnt.c, rpcprog_svc.c, rpcprog_xdr.c, rpcprog.h.
The client and server program must include (#include "rpcprog.h"
You must then:
compile the client code:
cc -c rpcprog.c
compile the client stub:
cc -c rpcprog_clnt.c
compile the XDR filter:
cc -c rpcprog_xdr.c
build the client executable:
cc -o rpcprog rpcprog.o rpcprog_clnt.o rpcprog_xdr.c
compile the service procedures:
cc -c rpcsvc.c
compile the server stub:
cc -c rpcprog_svc.c
build the server executable:
cc -o rpcsvc rpcsvc.o rpcprog_svc.o rpcprog_xdr.c
Now simply run the programs rpcprog and rpcsvc on the client and server respectively. The
server procedures must be registered before the client can call them.
Overview of Interface Routines
RPC has multiple levels of application interface to its services. These levels provide different
degrees of control balanced with different amounts of interface code to implement. In order of
increasing control and complexity. Below is a summary of the routines available at each level.
Simplified Level Routine Function
rpc_reg() -- Registers a procedure as an RPC program on all transports of the specified
type.
rpc_call() -- Remote calls the specified procedure on the specified remote host.
rpc_broadcast() -- Broadcasts a call message across all transports of the specified type.
Standard Interface Routines The standard interfaces are divided into top level, intermediate level,
expert level, and bottom level. These interfaces give a developer much greater control over
communication parameters such as the transport being used, how long to wait before responding to
errors and re transmitting requests, and so on.
Top Level Routines
At the top level, the interface is still simple, but the program has to create a client handle
before making a call or create a server handle before receiving calls. If you want the application to run
on all transports, use this interface. Use of these routines and code samples can be found in Top Level
Interface
clnt_create() -- Generic client creation. The program tells clnt_create() where the server
is located and the type of transport to use.
clnt_create_timed() Similar to clnt_create() but lets the programmer specify the
maximum time allowed for each type of transport tried during the creation attempt.
svc_create() -- Creates server handles for all transports of the specified type. The program tells
svc_create() which dispatch function to use.
clnt_call() -- Client calls a procedure to send a request to the server.
Intermediate Level Routines
The intermediate level interface of RPC lets you control details. Programs written at these
lower levels are more complicated but run more efficiently. The intermediate level enables you to
specify the transport to use.
clnt_tp_create() -- Creates a client handle for the specified transport.
clnt_tp_create_timed() -- Similar to clnt_tp_create() but lets the programmer
specify the maximum time allowed. svc_tp_create() Creates a server handle for the specified
transport.
clnt_call() -- Client calls a procedure to send a request to the server.
Expert Level Routines
The expert level contains a larger set of routines with which to specify transport-related
parameters. Use of these routines
clnt_tli_create() -- Creates a client handle for the specified transport.
svc_tli_create() -- Creates a server handle for the specified transport.
rpcb_set() -- Calls rpcbind to set a map between an RPC service and a network address.
rpcb_unset() -- Deletes a mapping set by rpcb_set().
rpcb_getaddr() -- Calls rpcbind to get the transport addresses of specified RPC services.
svc_reg() -- Associates the specified program and version number pair with the specified dispatch
routine.
svc_unreg() -- Deletes an association set by svc_reg().
clnt_call() -- Client calls a procedure to send a request to the server.
Bottom Level Routines
The bottom level contains routines used for full control of transport options.
clnt_dg_create() -- Creates an RPC client handle for the specified remote program, using a
connectionless transport.
svc_dg_create() -- Creates an RPC server handle, using a connectionless transport.
clnt_vc_create() -- Creates an RPC client handle for the specified remote program, using a
connection-oriented transport.
svc_vc_create() -- Creates an RPC server handle, using a connection-oriented transport.
clnt_call() -- Client calls a procedure to send a request to the server.
Passing Arbitrary Data Types
Data types passed to and received from remote procedures can be any of a set of predefined
types, or can be programmer-defined types. RPC handles arbitrary data structures, regardless of
different machines' byte orders or structure layout conventions, by always converting them to a
standard transfer format called external data representation (XDR) before sending them over the
transport. The conversion from a machine representation to XDR is called serializing, and the reverse
process is called de serializing. The translator arguments of rpc_call() and rpc_reg() can
specify an XDR primitive procedure, like xdr_u_long(), or a programmer-supplied routine that
processes a complete argument structure. Argument processing routines must take only two
arguments: a pointer to the result and a pointer to the XDR handle.
Multithreaded RPC
Each incoming request is handled by spawning a new thread
Designer must implement appropriate mutual exclusion to guard against “race
conditions” and other concurrency problems
Ideally, server is more active because it can process new requests while waiting
for its own RPC’s to complete on other pending requests
RPC offers substantial benefits for the writer of distributed applications .In summary, these
benefits are as follows:
The user code in both client and server is independent of the underlying transport protocol. In
particular, it makes no assumptions about the form of a transport endpoint address.
The XDR language aids the production of tightly defined and highly structured protocols.
The protocol specification file plays a central role not only in generating the code (via
rpcgen) for the stubs and the wrappers, but also in providing a concise human_ readable
statement of the application _ level protocol.
PRC preserve traditional non distributed program structure much more than sockets or TLI.
The program does not have to be redesigned around the I/O operations between client and
server; it continues to use the same mechanism ( a function call) to access the remote parts of
the program as it uses to access the local parts . The benefits are especially noticeable when
there are multiple service procedures. It is not necessary to invent ‘op_code ‘ to select the
appropriate server action, or to wrap a large switch around the server to dispatch a request to
the correct code, these details are handled automatically by the client stub and server wrapper
code.
The external data representation and the XDR filters, which convert to and from the host-
specific data representation, automatically handles differences in binary representation of
data between computers of different architecture. Whilst this may seem like anon-issue to
programmers who may be lucky enough to work on UNIX networks which are completely
homogeneous, it would be a short-sighted developer indeed who stated categorically that his
or her applications would never have to interoperate with a machine of different architecture.
If byte-order and other differences have to be handled within the application code, the
inconvenience is enormous.
By providing a way to transport credentials and verifiers, RPC offers support for
authentication of clients, and in the case of secure RPC, authentication of the severs as well.
References:
Books
[1]ALESSANDRO RUBINI & JONATHAN CORBET.. “Linux device drivers “ 2nd
edition June
2001.SHROFF-AVBLISHERS & DISTRIBUTORS.PVT.LTD CALCUTTA.
[2] David E. Simon “An Embedded Software Primer” Ninth India Reprint .2003 Published by person
Education (Singapore) Pte.ltd,India Branch,242 F.I.EPatparganj Delhi 110092,India.
[3]Michael Barr “Programming Embedded systems in C and C++” ,May , 2003., SHROFF
PUBLISHERS & Distributors PVT.LTD
[4]. W.RICHARD STEVENS” UNIX NETWORK PROGRAMMING INTERPROCESS
COMMUNICATIONS “Volume 2 Second Edition /2003
[5]. Daniel W .Lewis” Fundamentals of Embedded Software Where C and Assembly meet”
Prentice , Hall of India New Delhi-110001 , 2003
[6]. Andrew S. Tanenbaum Maarten Van Steen. “Distributed Systems Principles and paradigms”
Prentice , Hall of India New Delhi-110001,2002
[7]. OLAF KLRCH & TERRY DAWSON” LINUX NETWORK ADMINISTRATORS GUIDE”
Second Edition .SHROFF PUBLISHERS & DISTRIBUTORS PVT.LTD
[8] “The Linux system Administrator's Guide”, version 0.7 chapter 13.keeping time.
[9],Chris Brown” UNIX distributed programming “,1994
Periodicals:
[10]“Overview of Linux for the Embedded Application Developer”
A white paper by Gregory Haerr, CEO, Century Software, Inc.
[11] Linux man pages.
[12] http://www.sightspeed.com/files/SightSpeed-WhitePaper.pdf
Related web sites
[13] http://www.truetime.net/pdf/imp_netsync.pdf
[14] http://www.boulder.nist.gov/timefreq/service/pdf/computertime.pdf
[15] http://www.rannoch.com/PDF/p_04_innovative.pdf
[16] http://www.net-man.us/datasheets/netman_whitepaper04.PDF
[17] http://www.linuxsa.org.au/tips/time.html
[18] http://www.nurohman.pk.cx/oscillators.html
[19] http://www.bldrdoc.gov/timefreq/stations/wwvb.htm
[20] www.sparxsystems.com.au/use_case_model.html
[21]www. csapp.cs.cm.edu/public/ch13-preview.pdf
[22]] www.webopedia.com/TERM/embedded_system.html
[23] www.en.wikipedia.org/wiki/embedded_operating_system
[24]: http://www.cs.cf.ac.uk/Dave/C/node33.html
[25] http://www.linuxgazette.com/node/view/9005
[26] www.faqs.org/rfcs/rfc1361.htm
[27] www.faqs.org/rfcs/rfc868.htm
[28] www.faqs.org/rfcs/rfc1305.htm
[29] www.linux.org
[30] www.easysw.com/~mike/serial/serial.html
[31] www.linuxdevices.com
Manuals
[32] Satellite Signals navigation set AN/PSN-111 COLLINS AVIONICS &COMMUNICATION
DIVISION
[33] Rockwell Jupiter GPS page manual.
[34] Max 232 level converter .