├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── build ├── ntp_client.dll ├── ntp_client_console.exe └── ntp_client_gui.exe ├── doc └── VIN_NTP_klient.pdf ├── img ├── ntp_client_console.png ├── ntp_client_console2.png ├── ntp_client_gui.png └── ntp_eq.png ├── lib ├── vcredist.png ├── x64 │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── msvcp140_1.dll │ ├── msvcp140_2.dll │ ├── msvcp140_codecvt_ids.dll │ ├── vccorlib140.dll │ ├── vcruntime140.dll │ └── vcruntime140_1.dll └── x86 │ ├── concrt140.dll │ ├── msvcp140.dll │ ├── msvcp140_1.dll │ ├── msvcp140_2.dll │ ├── msvcp140_codecvt_ids.dll │ ├── vccorlib140.dll │ └── vcruntime140.dll └── src ├── ctu_vin_ntp_client.sln ├── ntp_client_console ├── ntp_client_console.cpp └── ntp_client_console.vcxproj ├── ntp_client_dll ├── ntp_client_dll.aps ├── ntp_client_dll.rc ├── ntp_client_dll.vcxproj ├── ntp_client_dll.vcxproj.filters ├── ntp_client_dll.vcxproj.user └── resource.h ├── ntp_client_gui ├── .manifest ├── icon.ico ├── icon.png ├── ntp_client.dll ├── ntp_client.h ├── ntp_client.lib ├── ntp_client_gui.c ├── ntp_client_gui.cws ├── ntp_client_gui.exe ├── ntp_client_gui.h ├── ntp_client_gui.png ├── ntp_client_gui.prj ├── ntp_client_gui.uir ├── ntp_client_gui_ui.c └── ntp_client_gui_ui.h ├── ntp_client_lib ├── ntp_client_lib.vcxproj ├── ntp_client_lib.vcxproj.filters └── ntp_client_lib.vcxproj.user └── ntp_client_shared ├── include └── ntp_client.h ├── ntp_client_shared.vcxitems ├── ntp_client_shared.vcxitems.filters └── src └── ntp_client.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | src/ntp_client_gui/* linguist-vendored=true 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2019 Jakub Parez 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NTP Client (Windows DLL/LIB + Console + CVI GUI) 2 | 3 | 1. [Time Synchronization via NTP](#1-Time-Synchronization-via-NTP) 4 | 2. [NTP Client Library (C++ DLL)](#2-NTP-Client---Library-C++-DLL) 5 | 2.1 [Description](#Description) 6 | 2.2 [C++ interface](#C++-interface) 7 | 2.3 [C interface](#C-interface) 8 | 2.4 [Example of Use](#Example-of-Use) 9 | 3. [NTP client - Graphical Interface (CVI)](#3-NTP-client---Graphical-Interface-CVI) 10 | 11 | ## 1. Time Synchronization via NTP 12 | 13 | NTP has been used to synchronize time in variable response networks since 14 | 1985 and that makes it one of the oldest Internet protocols. Uses UDP 15 | OSI layer 4 protocol and port 123. By default, it achieves an accuracy of 10 ms to 200 16 | µs, depending on the quality of the connection. 17 | 18 | NTP uses a hierarchical system called "*stratum*". Server of type *stratum* 0 19 | obtains the most accurate time, for example, from a cesium clock, but is not intended for 20 | time distribution to the network. This is done by the server of type *stratum* 1, which it receives 21 | time from *loss* 0. Then there are servers *stratum* 2 to 15, which always 22 | they get the time from the parent server and their number basically shows 23 | distance from the reference clock. 24 | 25 | The NTP algorithm begins by sending a defined packet (RFC 5905), respectively 26 | datagram, from client to server. The most important information transmitted by this packet 27 | are client mode (NTPv4), *stratum* local clock, accuracy of local clock, 28 | and especially the time **T1**, which indicates the time of the local clock at the time the packet leaves to 29 | networks. After the NTP server receives the packet, the server writes the time **T2** to it, which 30 | indicates the current time on the server clock and just before sending the time **T3**, which 31 | indicates the time the packet leaves back to the network. After receiving the packet by the client, it is finally 32 | writes the last time **T4**, which indicates the arrival back to the client. if they are 33 | these times are measured accurately, it is enough to calculate the two resulting ones thanks to the formulas below 34 | values. **Offset**, which symbolizes the shift of the client clock from the clock on the server and 35 | **Delay**, which represents the delay of the packet passing through the network, which can be due 36 | switches and network technologies are highly variable. The sum of these values then 37 | represents the final shift of the local clock, which should ideally be 38 | equal to zero. 39 | 40 |
41 | 42 |
43 | 44 | ## 2. NTP Client - Library (C++ DLL) 45 | 46 | ### 2.1 Description 47 | 48 | I developed a simple and single-purpose library in C ++ in the environment 49 | Microsoft Visual Studio 2019. I only relied on the official RFC specification 50 | 5905. The library is currently designed for Windows NT because it uses Win32 51 | API for reading and writing system time and *Winsock* for UDP communication. However 52 | in the future it is not a problem to extend it with directives \ #ifdef eg with POSIX 53 | *sockets*. 54 | 55 | Because the library contains only one **Client** class, the class diagram is 56 | unnecessary. 57 | 58 | ```cpp 59 | class Client: public IClient 60 | ``` 61 | 62 | The library has only two public methods, **query** and 63 | **query_and_sync**. 64 | 65 | ```cpp 66 | virtual Status query (const char* hostname, ResultEx** result_out); 67 | virtual Status query_and_sync (const char* hostname, ResultEx** result_out); 68 | ``` 69 | 70 | Query is the core of the whole library. At the beginning of this method, a UDP is created first 71 | packet, it is filled with the current values ??I mentioned in the first chapter and 72 | sends it to the NTP server. Upon arrival, he completes the time T4 and performs the calculation, according to 73 | formulas from the first chapter. Times are represented by the time_point class from the library 74 | std :: chrono with resolution to nanoseconds (time **t1**) or class 75 | high_resolution_clock (time **t1_b**). 76 | 77 | ```cpp 78 | typedef std::chrono::time_point time_point_t; 79 | time_point_t t1 = std::chrono::time_point_cast(std::chrono::system_clock::now()); 80 | auto t1_b = std::chrono::high_resolution_clock::now(); 81 | ``` 82 | 83 | This combination is because the times in the first formula (offset) must be 84 | absolute. These are the times **T2** and **T3** that came from the server. therefore not 85 | use high_resolution_clock, in the second formula (delay) it is then possible to read **T1** 86 | from **T4** use relative times, which can be obtained using high_resolution_clock. 87 | The following formulas show the calculation using this approach, all units 88 | variables are nanoseconds. 89 | 90 | ```cpp 91 | double offset = [(T2 - T1) + (T3 - T4)] / 2 92 | double delay = (T4b - T1b) - (T3 - T2) 93 | ``` 94 | 95 | By summing the values *offset* and *delay* we get *delta*, ie the value by which 96 | adjust the local system clock. However, this only applies if the latter is used 97 | public methods **query_and_sync**, the first mentioned will only communicate with 98 | server and calculation. 99 | 100 | Resulting calculated and obtained values, including *jitter* (stability indicators 101 | network connection) is returned to the user either in the Result structure that is used for 102 | classic C interface, or in the class ResultEx, which, unlike the first contains 103 | time represented by class time_point_t, as opposed to time represented by classical 104 | TimePt structure with *integers*. 105 | 106 | ```cpp 107 | struct Result 108 | { 109 | struct TimePt time; 110 | struct Metrics mtr; 111 | }; 112 | ``` 113 | ```cpp 114 | class ResultEx 115 | { 116 | public: 117 | time_point_t time; 118 | Metrics mtr; 119 | }; 120 | ``` 121 | 122 | This achieves the compatibility between C and C ++, which is required for a dynamic library. 123 | If the user uses the library directly from C ++, it is more convenient to work with time 124 | represented by the time_point_t class, otherwise there is no choice but to use it 125 | structure. 126 | 127 | ```cpp 128 | struct TimePt 129 | { 130 | int tm_nsec; 131 | int tm_usec; 132 | int tm_msec; 133 | int tm_sec; 134 | int tm_min; 135 | int tm_hour 136 | int tm_mday; 137 | int tm_mon; 138 | int tm_year; 139 | }; 140 | ``` 141 | ```cpp 142 | struct Metrics 143 | { 144 | double delay_ns; 145 | double offset_ns; 146 | double jitter_ns; 147 | double delta_ns; 148 | }; 149 | ``` 150 | 151 | Error states are returned as *enumerator* Status, where 0 means success 152 | (similar to POSIX) and anything else is a bug. 153 | 154 | ```cpp 155 | enum Status : int16_t 156 | { 157 | OK = 0, 158 | UNKNOWN_ERR = 1, 159 | INIT_WINSOCK_ERR = 2, 160 | CREATE_SOCKET_ERR = 3, 161 | SEND_MSG_ERR = 4, 162 | RECEIVE_MSG_ERR = 5, 163 | RECEIVE_MSG_TIMEOUT = 6, 164 | SET_WIN_TIME_ERR = 7, 165 | ADMIN_RIGHTS_NEEDED = 8 166 | }; 167 | ``` 168 | 169 | In addition, the library contains several static stateless methods to facilitate the work 170 | programmer, used primarily to format results and convert types. 171 | 172 | ### 2.2 C++ interface 173 | 174 | The standard library interface for use with object-oriented languages is in 175 | form *interface*, which exposes the two main public methods described above 176 | **query** a **query_and_sync**. The interface is only a macro for the struct type, 177 | of course you could use a proprietary MS **__interface**, but most of the time it gets better 178 | stick to proven and compatible things. 179 | 180 | ```cpp 181 | Interface IClient 182 | { 183 | virtual Status query(const char* hostname, ResultEx** result_out) = 0; 184 | virtual Status query_and_sync(const char* hostname, ResultEx**result_out) = 0; 185 | virtual ~IClient() {}; 186 | }; 187 | ``` 188 | 189 | ### 2.3 C interface 190 | 191 | The interface usable for DLL calls must be compatible with classic ANSI C, 192 | instead of classes, it is necessary to use the classic C OOP style, namely functions, structures and 193 | *opaque pointers*. These functions must then be exported using the EXPORT macro, 194 | which is a macro for **__declspec (dllexport)**. It is also necessary to set adequate 195 | calling convention, in our case it is **__cdecl**, where the one calling as well 196 | cleans the tray. 197 | 198 | The **Client__create** function creates a library instance, which is represented 199 | pointer, or macro, HNTP, which in the context of Windows is called 200 | *handle*. 201 | 202 | ```cpp 203 | typedef void* HNTP; 204 | ``` 205 | 206 | Other functions, such as **Client__query** or **Client__query_and_sync** 207 | they take this indicator as the first argument. The rest is very similar to C++ 208 | interface, however one difference it has. Instead of delete, it must be called at the end 209 | **Client__free_result** and **Client__close**. 210 | 211 | ```cpp 212 | extern "C" 213 | { 214 | /* object lifecycle */ 215 | EXPORT HNTP __cdecl Client__create(void); 216 | EXPORT void __cdecl Client__close(HNTP self); 217 | 218 | /* main NTP server query functions */ 219 | EXPORT enum Status __cdecl Client__query(HNTP self, const char* hostname, struct Result** result_out); 220 | EXPORT enum Status __cdecl Client__query_and_sync(HNTP self, const char* hostname, struct Result** result_out); 221 | 222 | /* helper functions */ 223 | EXPORT void __cdecl Client__format_info_str(struct Result* result, char* str_out); 224 | EXPORT void __cdecl Client__get_status_str(enum Status status, char* str_out); 225 | EXPORT void __cdecl Client__free_result(struct Result* result); 226 | } 227 | ``` 228 | 229 | ### 2.4 Example of Use 230 | 231 | You must have *runtime* **vc_redist** (2015-19) installed to run. Code 232 | it is at least partially annotated and perhaps even clear. I tried to make it 233 | use trivial. A client instance is created, the *query* function is called, and it terminates 234 | the client. This can be done in an infinite loop with a defined interval, 235 | to ensure constant time synchronization. The following lines are excluded 236 | from a console application that serves as an example of use. 237 | 238 | ```cpp 239 | enum Status s; 240 | struct Result* result = nullptr; 241 | HNTP client = Client__create() 242 | s = Client__query_and_sync(client, "195.113.144.201", &result); 243 | Client__free_result(result); 244 | Client__close(client); 245 | ``` 246 | 247 | ![Console](https://raw.githubusercontent.com/parezj/NTP-Client/master/img/ntp_client_console2.png) 248 | 249 | ## 3. NTP client - Graphical Interface (CVI) 250 | 251 | I used the dynamic library in the LabWindows / CVI environment to create 252 | graphical interface of the NTP client, which is periodically called from its own thread. On 253 | graph we then see the green delta value (the current difference of the local clock from 254 | server), its diameter in yellow and *jitter* in network communication in red. To run 255 | **CVI Runtime 2019** is required. 256 | 257 | ![CVI GUI](https://raw.githubusercontent.com/parezj/NTP-Client/master/img/ntp_client_gui.png) 258 | -------------------------------------------------------------------------------- /build/ntp_client.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/build/ntp_client.dll -------------------------------------------------------------------------------- /build/ntp_client_console.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/build/ntp_client_console.exe -------------------------------------------------------------------------------- /build/ntp_client_gui.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/build/ntp_client_gui.exe -------------------------------------------------------------------------------- /doc/VIN_NTP_klient.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/doc/VIN_NTP_klient.pdf -------------------------------------------------------------------------------- /img/ntp_client_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/img/ntp_client_console.png -------------------------------------------------------------------------------- /img/ntp_client_console2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/img/ntp_client_console2.png -------------------------------------------------------------------------------- /img/ntp_client_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/img/ntp_client_gui.png -------------------------------------------------------------------------------- /img/ntp_eq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/img/ntp_eq.png -------------------------------------------------------------------------------- /lib/vcredist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/vcredist.png -------------------------------------------------------------------------------- /lib/x64/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/concrt140.dll -------------------------------------------------------------------------------- /lib/x64/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/msvcp140.dll -------------------------------------------------------------------------------- /lib/x64/msvcp140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/msvcp140_1.dll -------------------------------------------------------------------------------- /lib/x64/msvcp140_2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/msvcp140_2.dll -------------------------------------------------------------------------------- /lib/x64/msvcp140_codecvt_ids.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/msvcp140_codecvt_ids.dll -------------------------------------------------------------------------------- /lib/x64/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/vccorlib140.dll -------------------------------------------------------------------------------- /lib/x64/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/vcruntime140.dll -------------------------------------------------------------------------------- /lib/x64/vcruntime140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x64/vcruntime140_1.dll -------------------------------------------------------------------------------- /lib/x86/concrt140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/concrt140.dll -------------------------------------------------------------------------------- /lib/x86/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/msvcp140.dll -------------------------------------------------------------------------------- /lib/x86/msvcp140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/msvcp140_1.dll -------------------------------------------------------------------------------- /lib/x86/msvcp140_2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/msvcp140_2.dll -------------------------------------------------------------------------------- /lib/x86/msvcp140_codecvt_ids.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/msvcp140_codecvt_ids.dll -------------------------------------------------------------------------------- /lib/x86/vccorlib140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/vccorlib140.dll -------------------------------------------------------------------------------- /lib/x86/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/lib/x86/vcruntime140.dll -------------------------------------------------------------------------------- /src/ctu_vin_ntp_client.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29926.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntp_client_dll", "ntp_client_dll\ntp_client_dll.vcxproj", "{D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntp_client_lib", "ntp_client_lib\ntp_client_lib.vcxproj", "{6E21FA4A-474A-46D1-9C88-D4F70041F4F8}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntp_client_shared", "ntp_client_shared\ntp_client_shared.vcxitems", "{CE1844D1-F6F4-40D9-85B6-530A3857450C}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ntp_client_test", "ntp_client_console\ntp_client_console.vcxproj", "{F8635A97-994B-4240-8495-DFA5A15DF321}" 13 | EndProject 14 | Global 15 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 16 | ntp_client_shared\ntp_client_shared.vcxitems*{6e21fa4a-474a-46d1-9c88-d4f70041f4f8}*SharedItemsImports = 4 17 | ntp_client_shared\ntp_client_shared.vcxitems*{ce1844d1-f6f4-40d9-85b6-530a3857450c}*SharedItemsImports = 9 18 | ntp_client_shared\ntp_client_shared.vcxitems*{d76f068d-a4a1-4bb0-941f-b5c9fbaff372}*SharedItemsImports = 4 19 | EndGlobalSection 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|x64 = Debug|x64 22 | Debug|x86 = Debug|x86 23 | Release|x64 = Release|x64 24 | Release|x86 = Release|x86 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Debug|x64.ActiveCfg = Debug|x64 28 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Debug|x64.Build.0 = Debug|x64 29 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Debug|x86.ActiveCfg = Debug|Win32 30 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Debug|x86.Build.0 = Debug|Win32 31 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Release|x64.ActiveCfg = Release|x64 32 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Release|x64.Build.0 = Release|x64 33 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Release|x86.ActiveCfg = Release|Win32 34 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372}.Release|x86.Build.0 = Release|Win32 35 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Debug|x64.ActiveCfg = Debug|x64 36 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Debug|x64.Build.0 = Debug|x64 37 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Debug|x86.ActiveCfg = Debug|Win32 38 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Debug|x86.Build.0 = Debug|Win32 39 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Release|x64.ActiveCfg = Release|x64 40 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Release|x64.Build.0 = Release|x64 41 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Release|x86.ActiveCfg = Release|Win32 42 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8}.Release|x86.Build.0 = Release|Win32 43 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Debug|x64.ActiveCfg = Debug|x64 44 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Debug|x64.Build.0 = Debug|x64 45 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Debug|x86.ActiveCfg = Debug|Win32 46 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Debug|x86.Build.0 = Debug|Win32 47 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Release|x64.ActiveCfg = Release|x64 48 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Release|x64.Build.0 = Release|x64 49 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Release|x86.ActiveCfg = Release|Win32 50 | {F8635A97-994B-4240-8495-DFA5A15DF321}.Release|x86.Build.0 = Release|Win32 51 | EndGlobalSection 52 | GlobalSection(SolutionProperties) = preSolution 53 | HideSolutionNode = FALSE 54 | EndGlobalSection 55 | GlobalSection(ExtensibilityGlobals) = postSolution 56 | SolutionGuid = {339BC5EC-6D32-463A-B783-8639EFA3518A} 57 | EndGlobalSection 58 | EndGlobal 59 | -------------------------------------------------------------------------------- /src/ntp_client_console/ntp_client_console.cpp: -------------------------------------------------------------------------------- 1 | /************************************** 2 | * Author: Jakub Parez 3 | * File: ntp_client_console.cpp 4 | * Project: NTP client 5 | * Company: CTU/VIN 6 | * Date: 2020/4/29 11:25 7 | * License: MIT 8 | ***************************************/ 9 | 10 | #include 11 | #include "ntp_client.h" 12 | 13 | #pragma warning(disable:4996) // disable CRT secure warnings 14 | 15 | #define IP "195.113.144.201" // NTP server ip 16 | #define INTERVAL 1000 // interval of NTP server query 17 | 18 | using namespace CTU::VIN::NTP_client; 19 | 20 | BOOL WINAPI ConsoleHandler(DWORD dwCtrlType); // console ctrl handler prototype 21 | 22 | HNTP client; // NTP client object opaque pointer 23 | 24 | int main(int argc, char** argv) // C style example 25 | { 26 | enum Status s; // status enum as a result from query 27 | struct Result* result = nullptr; // result struct with all data 28 | char status_str[100]; // status string from enum container 29 | char result_str[400]; // result print info char container 30 | char ip[20]; // IP char container 31 | 32 | if (argc > 1) // if there exists argument, 33 | strncpy(ip, argv[1], 20); // copy it into IP array 34 | else 35 | strcpy(ip, IP); // otherwise use predefined IP value 36 | 37 | SetConsoleCtrlHandler(ConsoleHandler, true); // assign console window onclose event 38 | client = Client__create(); // finally create NTP client 39 | 40 | while (true) 41 | { 42 | try 43 | { 44 | s = Client__query_and_sync(client, ip, &result); // main NTP server query 45 | 46 | Client__get_status_str(s, status_str); // convert status enum to str 47 | printf("\nStatus: %s\n", status_str); // print status string 48 | 49 | if (s == Status::OK) { // if status ok, print info 50 | Client__format_info_str(result, result_str); // format info into string 51 | Client__free_result(result); // delete dynamic object 52 | printf("%s", result_str); // print all important info 53 | } 54 | else { // if status not ok, quit 55 | Client__free_result(result); // delete dynamic object 56 | break; 57 | } 58 | Sleep(INTERVAL); // sleep for specified time 59 | } 60 | catch (const std::exception& exc) // catch any exception 61 | { 62 | printf("%s", exc.what()); // print exception details 63 | break; // quit 64 | } 65 | } 66 | getchar(); // finally wait for user input 67 | } 68 | 69 | BOOL WINAPI ConsoleHandler(DWORD dwCtrlType) // console ctrl event handler 70 | { 71 | if (CTRL_CLOSE_EVENT == dwCtrlType) // close window event fired 72 | { 73 | if (client != NULL) // if client exists, 74 | { 75 | Client__close(client); // close / clean-up 76 | } 77 | } 78 | return TRUE; 79 | } -------------------------------------------------------------------------------- /src/ntp_client_console/ntp_client_console.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {F8635A97-994B-4240-8495-DFA5A15DF321} 24 | Win32Proj 25 | ntpclienttest 26 | 10.0 27 | ntp_client_console 28 | 29 | 30 | 31 | Application 32 | true 33 | v142 34 | Unicode 35 | 36 | 37 | Application 38 | false 39 | v142 40 | true 41 | MultiByte 42 | 43 | 44 | Application 45 | true 46 | v142 47 | Unicode 48 | 49 | 50 | Application 51 | false 52 | v142 53 | true 54 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | 77 | 78 | true 79 | 80 | 81 | false 82 | $(IncludePath) 83 | $(SolutionDir)$(Configuration)\console\ 84 | $(Configuration)\console\ 85 | 86 | 87 | false 88 | 89 | 90 | 91 | 92 | 93 | Level3 94 | true 95 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 96 | true 97 | ..\ntp_client_shared\include 98 | 99 | 100 | Console 101 | true 102 | 103 | 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 111 | true 112 | 113 | 114 | Console 115 | true 116 | 117 | 118 | 119 | 120 | 121 | 122 | Level3 123 | true 124 | true 125 | true 126 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | ..\ntp_client_shared\include 129 | 130 | 131 | 132 | Console 133 | true 134 | true 135 | true 136 | 137 | 138 | 139 | 140 | 141 | 142 | Level3 143 | true 144 | true 145 | true 146 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 147 | true 148 | 149 | 150 | Console 151 | true 152 | true 153 | true 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | {6e21fa4a-474a-46d1-9c88-d4f70041f4f8} 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /src/ntp_client_dll/ntp_client_dll.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_dll/ntp_client_dll.aps -------------------------------------------------------------------------------- /src/ntp_client_dll/ntp_client_dll.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // Czech (Czech Republic) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) 19 | LANGUAGE LANG_CZECH, SUBLANG_DEFAULT 20 | #pragma code_page(1250) 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Version 51 | // 52 | 53 | VS_VERSION_INFO VERSIONINFO 54 | FILEVERSION 0,0,0,1 55 | PRODUCTVERSION 0,0,0,1 56 | FILEFLAGSMASK 0x3fL 57 | #ifdef _DEBUG 58 | FILEFLAGS 0x1L 59 | #else 60 | FILEFLAGS 0x0L 61 | #endif 62 | FILEOS 0x40004L 63 | FILETYPE 0x2L 64 | FILESUBTYPE 0x0L 65 | BEGIN 66 | BLOCK "StringFileInfo" 67 | BEGIN 68 | BLOCK "040504b0" 69 | BEGIN 70 | VALUE "CompanyName", "CTU/VIN" 71 | VALUE "FileDescription", "NTP client" 72 | VALUE "FileVersion", "0.0.0.1" 73 | VALUE "InternalName", "ntp_client.dll" 74 | VALUE "LegalCopyright", "Jakub Parez (C) 2020" 75 | VALUE "OriginalFilename", "ntp_client.dll" 76 | VALUE "ProductName", "NTP client" 77 | VALUE "ProductVersion", "0.0.0.1" 78 | END 79 | END 80 | BLOCK "VarFileInfo" 81 | BEGIN 82 | VALUE "Translation", 0x405, 1200 83 | END 84 | END 85 | 86 | #endif // Czech (Czech Republic) resources 87 | ///////////////////////////////////////////////////////////////////////////// 88 | 89 | 90 | 91 | #ifndef APSTUDIO_INVOKED 92 | ///////////////////////////////////////////////////////////////////////////// 93 | // 94 | // Generated from the TEXTINCLUDE 3 resource. 95 | // 96 | 97 | 98 | ///////////////////////////////////////////////////////////////////////////// 99 | #endif // not APSTUDIO_INVOKED 100 | 101 | -------------------------------------------------------------------------------- /src/ntp_client_dll/ntp_client_dll.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 16.0 29 | {D76F068D-A4A1-4BB0-941F-B5C9FBAFF372} 30 | Win32Proj 31 | ntpclient 32 | 10.0 33 | ntp_client_dll 34 | 35 | 36 | 37 | DynamicLibrary 38 | true 39 | v142 40 | MultiByte 41 | 42 | 43 | DynamicLibrary 44 | false 45 | v142 46 | true 47 | Unicode 48 | 49 | 50 | DynamicLibrary 51 | true 52 | v142 53 | Unicode 54 | 55 | 56 | DynamicLibrary 57 | false 58 | v142 59 | true 60 | Unicode 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | true 83 | ntp_client 84 | 85 | 86 | true 87 | 88 | 89 | false 90 | ntp_client 91 | $(SolutionDir)$(Configuration)\dll\ 92 | $(Configuration)\dll\ 93 | 94 | 95 | false 96 | 97 | 98 | 99 | 100 | 101 | Level4 102 | true 103 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;NTPCLIENT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 104 | true 105 | pch.h 106 | ..\ntp_client_shared\include;%(AdditionalIncludeDirectories) 107 | 108 | 109 | Windows 110 | true 111 | false 112 | Ws2_32.lib;%(AdditionalDependencies) 113 | true 114 | 115 | 116 | 117 | 118 | Use 119 | Level3 120 | true 121 | _DEBUG;NTPCLIENT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 122 | true 123 | pch.h 124 | 125 | 126 | Windows 127 | true 128 | false 129 | 130 | 131 | 132 | 133 | NotUsing 134 | Level3 135 | true 136 | true 137 | false 138 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;NTPCLIENT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 139 | false 140 | 141 | 142 | ..\ntp_client_shared\include;%(AdditionalIncludeDirectories) 143 | 144 | 145 | Windows 146 | true 147 | true 148 | true 149 | false 150 | Ws2_32.lib;%(AdditionalDependencies) 151 | 152 | 153 | 154 | 155 | Use 156 | Level3 157 | true 158 | true 159 | true 160 | NDEBUG;NTPCLIENT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 161 | true 162 | pch.h 163 | 164 | 165 | Windows 166 | true 167 | true 168 | true 169 | false 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /src/ntp_client_dll/ntp_client_dll.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Resource Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/ntp_client_dll/ntp_client_dll.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/ntp_client_dll/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by ntp_client_dll.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/ntp_client_gui/.manifest: -------------------------------------------------------------------------------- 1 | 2 | 6 | Description of your application 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/ntp_client_gui/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/icon.ico -------------------------------------------------------------------------------- /src/ntp_client_gui/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/icon.png -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/ntp_client.dll -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client.h: -------------------------------------------------------------------------------- 1 | /************************************** 2 | * Author: Jakub Parez 3 | * File: ntp_client.h 4 | * Project: NTP client 5 | * Company: CTU/VIN 6 | * Date: 2020/4/19 10:30 7 | * License: MIT 8 | ***************************************/ 9 | 10 | #ifndef ntp_client_h 11 | #define ntp_client_h 12 | 13 | #define EXPORT __declspec(dllexport) 14 | #define IMPORT __declspec(dllimport) 15 | 16 | #ifdef __cplusplus 17 | #include 18 | #include 19 | #endif 20 | 21 | #define Interface struct 22 | 23 | #define NTP_PACKET_LEN 48 24 | #define UDP_PORT 123 25 | #define RX_TIMEOUT 5000 26 | #define JITTER_WINDOW 100 27 | 28 | #define STR_MAX_SIZE 100 29 | #define NTP_TS_DELTA 2208988800ull 30 | 31 | 32 | //[module(name = "ntp_client")]; 33 | 34 | /* 35 | Below is a description of the NTP / SNTP Version 4 message format, 36 | which follows the IPand UDP headers.This format is identical to 37 | that described in RFC - 1305, with the exception of the contents of the 38 | reference identifier field.The header fields are defined as follows : 39 | 40 | 1 2 3 41 | 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 1 42 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 43 | | LI | VN | Mode | Stratum | Poll | Precision | 44 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 45 | | Root Delay | 46 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 47 | | Root Dispersion | 48 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 49 | | Reference Identifier | 50 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 51 | | | 52 | | Reference Timestamp(64) | 53 | | | 54 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 55 | | | 56 | | Originate Timestamp(64) | 57 | | | 58 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 59 | | | 60 | | Receive Timestamp(64) | 61 | | | 62 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 | | | 64 | | Transmit Timestamp(64) | 65 | | | 66 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67 | | Key Identifier(optional) (32) | 68 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69 | | | 70 | | | 71 | | Message Digest(optional) (128) | 72 | | | 73 | | | 74 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 75 | 76 | Reference Timestamp : This is the time at which the local clock was 77 | last set or corrected, in 64 - bit timestamp format. 78 | 79 | Originate Timestamp : This is the time at which the request departed 80 | the client for the server, in 64 - bit timestamp format. 81 | 82 | Receive Timestamp : This is the time at which the request arrived at 83 | the server, in 64 - bit timestamp format. 84 | 85 | Transmit Timestamp : This is the time at which the reply departed the 86 | server for the client, in 64 - bit timestamp format. 87 | 88 | 89 | * NTP uses two fixed point formats. The first (l_fp) is the "long" 90 | * format and is 64 bits long with the decimal between bits 31 and 32. 91 | * This is used for time stamps in the NTP packet header (in network 92 | * byte order) and for internal computations of offsets (in local host 93 | * byte order). We use the same structure for both signed and unsigned 94 | * values, which is a big hack but saves rewriting all the operators 95 | * twice. Just to confuse this, we also sometimes just carry the 96 | * fractional part in calculations, in both signed and unsigned forms. 97 | * Anyway, an l_fp looks like: 98 | * 99 | * 0 1 2 3 100 | * 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 1 101 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 102 | * | Integral Part | 103 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 104 | * | Fractional Part | 105 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 106 | * REF http://www.eecis.udel.edu/~mills/database/rfc/rfc2030.txt 107 | 108 | offset = [(T2 - T1) + (T3 - T4)] / 2 109 | delay = (T4 - T1) - (T3 - T2) 110 | 111 | */ 112 | 113 | #ifdef __cplusplus 114 | namespace CTU { namespace VIN { namespace NTP_client 115 | { 116 | #endif 117 | struct TimePt 118 | { 119 | int tm_nsec; /* nano seconds, range 0 to 999 */ 120 | int tm_usec; /* micro seconds, range 0 to 999 */ 121 | int tm_msec; /* mili seconds, range 0 to 999 */ 122 | int tm_sec; /* seconds, range 0 to 59 */ 123 | int tm_min; /* minutes, range 0 to 59 */ 124 | int tm_hour; /* hours, range 0 to 23 */ 125 | int tm_mday; /* day of the month, range 1 to 31 */ 126 | int tm_mon; /* month, range 0 to 11 */ 127 | int tm_year; /* The number of years since 1900 */ 128 | }; 129 | 130 | struct Metrics 131 | { 132 | double delay_ns; /* delay from transporting packet through network */ 133 | double offset_ns; /* offset from the server time */ 134 | double jitter_ns; /* network jitter accumulated in time when calling sync */ 135 | double delta_ns; /* actual difference between server and client time */ 136 | }; 137 | 138 | struct Result 139 | { 140 | struct TimePt time; /* plain C style struct time point with actual time*/ 141 | struct Metrics mtr; /* metrics values with other relevant data */ 142 | }; 143 | 144 | #ifdef __cplusplus 145 | typedef std::chrono::time_point time_point_t; 146 | 147 | class ResultEx 148 | { 149 | public: 150 | time_point_t time; /* time point class with actual time */ 151 | Metrics mtr; /* metrics values with other relevant data */ 152 | }; 153 | #endif 154 | 155 | enum Status : int16_t 156 | { 157 | OK = 0, 158 | UNKNOWN_ERR = 1, 159 | INIT_WINSOCK_ERR = 2, 160 | CREATE_SOCKET_ERR = 3, 161 | SEND_MSG_ERR = 4, 162 | RECEIVE_MSG_ERR = 5, 163 | RECEIVE_MSG_TIMEOUT = 6, 164 | SET_WIN_TIME_ERR = 7, 165 | ADMIN_RIGHTS_NEEDED = 8 166 | }; 167 | 168 | typedef void* HNTP; 169 | 170 | #ifdef __cplusplus 171 | extern "C" { 172 | #endif 173 | /* object lifecycle */ 174 | EXPORT HNTP __cdecl Client__create(void); 175 | EXPORT void __cdecl Client__close(HNTP self); 176 | 177 | /* main NTP server query functions */ 178 | EXPORT enum Status __cdecl Client__query(HNTP self, const char* hostname, struct Result** result_out); 179 | EXPORT enum Status __cdecl Client__query_and_sync(HNTP self, const char* hostname, struct Result** result_out); 180 | 181 | /* helper functions */ 182 | EXPORT void __cdecl Client__format_info_str(struct Result* result, char* str_out); 183 | EXPORT void __cdecl Client__get_status_str(enum Status status, char* str_out); 184 | EXPORT void __cdecl Client__free_result(struct Result* result); 185 | #ifdef __cplusplus 186 | } 187 | 188 | Interface IClient 189 | { 190 | virtual Status query(const char* hostname, ResultEx** result_out) = 0; 191 | virtual Status query_and_sync(const char* hostname, ResultEx** result_out) = 0; 192 | virtual ~IClient() {}; 193 | }; 194 | 195 | class Packet // Total: 384 bits or 48 bytes. 196 | { 197 | public: 198 | uint8_t li_vn_mode; // 8 bits. li, vn, and mode. 199 | // -li 2 bits. Leap indicator. 200 | // -vn 3 bits. Version number of the protocol. 3,4 201 | // -mode 3 bits. Client will pick mode 3 for client. 202 | 203 | uint8_t stratum; // 8 bits. Stratum level of the local clock. 204 | uint8_t poll; // 8 bits. Maximum interval between successive messages. 205 | uint8_t precision; // 8 bits. Precision of the local clock. 206 | uint32_t rootDelay; // 32 bits. Total round trip delay time. 207 | uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source. 208 | 209 | uint32_t refId; // 32 bits. Reference clock identifier. 210 | uint32_t refTm_s; // 32 bits. Reference time-stamp seconds. 211 | uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second. 212 | 213 | uint32_t origTm_s; // 32 bits. Originate time-stamp seconds. = t1 214 | uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second. 215 | 216 | uint32_t rxTm_s; // 32 bits. Received time-stamp seconds. = t2 217 | uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second. 218 | 219 | uint32_t txTm_s; // 32 bits. Transmit time-stamp seconds. = t3 220 | uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second. 221 | }; 222 | 223 | class Client : public IClient 224 | { 225 | protected: 226 | 227 | public: 228 | Client(); 229 | virtual ~Client(); 230 | 231 | virtual Status query(const char* hostname, ResultEx** result_out); 232 | virtual Status query_and_sync(const char* hostname, ResultEx** result_out); 233 | 234 | static void format_info_str(Result* result, char* str); 235 | static void format_info_str(ResultEx* result, char* str); 236 | static void get_status_str(Status status, char* str); 237 | static void time_pt_class_to_struct(time_point_t tp, TimePt& time_pt); 238 | static void extract_time_point(time_point_t tp, int& y, int& m, int& d, int& hr, 239 | int& min, int& sec, int& ms, int& us, int& ns) noexcept; 240 | 241 | private: 242 | WSADATA wsa; 243 | struct sockaddr_in si_addr; 244 | int s, slen; 245 | char ans[NTP_PACKET_LEN]; 246 | char msg[NTP_PACKET_LEN]; 247 | char host[STR_MAX_SIZE]; 248 | Packet* packet; 249 | 250 | enum Status init(const char* hostname); 251 | enum Status query(); 252 | enum Status set_win_clock(time_point_t tm); 253 | 254 | double offset_ns = 0; 255 | double delay_ns = 0; 256 | time_point_t time; 257 | double jitter_ns = 0; 258 | double delay_sum_ns = 0; 259 | double prev_delay = 0; 260 | 261 | double delay_ringbuff [JITTER_WINDOW]; 262 | int ringbuff_front = 0; 263 | int ringbuff_count = 0; 264 | }; 265 | 266 | const char status_s[9][50] = { "OK", "Unknown Error", "Init Winsock Error", "Create Socket Error", "Send Message Error", 267 | "Receive Message Error", "Receive Message Timeout", "Set Windows Time Error", "Admin Rights Needed" }; 268 | }}} 269 | #endif 270 | #endif -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/ntp_client.lib -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.c: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // 3 | // Title: ntp_client_gui 4 | // Purpose: A short description of the application. 5 | // 6 | // Created on: 5.5.2020 at 11:31:15 by Jakub Parez. 7 | // Copyright: CTU/VIN 8 | // 9 | //============================================================================== 10 | 11 | //============================================================================== 12 | // Include files 13 | 14 | #include 15 | #include "windows.h" 16 | #include 17 | #include 18 | #include "toolbox.h" 19 | #include "asynctmr.h" 20 | #include "ntp_client_gui_ui.h" 21 | #include "ntp_client_gui.h" 22 | #include "ntp_client.h" 23 | #undef GetSystemTime 24 | 25 | //============================================================================== 26 | // Constants 27 | #define TIMER_THREAD_SLEEP 100 28 | #define PTS 200 29 | 30 | //============================================================================== 31 | // Prototypes 32 | int CVICALLBACK MainThread (void *functionData); 33 | int CVICALLBACK TimerThread (void *functionData); 34 | 35 | 36 | //============================================================================== 37 | // Static global variables 38 | 39 | static int panelHandle = 0; /* main panel handle */ 40 | static int enabled = 0; /* enable state */ 41 | 42 | static HNTP client; /* NTP client object */ 43 | 44 | static enum Status s; /* result status enum */ 45 | static struct Result* result; /* result struct with all data */ 46 | static char status_str[100]; /* status string from enum container */ 47 | static char ip[20]; /* NTP server IP */ 48 | static int interval = 100; /* interval between querries */ 49 | 50 | static int quit = 0; /* thread exit flag */ 51 | static int threadId; /* main thread id */ 52 | static int threadId2; /* timer thread id */ 53 | 54 | static double data_all[PTS] = {0}; /* data buffer for averaging */ 55 | static double data_delta[PTS] = {0}; /* data buffer for averaging */ 56 | static int data_idx = 0; /* buffer current index */ 57 | static int data_cnt = 0; /* buffer total count */ 58 | 59 | //============================================================================== 60 | // Static functions 61 | int round_up_to_max_pow(int numToRound, int multiple) 62 | { 63 | if (multiple == 0) 64 | return numToRound; 65 | 66 | int remainder = numToRound % multiple; 67 | if (remainder == 0) 68 | return numToRound; 69 | 70 | return numToRound + multiple - remainder; 71 | } 72 | //============================================================================== 73 | // Global variables 74 | 75 | //============================================================================== 76 | // Global functions 77 | 78 | /// HIFN The main entry-point function. 79 | int main (int argc, char *argv[]) 80 | { 81 | int error = 0; 82 | 83 | /* initialize and load resources */ 84 | nullChk (InitCVIRTE (0, argv, 0)); 85 | //errChk (panelHandle = LoadPanel (0, "ntp_client_gui.uir", PANEL)); 86 | errChk (panelHandle = MainPANEL(0)); 87 | 88 | /* create NTP client */ 89 | client = Client__create(); 90 | 91 | /* display the panel */ 92 | errChk (DisplayPanel (panelHandle)); 93 | 94 | /* set trace legend names */ 95 | SetTraceAttributeEx (panelHandle, PANEL_STRIPCHART, 1, ATTR_TRACE_LG_TEXT, "Delta [ms]"); 96 | SetTraceAttributeEx (panelHandle, PANEL_STRIPCHART, 2, ATTR_TRACE_LG_TEXT, "Delta avg"); 97 | SetTraceAttributeEx (panelHandle, PANEL_STRIPCHART, 3, ATTR_TRACE_LG_TEXT, "Jitter [ms]"); 98 | 99 | /* set axis x offset */ 100 | double currTime = 0; 101 | GetCurrentDateTime(&currTime); 102 | SetCtrlAttribute(panelHandle, PANEL_STRIPCHART, ATTR_XAXIS_OFFSET, currTime); 103 | 104 | /* run MainThread */ 105 | CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, MainThread, NULL, &threadId); 106 | 107 | /* run TimerThread */ 108 | CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, TimerThread, NULL, &threadId2); 109 | 110 | /* run the user interface */ 111 | errChk (RunUserInterface ()); 112 | 113 | Error: 114 | /* clean up */ 115 | if (panelHandle > 0) 116 | DiscardPanel (panelHandle); 117 | return 0; 118 | } 119 | 120 | //============================================================================== 121 | // UI callback function prototypes 122 | 123 | /// HIFN Exit when the user dismisses the panel. 124 | int CVICALLBACK panelCB (int panel, int event, void *callbackData, 125 | int eventData1, int eventData2) 126 | { 127 | if (event == EVENT_CLOSE) 128 | { 129 | /* set flags */ 130 | enabled = 0; 131 | quit = 1; 132 | 133 | /* close NTP client */ 134 | Client__close(client); 135 | 136 | /* wait for main thread quits */ 137 | CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, threadId, 0); 138 | CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, threadId2, 0); 139 | 140 | /* quit this program */ 141 | QuitUserInterface (0); 142 | } 143 | 144 | return 0; 145 | } 146 | 147 | int CVICALLBACK callEnable (int panel, int control, int event, 148 | void *callbackData, int eventData1, int eventData2) 149 | { 150 | if (event != EVENT_COMMIT) 151 | return 0; 152 | 153 | /* toggle flag */ 154 | int _enabled = !enabled; 155 | 156 | /* toggle dimmed state */ 157 | SetCtrlAttribute(panelHandle, PANEL_CTRL_IP, ATTR_DIMMED, _enabled); 158 | SetCtrlAttribute(panelHandle, PANEL_CTRL_INTERVAL, ATTR_DIMMED, _enabled); 159 | 160 | if (_enabled) 161 | { 162 | /* set control properties */ 163 | SetCtrlVal(panelHandle, PANEL_CTRL_STATUS, "Init"); 164 | SetCtrlAttribute(panelHandle, PANEL_CTRL_STATUS, ATTR_TEXT_COLOR, 0xFFA500L); 165 | GetCtrlVal(panelHandle, PANEL_CTRL_IP, ip); 166 | GetCtrlVal(panelHandle, PANEL_CTRL_INTERVAL, &interval); 167 | 168 | /* adjust stripchart time values to match current time offset and update interval */ 169 | double currTime = 0; 170 | GetCurrentDateTime(&currTime); 171 | SetCtrlAttribute(panelHandle, PANEL_STRIPCHART, ATTR_XAXIS_OFFSET, currTime); 172 | SetCtrlAttribute(panelHandle, PANEL_STRIPCHART, ATTR_XAXIS_GAIN, interval / 1000.0); 173 | ClearStripChart(panelHandle, PANEL_STRIPCHART); 174 | 175 | /* clear max buffer */ 176 | data_idx = 0; 177 | data_cnt = 0; 178 | } 179 | else 180 | { 181 | /* set control propeties */ 182 | SetCtrlVal(panelHandle, PANEL_CTRL_STATUS, "Disabled"); 183 | SetCtrlAttribute(panelHandle, PANEL_CTRL_STATUS, ATTR_TEXT_COLOR, VAL_BLACK); 184 | } 185 | 186 | /* finally enable / disable timer and main thread via flag */ 187 | enabled = _enabled; 188 | 189 | return 0; 190 | } 191 | 192 | int CVICALLBACK MainThread (void *functionData) 193 | { 194 | while (!quit) 195 | { 196 | if (enabled && client != NULL) 197 | { 198 | /* set Wait status */ 199 | SetCtrlVal(panelHandle, PANEL_CTRL_STATUS, "Wait Rx"); 200 | SetCtrlAttribute(panelHandle, PANEL_CTRL_STATUS, ATTR_TEXT_COLOR, 0xFFA500L); 201 | 202 | /* main NTP server query */ 203 | s = Client__query_and_sync(client, ip, &result); 204 | 205 | /* if everything is fine */ 206 | if (s == OK) 207 | { 208 | char offset_str[50]; 209 | char delay_str[50]; 210 | char jitter_str[50]; 211 | char delta_str[50]; 212 | 213 | /* get metrics strings */ 214 | sprintf(offset_str, "%.3f", result->mtr.offset_ns / 1000000.0); 215 | sprintf(delay_str, "%.3f", result->mtr.delay_ns / 1000000.0); 216 | sprintf(jitter_str, "%.3f", result->mtr.jitter_ns / 1000000.0); 217 | sprintf(delta_str, "%.3f", result->mtr.delta_ns / 1000000.0); 218 | 219 | /* adjust strip chart properties */ 220 | SetCtrlAttribute(panelHandle, PANEL_CTRL_STATUS, ATTR_TEXT_COLOR, VAL_GREEN); 221 | SetCtrlVal(panelHandle, PANEL_CTRL_OFFSET, offset_str); 222 | SetCtrlVal(panelHandle, PANEL_CTRL_DELAY, delay_str); 223 | SetCtrlVal(panelHandle, PANEL_CTRL_JITTER, jitter_str); 224 | SetCtrlVal(panelHandle, PANEL_CTRL_DELTA, delta_str); 225 | 226 | /* get max of delta and jitter, ceil it to tenth, put in circular buffer and find max */ 227 | double points[3]; 228 | points[0] = result->mtr.delta_ns / 1000000.0; 229 | points[2] = result->mtr.jitter_ns / 1000000.0; 230 | double max = points[0]; 231 | 232 | if (points[2] > max) 233 | max = points[2]; 234 | 235 | /* insert data into buffers */ 236 | data_all[data_idx] = (double)round_up_to_max_pow(ceil(max), 2); 237 | data_delta[data_idx] = points[0]; 238 | 239 | /* shift helper vars */ 240 | if (data_idx == 199) 241 | data_idx = 0; 242 | else 243 | data_idx++; 244 | 245 | if (data_cnt < 200) 246 | data_cnt++; 247 | 248 | /* find max and avg from circular buffer */ 249 | max = 0; 250 | double avg = 0; 251 | for (int i = 0; i < data_cnt; i++) 252 | { 253 | if (data_all[i] > max) 254 | max = (double)data_all[i]; 255 | avg += (double)data_delta[i]; 256 | } 257 | avg /= data_cnt; 258 | 259 | /* set chart limits based on averaged max */ 260 | SetAxisScalingMode(panelHandle, PANEL_STRIPCHART, VAL_LEFT_YAXIS , VAL_MANUAL, 0.0, max); 261 | 262 | /* plot stripchart points */ 263 | points[1] = avg; 264 | PlotStripChart(panelHandle, PANEL_STRIPCHART, points, 3, 0, 0, VAL_DOUBLE); 265 | } 266 | else /* if there was an error */ 267 | { 268 | /* adjust strip chart properties */ 269 | 270 | SetCtrlAttribute(panelHandle, PANEL_CTRL_STATUS, ATTR_TEXT_COLOR, VAL_RED); 271 | /* 272 | SetCtrlVal(panelHandle, PANEL_CTRL_ENABLE, 0); 273 | callEnable(0, 0, EVENT_COMMIT, NULL, 0, 0); 274 | SetCtrlVal(panelHandle, PANEL_CTRL_OFFSET, "0"); 275 | SetCtrlVal(panelHandle, PANEL_CTRL_DELAY, "0"); 276 | SetCtrlVal(panelHandle, PANEL_CTRL_JITTER, "0"); 277 | SetCtrlVal(panelHandle, PANEL_CTRL_DELTA, "0"); 278 | */ 279 | } 280 | 281 | /* convert status enum to string and print it */ 282 | Client__get_status_str(s, status_str); 283 | SetCtrlVal(panelHandle, PANEL_CTRL_STATUS, status_str); 284 | 285 | /* finally delete result - dynamic object */ 286 | Client__free_result(result); 287 | } 288 | Sleep(interval); 289 | } 290 | 291 | return 0; 292 | } 293 | 294 | int CVICALLBACK TimerThread (void *functionData) 295 | { 296 | while (!quit) 297 | { 298 | SYSTEMTIME sdktime; 299 | int hour, min, sec, msec; 300 | 301 | /* get system time */ 302 | GetLocalTime (&sdktime); 303 | 304 | hour = sdktime.wHour; 305 | min = sdktime.wMinute; 306 | sec = sdktime.wSecond; 307 | msec = sdktime.wMilliseconds; 308 | 309 | /* print it */ 310 | char time_str[50]; 311 | sprintf(time_str, "%02d:%02d:%02d.%03d", hour, min, sec, msec); 312 | SetCtrlVal(panelHandle, PANEL_CTRL_TIME, time_str); 313 | 314 | Sleep(TIMER_THREAD_SLEEP); 315 | } 316 | 317 | return 0; 318 | } -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.cws: -------------------------------------------------------------------------------- 1 | [Workspace Header] 2 | Version = 1900 3 | Pathname = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.cws" 4 | CVI Dir = "/f/programs/national instruments/cvi2019" 5 | CVI Shared Dir = "/F/Programs/National Instruments/Shared/CVI" 6 | CVI Pub Local Dir = "/C/ProgramData/National Instruments/CVI2019" 7 | CVI Pub Global Dir = "/C/ProgramData/National Instruments/CVI" 8 | IVI Standard Root Dir = "/C/Program Files (x86)/IVI Foundation/IVI" 9 | IVI Standard Root 64-bit Dir = "/C/Program Files/IVI Foundation/IVI" 10 | VXIplug&play Framework Dir = "/C/Program Files (x86)/IVI Foundation/VISA/winnt" 11 | VXIplug&play Framework 64-bit Dir = "/C/Program Files/IVI Foundation/VISA/win64" 12 | Number of Projects = 1 13 | Active Project = 1 14 | Project 0001 = "ntp_client_gui.prj" 15 | Drag Bar Left = 243 16 | Window Top = 224 17 | Window Left = 1774 18 | Window Bottom = 1222 19 | Window Right = 3299 20 | Maximized = False 21 | Maximized Children = True 22 | Max32 Number Of Errors = 20 23 | Track Include File Dependencies = True 24 | Prompt For Missing Includes = True 25 | Stop On First Error File = False 26 | Bring Up Err Win At Start = True 27 | Bring Up Err Win For Errors = False 28 | Save Changes Before Running = "Always" 29 | Save Changes Before Compiling = "Always" 30 | Hide Windows = False 31 | Break At First Statement = False 32 | Sort Type = "File Name" 33 | Number of Opened Files = 6 34 | Window Confinement Region Enabled = True 35 | MainColumnWidth = 226 36 | FileDateColumnWidth = 70 37 | FileSizeColumnWidth = 70 38 | 39 | [Project Header 0001] 40 | Version = 1900 41 | Don't Update DistKit = False 42 | Platform Code = 4 43 | Build Configuration = "Debug" 44 | Warn User If Debugging Release = 1 45 | Batch Build Release = False 46 | Batch Build Debug = False 47 | 48 | [File 0001] 49 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.uir" 50 | File Type = "User Interface Resource" 51 | Disk Date = 3674018003 52 | In Projects = "1," 53 | Window Top = 32 54 | Window Left = 10 55 | Window Height = 401 56 | Window Width = 602 57 | Window Z-Order = 2 58 | 59 | [File 0002] 60 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.c" 61 | File Type = "CSource" 62 | Disk Date = 3674018432 63 | In Projects = "1," 64 | Source Window State = "1,199,199,199,87,87,87,0,0,0,0,0,0,0,0,0,173,0,199,87,401,602,1,0," 65 | Window Top = 62 66 | Window Left = 26 67 | Window Z-Order = 1 68 | 69 | [File 0003] 70 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client.h" 71 | File Type = "Include" 72 | Disk Date = 3673959092 73 | In Projects = "1," 74 | Source Window State = "1,172,172,172,26,26,26,0,0,0,0,0,0,0,0,0,163,0,172,26,386,602,1,0," 75 | Window Top = 62 76 | Window Left = 26 77 | Window Z-Order = 5 78 | 79 | [File 0004] 80 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui_ui.h" 81 | File Type = "Include" 82 | Disk Date = 3674014100 83 | In Projects = "1," 84 | Source Window State = "1,59,59,59,67,67,67,0,0,0,0,0,0,0,0,0,19,0,59,67,400,600,1,0," 85 | Window Top = 30 86 | Window Z-Order = 4 87 | 88 | [File 0005] 89 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui_ui.c" 90 | File Type = "CSource" 91 | Disk Date = 3674018381 92 | In Projects = "1," 93 | Source Window State = "1,512,512,512,44,44,44,0,0,0,0,0,0,0,0,0,508,0,512,44,386,602,1,0," 94 | Window Top = 122 95 | Window Left = 58 96 | Window Z-Order = 3 97 | 98 | [File 0006] 99 | Path = "/f/Programs/National Instruments/CVI2019/toolslib/toolbox/asynctmr.h" 100 | File Type = "Include" 101 | Disk Date = 3635247522 102 | In Projects = "" 103 | Source Window State = "1,54,54,54,66,87,66,0,3,0,0,0,0,0,0,0,20,0,54,87,386,630,1,0," 104 | Window Top = 122 105 | Window Left = 58 106 | Window Z-Order = 6 107 | 108 | [File 0007] 109 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client.lib" 110 | File Type = "Library" 111 | Disk Date = 3674017603 112 | In Projects = "1," 113 | 114 | [Tab Order] 115 | Tab 0001 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.uir" 116 | Tab 0002 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.c" 117 | Tab 0003 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client.h" 118 | Tab 0004 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui_ui.h" 119 | Tab 0005 = "/f/Programs/National Instruments/CVI2019/toolslib/toolbox/asynctmr.h" 120 | Tab 0006 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui_ui.c" 121 | 122 | [Default Build Config 0001 Debug] 123 | Generate Browse Info = True 124 | Enable Uninitialized Locals Runtime Warning = True 125 | Batch Build = False 126 | Profile = "Disabled" 127 | Debugging Level = "Standard" 128 | Execution Trace = "Disabled" 129 | Command Line Args = "" 130 | Working Directory = "" 131 | Environment Options = "" 132 | External Process Path = "" 133 | 134 | [Default Build Config 0001 Release] 135 | Generate Browse Info = True 136 | Enable Uninitialized Locals Runtime Warning = True 137 | Batch Build = False 138 | Profile = "Disabled" 139 | Debugging Level = "Standard" 140 | Execution Trace = "Disabled" 141 | Command Line Args = "" 142 | Working Directory = "" 143 | Environment Options = "" 144 | External Process Path = "" 145 | 146 | [Default Build Config 0001 Debug64] 147 | Generate Browse Info = True 148 | Enable Uninitialized Locals Runtime Warning = True 149 | Batch Build = False 150 | Profile = "Disabled" 151 | Debugging Level = "Standard" 152 | Execution Trace = "Disabled" 153 | Command Line Args = "" 154 | Working Directory = "" 155 | Environment Options = "" 156 | External Process Path = "" 157 | 158 | [Default Build Config 0001 Release64] 159 | Generate Browse Info = True 160 | Enable Uninitialized Locals Runtime Warning = True 161 | Batch Build = False 162 | Profile = "Disabled" 163 | Debugging Level = "Standard" 164 | Execution Trace = "Disabled" 165 | Command Line Args = "" 166 | Working Directory = "" 167 | Environment Options = "" 168 | External Process Path = "" 169 | 170 | [Build Dependencies 0001] 171 | Number of Dependencies = 0 172 | 173 | [Build Options 0001] 174 | Generate Browse Info = True 175 | Enable Uninitialized Locals Runtime Warning = True 176 | Execution Trace = "Disabled" 177 | Profile = "Disabled" 178 | Debugging Level = "Standard" 179 | Break On Library Errors = True 180 | Break On First Chance Exceptions = False 181 | 182 | [Execution Target 0001] 183 | Execution Target Address = "Local desktop computer" 184 | Execution Target Port = 0 185 | Execution Target Type = 0 186 | 187 | [SCC Options 0001] 188 | Use global settings = True 189 | SCC Provider = "" 190 | SCC Project = "" 191 | Local Path = "" 192 | Auxiliary Path = "" 193 | Perform Same Action For .h File As For .uir File = "Ask" 194 | Perform Same Action For .cds File As For .prj File = "Ask" 195 | Username = "" 196 | Comment = "" 197 | Use Default Username = False 198 | Use Default Comment = False 199 | Suppress CVI Error Messages = False 200 | Always show confirmation dialog = True 201 | 202 | [DLL Debugging Support 0001] 203 | External Process Path = "" 204 | 205 | [Command Line Args 0001] 206 | Command Line Args = "" 207 | Working Directory = "" 208 | Environment Options = "" 209 | 210 | -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/ntp_client_gui.exe -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /* LabWindows/CVI User Interface Resource (UIR) Include File */ 3 | /* */ 4 | /* WARNING: Do not add to, delete from, or otherwise modify the contents */ 5 | /* of this include file. */ 6 | /**************************************************************************/ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* Panels and Controls: */ 15 | 16 | #define PANEL 1 /* callback function: panelCB */ 17 | #define PANEL_CTRL_IP 2 /* control type: string, callback function: (none) */ 18 | #define PANEL_CTRL_ENABLE 3 /* control type: textButton, callback function: callEnable */ 19 | #define PANEL_DELAYLBL 4 /* control type: textMsg, callback function: (none) */ 20 | #define PANEL_JITTERLBL 5 /* control type: textMsg, callback function: (none) */ 21 | #define PANEL_OFFSETLBL 6 /* control type: textMsg, callback function: (none) */ 22 | #define PANEL_DELTALBL 7 /* control type: textMsg, callback function: (none) */ 23 | #define PANEL_CTRL_JITTER 8 /* control type: textMsg, callback function: (none) */ 24 | #define PANEL_DECORATION 9 /* control type: deco, callback function: (none) */ 25 | #define PANEL_CTRL_DELTA 10 /* control type: textMsg, callback function: (none) */ 26 | #define PANEL_CTRL_INTERVAL 11 /* control type: numeric, callback function: (none) */ 27 | #define PANEL_STATUSLBL 12 /* control type: textMsg, callback function: (none) */ 28 | #define PANEL_DECORATION_2 13 /* control type: deco, callback function: (none) */ 29 | #define PANEL_TEXTMSG 14 /* control type: textMsg, callback function: (none) */ 30 | #define PANEL_CTRL_TIME 15 /* control type: textMsg, callback function: (none) */ 31 | #define PANEL_TEXTMSG_2 16 /* control type: textMsg, callback function: (none) */ 32 | #define PANEL_TIMELBL 17 /* control type: textMsg, callback function: (none) */ 33 | #define PANEL_CTRL_OFFSET 18 /* control type: textMsg, callback function: (none) */ 34 | #define PANEL_CTRL_STATUS 19 /* control type: textMsg, callback function: (none) */ 35 | #define PANEL_CTRL_DELAY 20 /* control type: textMsg, callback function: (none) */ 36 | #define PANEL_STRIPCHART 21 /* control type: strip, callback function: (none) */ 37 | 38 | 39 | /* Control Arrays: */ 40 | 41 | /* (no control arrays in the resource file) */ 42 | 43 | 44 | /* Menu Bars, Menus, and Menu Items: */ 45 | 46 | /* (no menu bars in the resource file) */ 47 | 48 | 49 | /* Callback Prototypes: */ 50 | 51 | int CVICALLBACK callEnable(int panel, int control, int event, void *callbackData, int eventData1, int eventData2); 52 | int CVICALLBACK panelCB(int panel, int event, void *callbackData, int eventData1, int eventData2); 53 | 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/ntp_client_gui.png -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.prj: -------------------------------------------------------------------------------- 1 | [Project Header] 2 | Version = 1900 3 | Pathname = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.prj" 4 | CVI Dir = "/f/programs/national instruments/cvi2019" 5 | CVI Shared Dir = "/F/Programs/National Instruments/Shared/CVI" 6 | CVI Pub Local Dir = "/C/ProgramData/National Instruments/CVI2019" 7 | CVI Pub Global Dir = "/C/ProgramData/National Instruments/CVI" 8 | IVI Standard Root Dir = "/C/Program Files (x86)/IVI Foundation/IVI" 9 | VXIplug&play Framework Dir = "/C/Program Files (x86)/IVI Foundation/VISA/winnt" 10 | IVI Standard Root 64-bit Dir = "/C/Program Files/IVI Foundation/IVI" 11 | VXIplug&play Framework 64-bit Dir = "/C/Program Files/IVI Foundation/VISA/win64" 12 | Number of Files = 6 13 | Target Type = "Executable" 14 | Flags = 16 15 | Copied From Locked InstrDrv Directory = False 16 | Copied from VXIPNP Directory = False 17 | Locked InstrDrv Name = "" 18 | Don't Display Deploy InstrDrv Dialog = False 19 | 20 | [Folders] 21 | Instrument Files Folder Not Added Yet = True 22 | Folder 0 = "Source Files" 23 | FolderEx 0 = "Source Files" 24 | Folder 1 = "Include Files" 25 | FolderEx 1 = "Include Files" 26 | Folder 2 = "Library Files" 27 | FolderEx 2 = "Library Files" 28 | Folder 3 = "User Interface Files" 29 | FolderEx 3 = "User Interface Files" 30 | 31 | [File 0001] 32 | File Type = "CSource" 33 | Res Id = 1 34 | Path Is Rel = True 35 | Path Rel To = "Project" 36 | Path Rel Path = "ntp_client_gui.c" 37 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.c" 38 | Exclude = False 39 | Compile Into Object File = False 40 | Project Flags = 0 41 | Folder = "Source Files" 42 | Folder Id = 0 43 | 44 | [File 0002] 45 | File Type = "CSource" 46 | Res Id = 2 47 | Path Is Rel = True 48 | Path Rel To = "Project" 49 | Path Rel Path = "ntp_client_gui_ui.c" 50 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui_ui.c" 51 | Exclude = False 52 | Compile Into Object File = False 53 | Project Flags = 0 54 | Folder = "Source Files" 55 | Folder Id = 0 56 | 57 | [File 0003] 58 | File Type = "Include" 59 | Res Id = 3 60 | Path Is Rel = True 61 | Path Rel To = "Project" 62 | Path Rel Path = "ntp_client.h" 63 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client.h" 64 | Exclude = False 65 | Project Flags = 0 66 | Folder = "Include Files" 67 | Folder Id = 1 68 | 69 | [File 0004] 70 | File Type = "Include" 71 | Res Id = 4 72 | Path Is Rel = True 73 | Path Rel To = "Project" 74 | Path Rel Path = "ntp_client_gui_ui.h" 75 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui_ui.h" 76 | Exclude = False 77 | Project Flags = 0 78 | Folder = "Include Files" 79 | Folder Id = 1 80 | 81 | [File 0005] 82 | File Type = "Library" 83 | Res Id = 5 84 | Path Is Rel = True 85 | Path Rel To = "Project" 86 | Path Rel Path = "ntp_client.lib" 87 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client.lib" 88 | Exclude = False 89 | Project Flags = 0 90 | Folder = "Library Files" 91 | Folder Id = 2 92 | 93 | [File 0006] 94 | File Type = "User Interface Resource" 95 | Res Id = 6 96 | Path Is Rel = True 97 | Path Rel To = "Project" 98 | Path Rel Path = "ntp_client_gui.uir" 99 | Path = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.uir" 100 | Exclude = False 101 | Project Flags = 0 102 | Folder = "User Interface Files" 103 | Folder Id = 3 104 | 105 | [Custom Build Configs] 106 | Num Custom Build Configs = 0 107 | 108 | [Default Build Config Debug] 109 | Config Name = "Debug" 110 | Is 64-Bit = False 111 | Is Release = False 112 | Default Calling Convention = "cdecl" 113 | Optimization Level = "Optimize for speed (level 2)" 114 | Require Prototypes = True 115 | Show Warning IDs in Build Output = False 116 | Selected Warning Level = "Extended" 117 | Warning List None = "" 118 | Error List None = "" 119 | Warning List Common = "" 120 | Error List Common = "" 121 | Warning List Extended = "" 122 | Error List Extended = "" 123 | Warning List All = "" 124 | Error List All = "" 125 | Warning Mode = 0 126 | Enable Unreferenced Identifiers Warning = True 127 | Enable Pointer Mismatch Warning = True 128 | Enable Unreachable Code Warning = True 129 | Enable Assignment In Conditional Warning = True 130 | Uninitialized Locals Compile Warning = "Aggressive" 131 | Require Return Values = True 132 | Enable C99 Extensions = True 133 | Enable OpenMP Extensions = False 134 | Stack Size = 250000 135 | Stack Reserve = 1048576 136 | Stack Commit = 4096 137 | Image Base Address = 4194304 138 | Image Base Address x64 = 4194304 139 | Compiler Defines = "/DWIN32_LEAN_AND_MEAN" 140 | Sign = False 141 | Sign Store = "" 142 | Sign Certificate = "" 143 | Sign Timestamp URL = "" 144 | Sign URL = "" 145 | Manifest Embed = False 146 | Manifest Path Is Rel = True 147 | Manifest Path Rel To = "Project" 148 | Manifest Path Rel Path = ".manifest" 149 | Manifest Path = "/d/__CVUT/VIN/ntp_client_gui/.manifest" 150 | Icon File Is Rel = True 151 | Icon File Rel To = "Project" 152 | Icon File Rel Path = "icon.ico" 153 | Icon File = "/d/__CVUT/VIN/ntp_client_gui/icon.ico" 154 | Application Title = "NTP Client" 155 | Use IVI Subdirectories for Import Libraries = False 156 | Use VXIPNP Subdirectories for Import Libraries = False 157 | Use Dflt Import Lib Base Name = True 158 | Where to Copy DLL = "Do not copy" 159 | Custom Directory to Copy DLL Is Rel = False 160 | Custom Directory to Copy DLL = "" 161 | Generate Source Documentation = "None" 162 | Runtime Support = "Full Runtime Support" 163 | Runtime Binding = "Shared" 164 | Embed Project .UIRs = False 165 | Generate Map File = False 166 | Embed Timestamp = True 167 | Create Console Application = False 168 | Using LoadExternalModule = True 169 | DLL Exports = "Include File Symbols" 170 | Register ActiveX Server = False 171 | Numeric File Version = "1,0,0,0" 172 | Numeric Prod Version = "1,0,0,0" 173 | Comments = "" 174 | Comments Ex = "" 175 | Company Name = "CTU/VIN" 176 | Company Name Ex = "CTU/VIN" 177 | File Description = "NTP Client" 178 | File Description Ex = "NTP Client" 179 | File Version = "1.0" 180 | File Version Ex = "%f1.%f2" 181 | Internal Name = "ntp_client_gui" 182 | Internal Name Ex = "%basename" 183 | Legal Copyright = "Jakub Parez" 184 | Legal Copyright Ex = "Jakub Parez" 185 | Legal Trademarks = "" 186 | Legal Trademarks Ex = "" 187 | Original Filename = "ntp_client_gui.exe" 188 | Original Filename Ex = "%filename" 189 | Private Build = "" 190 | Private Build Ex = "" 191 | Product Name = "ATEsystem NTP Client" 192 | Product Name Ex = "%company %application" 193 | Product Version = "1.0" 194 | Product Version Ex = "%p1.%p2" 195 | Special Build = "" 196 | Special Build Ex = "" 197 | Add Type Lib To DLL = False 198 | Include Type Lib Help Links = False 199 | TLB Help Style = "HLP" 200 | Type Lib FP File Is Rel = False 201 | Type Lib FP File = "" 202 | Add NI Type Info To DLL = False 203 | Use Single Header for NI Type Info = False 204 | Single Header NI Type Info File Is Rel = False 205 | Single Header NI Type Info File = "" 206 | 207 | [Default Build Config Release] 208 | Config Name = "Release" 209 | Is 64-Bit = False 210 | Is Release = True 211 | Default Calling Convention = "cdecl" 212 | Optimization Level = "Optimize for speed (level 2)" 213 | Require Prototypes = True 214 | Show Warning IDs in Build Output = False 215 | Selected Warning Level = "Common" 216 | Warning List None = "" 217 | Error List None = "" 218 | Warning List Common = "" 219 | Error List Common = "" 220 | Warning List Extended = "" 221 | Error List Extended = "" 222 | Warning List All = "" 223 | Error List All = "" 224 | Warning Mode = 0 225 | Enable Unreferenced Identifiers Warning = True 226 | Enable Pointer Mismatch Warning = True 227 | Enable Unreachable Code Warning = True 228 | Enable Assignment In Conditional Warning = True 229 | Uninitialized Locals Compile Warning = "Aggressive" 230 | Require Return Values = True 231 | Enable C99 Extensions = True 232 | Enable OpenMP Extensions = False 233 | Stack Size = 250000 234 | Stack Reserve = 1048576 235 | Stack Commit = 4096 236 | Image Base Address = 4194304 237 | Image Base Address x64 = 4194304 238 | Compiler Defines = "/DWIN32_LEAN_AND_MEAN" 239 | Sign = False 240 | Sign Store = "" 241 | Sign Certificate = "" 242 | Sign Timestamp URL = "" 243 | Sign URL = "" 244 | Manifest Embed = False 245 | Manifest Path Is Rel = True 246 | Manifest Path Rel To = "Project" 247 | Manifest Path Rel Path = ".manifest" 248 | Manifest Path = "/d/__CVUT/VIN/ntp_client_gui/.manifest" 249 | Icon File Is Rel = True 250 | Icon File Rel To = "Project" 251 | Icon File Rel Path = "icon.ico" 252 | Icon File = "/d/__CVUT/VIN/ntp_client_gui/icon.ico" 253 | Application Title = "NTP Client" 254 | Use IVI Subdirectories for Import Libraries = False 255 | Use VXIPNP Subdirectories for Import Libraries = False 256 | Use Dflt Import Lib Base Name = True 257 | Where to Copy DLL = "Do not copy" 258 | Custom Directory to Copy DLL Is Rel = False 259 | Custom Directory to Copy DLL = "" 260 | Generate Source Documentation = "None" 261 | Runtime Support = "Full Runtime Support" 262 | Runtime Binding = "Shared" 263 | Embed Project .UIRs = False 264 | Generate Map File = False 265 | Embed Timestamp = True 266 | Create Console Application = False 267 | Using LoadExternalModule = True 268 | DLL Exports = "Include File Symbols" 269 | Register ActiveX Server = False 270 | Numeric File Version = "1,0,0,0" 271 | Numeric Prod Version = "1,0,0,0" 272 | Comments = "" 273 | Comments Ex = "" 274 | Company Name = "CTU/VIN" 275 | Company Name Ex = "CTU/VIN" 276 | File Description = "NTP Client" 277 | File Description Ex = "NTP Client" 278 | File Version = "1.0" 279 | File Version Ex = "%f1.%f2" 280 | Internal Name = "ntp_client_gui" 281 | Internal Name Ex = "%basename" 282 | Legal Copyright = "Jakub Parez" 283 | Legal Copyright Ex = "Jakub Parez" 284 | Legal Trademarks = "" 285 | Legal Trademarks Ex = "" 286 | Original Filename = "ntp_client_gui.exe" 287 | Original Filename Ex = "%filename" 288 | Private Build = "" 289 | Private Build Ex = "" 290 | Product Name = "ATEsystem NTP Client" 291 | Product Name Ex = "%company %application" 292 | Product Version = "1.0" 293 | Product Version Ex = "%p1.%p2" 294 | Special Build = "" 295 | Special Build Ex = "" 296 | Add Type Lib To DLL = False 297 | Include Type Lib Help Links = False 298 | TLB Help Style = "HLP" 299 | Type Lib FP File Is Rel = False 300 | Type Lib FP File = "" 301 | Add NI Type Info To DLL = False 302 | Use Single Header for NI Type Info = False 303 | Single Header NI Type Info File Is Rel = False 304 | Single Header NI Type Info File = "" 305 | 306 | [Default Build Config Debug64] 307 | Config Name = "Debug64" 308 | Is 64-Bit = True 309 | Is Release = False 310 | Default Calling Convention = "cdecl" 311 | Optimization Level = "Optimize for speed (level 2)" 312 | Require Prototypes = True 313 | Show Warning IDs in Build Output = False 314 | Selected Warning Level = "Common" 315 | Warning List None = "" 316 | Error List None = "" 317 | Warning List Common = "" 318 | Error List Common = "" 319 | Warning List Extended = "" 320 | Error List Extended = "" 321 | Warning List All = "" 322 | Error List All = "" 323 | Warning Mode = 0 324 | Enable Unreferenced Identifiers Warning = True 325 | Enable Pointer Mismatch Warning = True 326 | Enable Unreachable Code Warning = True 327 | Enable Assignment In Conditional Warning = True 328 | Uninitialized Locals Compile Warning = "Aggressive" 329 | Require Return Values = True 330 | Enable C99 Extensions = True 331 | Enable OpenMP Extensions = False 332 | Stack Size = 250000 333 | Stack Reserve = 1048576 334 | Stack Commit = 4096 335 | Image Base Address = 4194304 336 | Image Base Address x64 = 4194304 337 | Compiler Defines = "/DWIN32_LEAN_AND_MEAN" 338 | Sign = False 339 | Sign Store = "" 340 | Sign Certificate = "" 341 | Sign Timestamp URL = "" 342 | Sign URL = "" 343 | Manifest Embed = False 344 | Icon File Is Rel = False 345 | Icon File = "" 346 | Application Title = "" 347 | Use IVI Subdirectories for Import Libraries = False 348 | Use VXIPNP Subdirectories for Import Libraries = False 349 | Use Dflt Import Lib Base Name = True 350 | Where to Copy DLL = "Do not copy" 351 | Custom Directory to Copy DLL Is Rel = False 352 | Custom Directory to Copy DLL = "" 353 | Generate Source Documentation = "None" 354 | Runtime Support = "Full Runtime Support" 355 | Runtime Binding = "Shared" 356 | Embed Project .UIRs = False 357 | Generate Map File = False 358 | Embed Timestamp = True 359 | Create Console Application = False 360 | Using LoadExternalModule = True 361 | DLL Exports = "Include File Symbols" 362 | Register ActiveX Server = False 363 | Add Type Lib To DLL = False 364 | Include Type Lib Help Links = False 365 | TLB Help Style = "HLP" 366 | Type Lib FP File Is Rel = False 367 | Type Lib FP File = "" 368 | Add NI Type Info To DLL = False 369 | Use Single Header for NI Type Info = False 370 | Single Header NI Type Info File Is Rel = False 371 | Single Header NI Type Info File = "" 372 | 373 | [Default Build Config Release64] 374 | Config Name = "Release64" 375 | Is 64-Bit = True 376 | Is Release = True 377 | Default Calling Convention = "cdecl" 378 | Optimization Level = "Optimize for speed (level 2)" 379 | Require Prototypes = True 380 | Show Warning IDs in Build Output = False 381 | Selected Warning Level = "Common" 382 | Warning List None = "" 383 | Error List None = "" 384 | Warning List Common = "" 385 | Error List Common = "" 386 | Warning List Extended = "" 387 | Error List Extended = "" 388 | Warning List All = "" 389 | Error List All = "" 390 | Warning Mode = 0 391 | Enable Unreferenced Identifiers Warning = True 392 | Enable Pointer Mismatch Warning = True 393 | Enable Unreachable Code Warning = True 394 | Enable Assignment In Conditional Warning = True 395 | Uninitialized Locals Compile Warning = "Aggressive" 396 | Require Return Values = True 397 | Enable C99 Extensions = True 398 | Enable OpenMP Extensions = False 399 | Stack Size = 250000 400 | Stack Reserve = 1048576 401 | Stack Commit = 4096 402 | Image Base Address = 4194304 403 | Image Base Address x64 = 4194304 404 | Compiler Defines = "/DWIN32_LEAN_AND_MEAN" 405 | Sign = False 406 | Sign Store = "" 407 | Sign Certificate = "" 408 | Sign Timestamp URL = "" 409 | Sign URL = "" 410 | Manifest Embed = False 411 | Icon File Is Rel = False 412 | Icon File = "" 413 | Application Title = "" 414 | Use IVI Subdirectories for Import Libraries = False 415 | Use VXIPNP Subdirectories for Import Libraries = False 416 | Use Dflt Import Lib Base Name = True 417 | Where to Copy DLL = "Do not copy" 418 | Custom Directory to Copy DLL Is Rel = False 419 | Custom Directory to Copy DLL = "" 420 | Generate Source Documentation = "None" 421 | Runtime Support = "Full Runtime Support" 422 | Runtime Binding = "Shared" 423 | Embed Project .UIRs = False 424 | Generate Map File = False 425 | Embed Timestamp = True 426 | Create Console Application = False 427 | Using LoadExternalModule = True 428 | DLL Exports = "Include File Symbols" 429 | Register ActiveX Server = False 430 | Add Type Lib To DLL = False 431 | Include Type Lib Help Links = False 432 | TLB Help Style = "HLP" 433 | Type Lib FP File Is Rel = False 434 | Type Lib FP File = "" 435 | Add NI Type Info To DLL = False 436 | Use Single Header for NI Type Info = False 437 | Single Header NI Type Info File Is Rel = False 438 | Single Header NI Type Info File = "" 439 | 440 | [Compiler Options] 441 | Default Calling Convention = "cdecl" 442 | Require Prototypes = True 443 | Require Return Values = True 444 | Enable Pointer Mismatch Warning = True 445 | Enable Unreachable Code Warning = True 446 | Enable Unreferenced Identifiers Warning = True 447 | Enable Assignment In Conditional Warning = True 448 | Enable C99 Extensions = True 449 | Uninitialized Locals Compile Warning = "Aggressive" 450 | Precompile Prefix Header = False 451 | Prefix Header File = "" 452 | 453 | [Run Options] 454 | Stack Size = 250000 455 | Stack Commit = 4096 456 | Image Base Address = 4194304 457 | Image Base Address x64 = 4194304 458 | 459 | [Compiler Defines] 460 | Compiler Defines = "/DWIN32_LEAN_AND_MEAN" 461 | 462 | [Create Executable] 463 | Executable File_Debug Is Rel = True 464 | Executable File_Debug Rel To = "Project" 465 | Executable File_Debug Rel Path = "ntp_client_gui.exe" 466 | Executable File_Debug = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.exe" 467 | Executable File_Release Is Rel = True 468 | Executable File_Release Rel To = "Project" 469 | Executable File_Release Rel Path = "ntp_client_gui.exe" 470 | Executable File_Release = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.exe" 471 | Executable File_Debug64 Is Rel = True 472 | Executable File_Debug64 Rel To = "Project" 473 | Executable File_Debug64 Rel Path = "ntp_client_gui.exe" 474 | Executable File_Debug64 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.exe" 475 | Executable File_Release64 Is Rel = True 476 | Executable File_Release64 Rel To = "Project" 477 | Executable File_Release64 Rel Path = "ntp_client_gui.exe" 478 | Executable File_Release64 = "/d/__CVUT/VIN/ntp_client_gui/ntp_client_gui.exe" 479 | Icon File Is Rel = True 480 | Icon File Rel To = "Project" 481 | Icon File Rel Path = "icon.ico" 482 | Icon File = "/d/__CVUT/VIN/ntp_client_gui/icon.ico" 483 | Application Title = "NTP Client" 484 | Numeric File Version = "1,0,0,0" 485 | Numeric Prod Version = "1,0,0,0" 486 | Comments = "" 487 | Comments Ex = "" 488 | Company Name = "CTU/VIN" 489 | Company Name Ex = "CTU/VIN" 490 | File Description = "NTP Client" 491 | File Description Ex = "NTP Client" 492 | File Version = "1.0" 493 | File Version Ex = "%f1.%f2" 494 | Internal Name = "ntp_client_gui" 495 | Internal Name Ex = "%basename" 496 | Legal Copyright = "Jakub Parez" 497 | Legal Copyright Ex = "Jakub Parez" 498 | Legal Trademarks = "" 499 | Legal Trademarks Ex = "" 500 | Original Filename = "ntp_client_gui.exe" 501 | Original Filename Ex = "%filename" 502 | Private Build = "" 503 | Private Build Ex = "" 504 | Product Name = "ATEsystem NTP Client" 505 | Product Name Ex = "%company %application" 506 | Product Version = "1.0" 507 | Product Version Ex = "%p1.%p2" 508 | Special Build = "" 509 | Special Build Ex = "" 510 | DLL Exports = "Include File Symbols" 511 | Use IVI Subdirectories for Import Libraries = False 512 | Use VXIPNP Subdirectories for Import Libraries = False 513 | Use Dflt Import Lib Base Name = True 514 | Where to Copy DLL = "Do not copy" 515 | Custom Directory to Copy DLL Is Rel = False 516 | Custom Directory to Copy DLL = "" 517 | Generate Source Documentation = "None" 518 | Add Type Lib To DLL = False 519 | Include Type Lib Help Links = False 520 | TLB Help Style = "HLP" 521 | Type Lib FP File Is Rel = False 522 | Type Lib FP File = "" 523 | Type Lib Guid = "" 524 | Runtime Support = "Full Runtime Support" 525 | Instrument Driver Support Only = False 526 | Embed Project .UIRs = False 527 | Generate Map File = False 528 | 529 | [External Compiler Support] 530 | UIR Callbacks File Option = 0 531 | Using LoadExternalModule = False 532 | Create Project Symbols File = True 533 | UIR Callbacks Obj File Is Rel = False 534 | UIR Callbacks Obj File = "" 535 | Project Symbols H File Is Rel = False 536 | Project Symbols H File = "" 537 | Project Symbols Obj File Is Rel = False 538 | Project Symbols Obj File = "" 539 | 540 | [ActiveX Server Options] 541 | Specification File Is Rel = False 542 | Specification File = "" 543 | Source File Is Rel = False 544 | Source File = "" 545 | Include File Is Rel = False 546 | Include File = "" 547 | IDL File Is Rel = False 548 | IDL File = "" 549 | Register ActiveX Server = False 550 | 551 | [Signing Info] 552 | Sign = False 553 | Sign Debug Build = False 554 | Store = "" 555 | Certificate = "" 556 | Timestamp URL = "" 557 | URL = "" 558 | 559 | [Manifest Info] 560 | Embed = False 561 | Path Is Rel = True 562 | Path Rel To = "Project" 563 | Path Rel Path = ".manifest" 564 | Path = "/d/__CVUT/VIN/ntp_client_gui/.manifest" 565 | 566 | [tpcSection] 567 | tpcEnabled = 0 568 | tpcOverrideEnvironment = 0 569 | tpcEnabled x64 = 0 570 | tpcOverrideEnvironment x64 = 0 571 | 572 | -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui.uir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parezj/NTP-Client/92779bd24d36aaf55682c5e1795e26005b82c7e7/src/ntp_client_gui/ntp_client_gui.uir -------------------------------------------------------------------------------- /src/ntp_client_gui/ntp_client_gui_ui.h: -------------------------------------------------------------------------------- 1 | 2 | //---------------------------------------------------------------------------------------------------- 3 | //---------------------------------------------------------------------------------------------------- 4 | // 5 | // "ntp_client_gui_ui.h" 6 | // 7 | // Declaration and include file for UI build functions 8 | // 9 | 10 | // Date: 06-02-2020 11 | // 12 | 13 | //---------------------------------------------------------------------------------------------------- 14 | //---------------------------------------------------------------------------------------------------- 15 | 16 | #ifndef _NTP_CLIENT_GUI_UI_INCLUDED 17 | #define _NTP_CLIENT_GUI_UI_INCLUDED 18 | 19 | #ifdef __cplusplus 20 | extern "C" { /* Assume C declarations for C++ */ 21 | #endif /* __cplusplus */ 22 | 23 | //---------------------------------------------------------------------------------------------------- 24 | // Include required headers 25 | //---------------------------------------------------------------------------------------------------- 26 | 27 | #include // definition of CVICALLBACK 28 | 29 | //---------------------------------------------------------------------------------------------------- 30 | // Prototype UI build functions. 31 | //---------------------------------------------------------------------------------------------------- 32 | 33 | int MainPANEL (int hParentPanel); 34 | 35 | //------------------------------------------------------------------------------------------------- 36 | // Prototype callbacks for Panel: PANEL 37 | // ------------------------------------------------------------------------------------------------ 38 | 39 | // Panel 40 | int CVICALLBACK panelCB (int panelHandle, int event, void *callbackData, int eventData1, int eventData2); 41 | 42 | // Control: PANEL_CTRL_ENABLE 43 | int CVICALLBACK callEnable (int panelHandle, int control, int event, void *callbackData, int eventData1, int eventData2); 44 | 45 | //------------------------------------------------------------------------------------------------- 46 | // Declare identifiers for Panel: PANEL 47 | // ------------------------------------------------------------------------------------------------ 48 | 49 | extern int PANEL_CTRL_IP ; // control identifier 50 | extern int PANEL_CTRL_ENABLE ; // control identifier 51 | extern int PANEL_DELAYLBL ; // control identifier 52 | extern int PANEL_JITTERLBL ; // control identifier 53 | extern int PANEL_OFFSETLBL ; // control identifier 54 | extern int PANEL_DELTALBL ; // control identifier 55 | extern int PANEL_CTRL_JITTER ; // control identifier 56 | extern int PANEL_DECORATION ; // control identifier 57 | extern int PANEL_CTRL_DELTA ; // control identifier 58 | extern int PANEL_CTRL_INTERVAL ; // control identifier 59 | extern int PANEL_STATUSLBL ; // control identifier 60 | extern int PANEL_DECORATION_2 ; // control identifier 61 | extern int PANEL_TEXTMSG ; // control identifier 62 | extern int PANEL_CTRL_TIME ; // control identifier 63 | extern int PANEL_TEXTMSG_2 ; // control identifier 64 | extern int PANEL_TIMELBL ; // control identifier 65 | extern int PANEL_CTRL_OFFSET ; // control identifier 66 | extern int PANEL_CTRL_STATUS ; // control identifier 67 | extern int PANEL_CTRL_DELAY ; // control identifier 68 | extern int PANEL_STRIPCHART ; // control identifier 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif // _NTP_CLIENT_GUI_UI_INCLUDED -------------------------------------------------------------------------------- /src/ntp_client_lib/ntp_client_lib.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {6E21FA4A-474A-46D1-9C88-D4F70041F4F8} 24 | Win32Proj 25 | ntpclientlib 26 | 10.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v142 33 | MultiByte 34 | 35 | 36 | StaticLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | StaticLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | ntp_client 77 | 78 | 79 | true 80 | 81 | 82 | false 83 | ntp_client 84 | $(SolutionDir)$(Configuration)\lib\ 85 | $(Configuration)\lib\ 86 | 87 | 88 | false 89 | 90 | 91 | 92 | 93 | 94 | Level3 95 | true 96 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 97 | true 98 | pch.h 99 | ..\ntp_client_shared\include;%(AdditionalIncludeDirectories) 100 | 101 | 102 | Windows 103 | true 104 | 105 | 106 | Ws2_32.lib;%(AdditionalDependencies) 107 | 108 | 109 | 110 | 111 | Use 112 | Level3 113 | true 114 | _DEBUG;_LIB;%(PreprocessorDefinitions) 115 | true 116 | pch.h 117 | 118 | 119 | Windows 120 | true 121 | 122 | 123 | 124 | 125 | NotUsing 126 | Level3 127 | true 128 | true 129 | false 130 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 131 | false 132 | 133 | 134 | ..\ntp_client_shared\include;%(AdditionalIncludeDirectories) 135 | 136 | 137 | Windows 138 | true 139 | true 140 | true 141 | 142 | 143 | Ws2_32.lib;%(AdditionalDependencies) 144 | Windows 145 | 146 | 147 | true 148 | 149 | 150 | 151 | 152 | Use 153 | Level3 154 | true 155 | true 156 | true 157 | NDEBUG;_LIB;%(PreprocessorDefinitions) 158 | true 159 | pch.h 160 | 161 | 162 | Windows 163 | true 164 | true 165 | true 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /src/ntp_client_lib/ntp_client_lib.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/ntp_client_lib/ntp_client_lib.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/ntp_client_shared/include/ntp_client.h: -------------------------------------------------------------------------------- 1 | /************************************** 2 | * Author: Jakub Parez 3 | * File: ntp_client.h 4 | * Project: NTP client 5 | * Company: CTU/VIN 6 | * Date: 2020/4/19 10:30 7 | * License: MIT 8 | ***************************************/ 9 | 10 | #ifndef ntp_client_h 11 | #define ntp_client_h 12 | 13 | #define EXPORT __declspec(dllexport) 14 | #define IMPORT __declspec(dllimport) 15 | 16 | #ifdef __cplusplus 17 | #include 18 | #include 19 | #endif 20 | 21 | #define Interface struct 22 | 23 | #define NTP_PACKET_LEN 48 24 | #define UDP_PORT 123 25 | #define RX_TIMEOUT 5000 26 | #define JITTER_WINDOW 100 27 | 28 | #define STR_MAX_SIZE 100 29 | #define NTP_TS_DELTA 2208988800ull 30 | 31 | 32 | //[module(name = "ntp_client")]; 33 | 34 | /* 35 | Below is a description of the NTP / SNTP Version 4 message format, 36 | which follows the IPand UDP headers.This format is identical to 37 | that described in RFC - 1305, with the exception of the contents of the 38 | reference identifier field.The header fields are defined as follows : 39 | 40 | 1 2 3 41 | 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 1 42 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 43 | | LI | VN | Mode | Stratum | Poll | Precision | 44 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 45 | | Root Delay | 46 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 47 | | Root Dispersion | 48 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 49 | | Reference Identifier | 50 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 51 | | | 52 | | Reference Timestamp(64) | 53 | | | 54 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 55 | | | 56 | | Originate Timestamp(64) | 57 | | | 58 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 59 | | | 60 | | Receive Timestamp(64) | 61 | | | 62 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 | | | 64 | | Transmit Timestamp(64) | 65 | | | 66 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67 | | Key Identifier(optional) (32) | 68 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69 | | | 70 | | | 71 | | Message Digest(optional) (128) | 72 | | | 73 | | | 74 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 75 | 76 | Reference Timestamp : This is the time at which the local clock was 77 | last set or corrected, in 64 - bit timestamp format. 78 | 79 | Originate Timestamp : This is the time at which the request departed 80 | the client for the server, in 64 - bit timestamp format. 81 | 82 | Receive Timestamp : This is the time at which the request arrived at 83 | the server, in 64 - bit timestamp format. 84 | 85 | Transmit Timestamp : This is the time at which the reply departed the 86 | server for the client, in 64 - bit timestamp format. 87 | 88 | 89 | * NTP uses two fixed point formats. The first (l_fp) is the "long" 90 | * format and is 64 bits long with the decimal between bits 31 and 32. 91 | * This is used for time stamps in the NTP packet header (in network 92 | * byte order) and for internal computations of offsets (in local host 93 | * byte order). We use the same structure for both signed and unsigned 94 | * values, which is a big hack but saves rewriting all the operators 95 | * twice. Just to confuse this, we also sometimes just carry the 96 | * fractional part in calculations, in both signed and unsigned forms. 97 | * Anyway, an l_fp looks like: 98 | * 99 | * 0 1 2 3 100 | * 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 1 101 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 102 | * | Integral Part | 103 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 104 | * | Fractional Part | 105 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 106 | * REF http://www.eecis.udel.edu/~mills/database/rfc/rfc2030.txt 107 | 108 | offset = [(T2 - T1) + (T3 - T4)] / 2 109 | delay = (T4 - T1) - (T3 - T2) 110 | 111 | */ 112 | 113 | #ifdef __cplusplus 114 | namespace CTU { namespace VIN { namespace NTP_client 115 | { 116 | #endif 117 | struct TimePt 118 | { 119 | int tm_nsec; /* nano seconds, range 0 to 999 */ 120 | int tm_usec; /* micro seconds, range 0 to 999 */ 121 | int tm_msec; /* mili seconds, range 0 to 999 */ 122 | int tm_sec; /* seconds, range 0 to 59 */ 123 | int tm_min; /* minutes, range 0 to 59 */ 124 | int tm_hour; /* hours, range 0 to 23 */ 125 | int tm_mday; /* day of the month, range 1 to 31 */ 126 | int tm_mon; /* month, range 0 to 11 */ 127 | int tm_year; /* The number of years since 1900 */ 128 | }; 129 | 130 | struct Metrics 131 | { 132 | double delay_ns; /* delay from transporting packet through network */ 133 | double offset_ns; /* offset from the server time */ 134 | double jitter_ns; /* network jitter accumulated in time when calling sync */ 135 | double delta_ns; /* actual difference between server and client time */ 136 | }; 137 | 138 | struct Result 139 | { 140 | struct TimePt time; /* plain C style struct time point with actual time*/ 141 | struct Metrics mtr; /* metrics values with other relevant data */ 142 | }; 143 | 144 | #ifdef __cplusplus 145 | typedef std::chrono::time_point time_point_t; 146 | 147 | class ResultEx 148 | { 149 | public: 150 | time_point_t time; /* time point class with actual time */ 151 | Metrics mtr; /* metrics values with other relevant data */ 152 | }; 153 | #endif 154 | 155 | enum Status : int16_t 156 | { 157 | OK = 0, 158 | UNKNOWN_ERR = 1, 159 | INIT_WINSOCK_ERR = 2, 160 | CREATE_SOCKET_ERR = 3, 161 | SEND_MSG_ERR = 4, 162 | RECEIVE_MSG_ERR = 5, 163 | RECEIVE_MSG_TIMEOUT = 6, 164 | SET_WIN_TIME_ERR = 7, 165 | ADMIN_RIGHTS_NEEDED = 8 166 | }; 167 | 168 | typedef void* HNTP; 169 | 170 | #ifdef __cplusplus 171 | extern "C" { 172 | #endif 173 | /* object lifecycle */ 174 | EXPORT HNTP __cdecl Client__create(void); 175 | EXPORT void __cdecl Client__close(HNTP self); 176 | 177 | /* main NTP server query functions */ 178 | EXPORT enum Status __cdecl Client__query(HNTP self, const char* hostname, struct Result** result_out); 179 | EXPORT enum Status __cdecl Client__query_and_sync(HNTP self, const char* hostname, struct Result** result_out); 180 | 181 | /* helper functions */ 182 | EXPORT void __cdecl Client__format_info_str(struct Result* result, char* str_out); 183 | EXPORT void __cdecl Client__get_status_str(enum Status status, char* str_out); 184 | EXPORT void __cdecl Client__free_result(struct Result* result); 185 | #ifdef __cplusplus 186 | } 187 | 188 | Interface IClient 189 | { 190 | virtual Status query(const char* hostname, ResultEx** result_out) = 0; 191 | virtual Status query_and_sync(const char* hostname, ResultEx** result_out) = 0; 192 | virtual ~IClient() {}; 193 | }; 194 | 195 | class Packet // Total: 384 bits or 48 bytes. 196 | { 197 | public: 198 | uint8_t li_vn_mode; // 8 bits. li, vn, and mode. 199 | // -li 2 bits. Leap indicator. 200 | // -vn 3 bits. Version number of the protocol. 3,4 201 | // -mode 3 bits. Client will pick mode 3 for client. 202 | 203 | uint8_t stratum; // 8 bits. Stratum level of the local clock. 204 | uint8_t poll; // 8 bits. Maximum interval between successive messages. 205 | uint8_t precision; // 8 bits. Precision of the local clock. 206 | uint32_t rootDelay; // 32 bits. Total round trip delay time. 207 | uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source. 208 | 209 | uint32_t refId; // 32 bits. Reference clock identifier. 210 | uint32_t refTm_s; // 32 bits. Reference time-stamp seconds. 211 | uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second. 212 | 213 | uint32_t origTm_s; // 32 bits. Originate time-stamp seconds. = t1 214 | uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second. 215 | 216 | uint32_t rxTm_s; // 32 bits. Received time-stamp seconds. = t2 217 | uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second. 218 | 219 | uint32_t txTm_s; // 32 bits. Transmit time-stamp seconds. = t3 220 | uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second. 221 | }; 222 | 223 | class Client : public IClient 224 | { 225 | protected: 226 | 227 | public: 228 | Client(); 229 | virtual ~Client(); 230 | 231 | virtual Status query(const char* hostname, ResultEx** result_out); 232 | virtual Status query_and_sync(const char* hostname, ResultEx** result_out); 233 | 234 | static void format_info_str(Result* result, char* str); 235 | static void format_info_str(ResultEx* result, char* str); 236 | static void get_status_str(Status status, char* str); 237 | static void time_pt_class_to_struct(time_point_t tp, TimePt& time_pt); 238 | static void extract_time_point(time_point_t tp, int& y, int& m, int& d, int& hr, 239 | int& min, int& sec, int& ms, int& us, int& ns) noexcept; 240 | 241 | private: 242 | WSADATA wsa; 243 | struct sockaddr_in si_addr; 244 | int s, slen; 245 | char ans[NTP_PACKET_LEN]; 246 | char msg[NTP_PACKET_LEN]; 247 | char host[STR_MAX_SIZE]; 248 | Packet* packet; 249 | 250 | enum Status init(const char* hostname); 251 | enum Status query(); 252 | enum Status set_win_clock(time_point_t tm); 253 | 254 | double offset_ns = 0; 255 | double delay_ns = 0; 256 | time_point_t time; 257 | double jitter_ns = 0; 258 | double delay_sum_ns = 0; 259 | double prev_delay = 0; 260 | 261 | double delay_ringbuff [JITTER_WINDOW]; 262 | int ringbuff_front = 0; 263 | int ringbuff_count = 0; 264 | }; 265 | 266 | const char status_s[9][50] = { "OK", "Unknown Error", "Init Winsock Err", "Create Socket Err", "Tx Message Err", 267 | "Rx Msg Err", "Rx Msg Timeout", "Set Win Time Err", "Admin Rights Needed" }; 268 | }}} 269 | #endif 270 | #endif -------------------------------------------------------------------------------- /src/ntp_client_shared/ntp_client_shared.vcxitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {ce1844d1-f6f4-40d9-85b6-530a3857450c} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/ntp_client_shared/ntp_client_shared.vcxitems.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {8f57f7e7-808d-437c-a760-142626c95e3c} 6 | 7 | 8 | {99f3c7bb-1713-4a6c-ab6e-0b9e53c5d0fd} 9 | 10 | 11 | {f4f4744f-b25e-4bfc-b6e4-6d1976d37e96} 12 | 13 | 14 | 15 | 16 | include 17 | 18 | 19 | 20 | 21 | src 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ntp_client_shared/src/ntp_client.cpp: -------------------------------------------------------------------------------- 1 | /************************************** 2 | * Author: Jakub Parez 3 | * File: ntp_client.cpp 4 | * Project: NTP client 5 | * Company: CTU/VIN 6 | * Date: 2020/4/19 10:32 7 | * License: MIT 8 | ***************************************/ 9 | 10 | #if defined(_MSC_VER) 11 | #define WIN32_LEAN_AND_MEAN 12 | #include 13 | #include 14 | #ifdef _WIN32_WINNT 15 | #undef _WIN32_WINNT 16 | #endif 17 | #define _WIN32_WINNT 0x0601 // Windows 7 and higher 18 | #include 19 | //#define Interface __interface 20 | //#define CDECL __cdecl 21 | //#define PACKED_STRUCT(name) __pragma(pack(push, 1)) struct name __pragma(pack(pop)) 22 | #else 23 | #error Unknown / unsupported platform 24 | #endif 25 | 26 | //Ws2_32.lib 27 | //Mswsock.lib 28 | //AdvApi32.lib 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "..\include\ntp_client.h" 38 | 39 | 40 | #if defined(WIN32) 41 | BOOL WINAPIV DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 42 | { 43 | // Perform actions based on the reason for calling. 44 | switch (ul_reason_for_call) 45 | { 46 | case DLL_PROCESS_ATTACH: 47 | // Initialize once for each new process. 48 | // Return FALSE to fail DLL load. 49 | break; 50 | 51 | case DLL_THREAD_ATTACH: 52 | // Do thread-specific initialization. 53 | break; 54 | 55 | case DLL_THREAD_DETACH: 56 | // Do thread-specific cleanup. 57 | break; 58 | 59 | case DLL_PROCESS_DETACH: 60 | // Perform any necessary cleanup. 61 | break; 62 | } 63 | return TRUE; 64 | } 65 | #endif 66 | 67 | 68 | namespace CTU { namespace VIN { namespace NTP_client 69 | { 70 | /* Exported DLL functions - instance */ 71 | 72 | extern "C" EXPORT HNTP CDECL Client__create(void) 73 | { 74 | return reinterpret_cast(new Client()); 75 | } 76 | 77 | extern "C" EXPORT void CDECL Client__close(HNTP self) 78 | { 79 | delete reinterpret_cast(self); 80 | } 81 | 82 | extern "C" EXPORT enum Status CDECL Client__query(HNTP self, const char* hostname, struct Result** result_out) 83 | { 84 | ResultEx* result = nullptr; 85 | *result_out = new Result(); 86 | 87 | Status ret = reinterpret_cast(self)->query(hostname, &result); 88 | 89 | if (result != nullptr) 90 | { 91 | (*result_out)->mtr = result->mtr; 92 | Client::time_pt_class_to_struct(result->time, (*result_out)->time); 93 | delete result; 94 | } 95 | return ret; 96 | } 97 | 98 | extern "C" EXPORT enum Status CDECL Client__query_and_sync(HNTP self, const char* hostname, struct Result** result_out) 99 | { 100 | ResultEx* result = nullptr; 101 | *result_out = new Result(); 102 | 103 | Status ret = reinterpret_cast(self)->query_and_sync(hostname, &result); 104 | 105 | if (result != nullptr) 106 | { 107 | (*result_out)->mtr = result->mtr; 108 | Client::time_pt_class_to_struct(result->time, (*result_out)->time); 109 | delete result; 110 | } 111 | return ret; 112 | } 113 | 114 | /* Exported DLL functions - static */ 115 | 116 | extern "C" EXPORT void CDECL Client__format_info_str(struct Result* result, char* str_out) 117 | { 118 | Client::format_info_str(result, str_out); 119 | } 120 | 121 | extern "C" EXPORT void CDECL Client__get_status_str(enum Status status, char* str_out) 122 | { 123 | Client::get_status_str(status, str_out); 124 | } 125 | 126 | extern "C" EXPORT void CDECL Client__free_result(struct Result* result) 127 | { 128 | if (result != NULL) 129 | delete result; 130 | } 131 | 132 | /* Public Instance Methods */ 133 | 134 | Client::Client() 135 | { 136 | this->packet = new Packet(); 137 | this->delay_sum_ns = 0; 138 | this->prev_delay = 0; 139 | } 140 | 141 | Client::~Client() 142 | { 143 | delete this->packet; 144 | } 145 | 146 | Status Client::query(const char* hostname, ResultEx** result_out) 147 | { 148 | assert(hostname != NULL && strlen(hostname) > 0); 149 | 150 | try 151 | { 152 | // if hostname changed, reinit 153 | if (strcmp(this->host, hostname) != 0) 154 | { 155 | Status ret1 = this->init(hostname); 156 | strncpy_s(this->host, hostname, strlen(hostname)); 157 | printf("Server: %s\n", this->host); 158 | 159 | if (ret1 != Status::OK) 160 | return ret1; 161 | } 162 | 163 | // start meas time 164 | //auto t1 = std::chrono::high_resolution_clock::now(); 165 | 166 | // NTP server query 167 | Status ret2 = this->query(); 168 | 169 | // stop meas time 170 | //auto t2 = std::chrono::high_resolution_clock::now(); 171 | 172 | if (ret2 != Status::OK) 173 | return ret2; 174 | 175 | if (*result_out == nullptr) 176 | *result_out = new ResultEx(); 177 | 178 | // save results 179 | (*result_out)->mtr.delay_ns = this->delay_ns; 180 | (*result_out)->mtr.jitter_ns = this->delay_ns; 181 | (*result_out)->mtr.offset_ns = this->offset_ns; 182 | (*result_out)->time = this->time; 183 | double t_diff = 0; 184 | 185 | // calc jitter 186 | if (this->prev_delay > 0) 187 | { 188 | //double t1_ns = (double)t1.time_since_epoch().count(); 189 | //double t2_ns = (double)t2.time_since_epoch().count(); 190 | //t_diff = (t2_ns - t1_ns); 191 | //double delay_diff = t_diff - this->prev_delay; 192 | double delay_diff = (*result_out)->mtr.delay_ns - this->prev_delay; 193 | if (delay_diff < 0) 194 | delay_diff *= -1; 195 | 196 | double sum = 0; 197 | delay_ringbuff[ringbuff_front] = delay_diff; 198 | 199 | if (ringbuff_front < JITTER_WINDOW - 1) 200 | ringbuff_front++; 201 | else 202 | ringbuff_front = 0; 203 | 204 | if (ringbuff_count < JITTER_WINDOW) 205 | ringbuff_count++; 206 | 207 | for (int i = 0; i < ringbuff_count; i++) 208 | sum += delay_ringbuff[i]; 209 | 210 | this->jitter_ns = sum / ringbuff_count; 211 | } 212 | 213 | (*result_out)->mtr.jitter_ns = this->jitter_ns; 214 | (*result_out)->mtr.delta_ns = this->delay_ns + this->offset_ns; 215 | this->prev_delay = (*result_out)->mtr.delay_ns; // t_diff 216 | 217 | return ret2; 218 | } 219 | catch (const std::exception& exc) 220 | { 221 | std::cout << exc.what(); 222 | return Status::UNKNOWN_ERR; 223 | } 224 | } 225 | 226 | Status Client::query_and_sync(const char* hostname, ResultEx** result_out) 227 | { 228 | Status ret1 = this->query(hostname, result_out); 229 | 230 | if (ret1 != Status::OK) 231 | return ret1; 232 | 233 | return this->set_win_clock(this->time); 234 | } 235 | 236 | /* Public Static Methods */ 237 | 238 | void Client::time_pt_class_to_struct(time_point_t tp, TimePt& time_pt) 239 | { 240 | int y, m, d, h, mm, s, ms, us, ns; 241 | Client::extract_time_point(tp, y, m, d, h, mm, s, ms, us, ns); 242 | 243 | time_pt.tm_nsec = ns; 244 | time_pt.tm_usec = us; 245 | time_pt.tm_msec = ms; 246 | time_pt.tm_sec = s; 247 | time_pt.tm_min = mm; 248 | time_pt.tm_hour = h; 249 | time_pt.tm_mday = d; 250 | time_pt.tm_mon = m; 251 | time_pt.tm_year = y; 252 | } 253 | 254 | void Client::extract_time_point(time_point_t tp, int& y, int& m, int& d, int& hr, int& min, int& sec, int& ms, int& us, int& ns) noexcept 255 | { 256 | time_t tt = std::chrono::duration_cast(tp.time_since_epoch()).count(); 257 | tm local_tm; 258 | localtime_s(&local_tm , &tt); 259 | 260 | y = local_tm.tm_year + 1900; 261 | m = local_tm.tm_mon + 1; 262 | d = local_tm.tm_mday; 263 | hr = local_tm.tm_hour; 264 | min = local_tm.tm_min; 265 | sec = local_tm.tm_sec; 266 | 267 | auto nanosec = std::chrono::duration_cast(tp.time_since_epoch()).count() - (tt * 1000000000); 268 | ms = (int)(nanosec / 1000000); 269 | nanosec -= ms * 1000000; 270 | us = (int)(nanosec / 1000); 271 | nanosec -= us * 1000; 272 | ns = (int)(nanosec); 273 | } 274 | 275 | void Client::format_info_str(Result* result, char* str) 276 | { 277 | if (result != nullptr) 278 | { 279 | int y, m, d, h, mm, s, ms, us, ns; 280 | y = result->time.tm_year; 281 | m = result->time.tm_mon; 282 | d = result->time.tm_mday; 283 | h = result->time.tm_hour; 284 | mm = result->time.tm_min; 285 | s = result->time.tm_sec; 286 | ms = result->time.tm_msec; 287 | us = result->time.tm_usec; 288 | ns = result->time.tm_nsec; 289 | 290 | char time_str[200]; 291 | char offset_str[50]; 292 | char delay_str[50]; 293 | char jitter_str[50]; 294 | char delta_str[50]; 295 | 296 | sprintf(time_str, "Time: %u/%02u/%02u %02u:%02u:%02u [%03u %03u %03u]\n", y, m, d, h, mm, s, ms, us, ns); 297 | sprintf(offset_str, "Offset: %.6f ms\n", result->mtr.offset_ns / 1000000.0); 298 | sprintf(delay_str, "Delay: %.6f ms\n", result->mtr.delay_ns / 1000000.0); 299 | sprintf(jitter_str, "Jitter: %.6f ms\n", result->mtr.jitter_ns / 1000000.0); 300 | sprintf(delta_str, "Delta: %.6f ms\n", (result->mtr.offset_ns + result->mtr.delay_ns) / 1000000.0); 301 | sprintf(str, "%s%s%s%s%s", time_str, offset_str, delay_str, jitter_str, delta_str); 302 | } 303 | } 304 | 305 | void Client::format_info_str(ResultEx* result, char* str) 306 | { 307 | if (result != nullptr) 308 | { 309 | Result res; 310 | Client::time_pt_class_to_struct(result->time, res.time); 311 | Client::format_info_str(&res, str); 312 | } 313 | } 314 | 315 | void Client::get_status_str(Status status, char* str) 316 | { 317 | auto s = (unsigned int)status; 318 | if (s >= 0 && s <= 8) 319 | strcpy(str, status_s[s]); 320 | } 321 | 322 | /* Private Methods */ 323 | 324 | Status Client::init(const char* hostname) 325 | { 326 | this->slen = sizeof(this->si_addr); 327 | 328 | //Initialise winsock 329 | //printf(" \nInitialising Winsock... & quot;); 330 | if (WSAStartup(MAKEWORD(2, 2), &this->wsa) != 0) 331 | { 332 | //printf(" Failed.Error Code : % d & quot; , WSAGetLastError()); 333 | return Status::INIT_WINSOCK_ERR; 334 | } 335 | //printf(" Initialised.\n & quot;); 336 | 337 | //create socket 338 | if ((this->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR) 339 | { 340 | //printf(" socket() failed with error code : % d & quot;, WSAGetLastError()); 341 | return Status::CREATE_SOCKET_ERR; 342 | } 343 | 344 | //setup address structure 345 | memset((char*)&this->si_addr, 0, sizeof(si_addr)); 346 | si_addr.sin_family = AF_INET; 347 | si_addr.sin_port = htons(UDP_PORT); 348 | InetPtonA(AF_INET, hostname, &(si_addr.sin_addr)); 349 | 350 | int rx_timeout = RX_TIMEOUT; 351 | setsockopt(this->s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&rx_timeout, sizeof(rx_timeout)); 352 | 353 | return Status::OK; 354 | } 355 | 356 | Status Client::query() 357 | { 358 | memset(this->packet, '\0', NTP_PACKET_LEN); 359 | memset(this->ans, '\0', NTP_PACKET_LEN); 360 | 361 | this->packet->li_vn_mode = 227; // 11100011 (client mode + NTPv4) 362 | this->packet->stratum = 0; // Stratum level of the local clock 363 | this->packet->poll = 4; // Maximum interval between successive messages 364 | this->packet->precision = (uint8_t)-10; // Precision of the local clock (expressed in power of 2, -10 means 2-10, that is to say 1/1024=0.97ms) 365 | this->packet->rootDelay = 256; // Total round trip delay time 366 | this->packet->rootDispersion = 256; // Max error aloud from primary clock source 367 | 368 | memcpy(this->msg, this->packet, NTP_PACKET_LEN); 369 | 370 | //send the message 371 | time_point_t t1 = std::chrono::time_point_cast(std::chrono::system_clock::now()); 372 | auto t1_b = std::chrono::high_resolution_clock::now(); 373 | 374 | if (sendto(this->s, this->msg, NTP_PACKET_LEN, 0, (struct sockaddr*) &this->si_addr, this->slen) == SOCKET_ERROR) 375 | { 376 | //printf(" sendto() failed with error code : % d & quot;, WSAGetLastError()); 377 | return Status::SEND_MSG_ERR; 378 | } 379 | 380 | // receive message 381 | if (recvfrom(this->s, this->ans, NTP_PACKET_LEN, 0, (struct sockaddr*) &this->si_addr, &this->slen) == SOCKET_ERROR) 382 | { 383 | //printf(" recvfrom() failed with error code : % d & quot;, WSAGetLastError()); 384 | if (WSAGetLastError() == WSAETIMEDOUT) 385 | return Status::RECEIVE_MSG_TIMEOUT; 386 | return Status::RECEIVE_MSG_ERR; 387 | } 388 | time_point_t t4 = std::chrono::time_point_cast(std::chrono::system_clock::now()); 389 | auto t4_b = std::chrono::high_resolution_clock::now(); 390 | 391 | memcpy(this->packet, this->ans, NTP_PACKET_LEN); 392 | 393 | this->packet->txTm_s = ntohl(this->packet->txTm_s); 394 | this->packet->txTm_f = ntohl(this->packet->txTm_f); 395 | 396 | this->packet->rxTm_s = ntohl(this->packet->rxTm_s); 397 | this->packet->rxTm_f = ntohl(this->packet->rxTm_f); 398 | 399 | uint32_t txTm = this->packet->txTm_s - NTP_TS_DELTA; // seconds from 1970 400 | uint32_t rxTm = this->packet->rxTm_s - NTP_TS_DELTA; 401 | 402 | double t2_ns = (double)txTm * 1000000000; // nanoseconds from 1970 403 | double t3_ns = (double)rxTm * 1000000000; 404 | 405 | t2_ns += ((double)this->packet->txTm_f / 4294967295) * 1000000000; // add fraction 406 | t3_ns += ((double)this->packet->rxTm_f / 4294967295) * 1000000000; // 0x100000000ULL = 4294967295 407 | 408 | double t1_ns = (double)std::chrono::duration_cast(t1.time_since_epoch()).count(); // nanoseconds from 1970 409 | double t4_ns = (double)std::chrono::duration_cast(t4.time_since_epoch()).count(); 410 | 411 | double t1_b_ns = (double)t1_b.time_since_epoch().count(); // nanoseconds from start measuring 412 | double t4_b_ns = (double)t4_b.time_since_epoch().count(); 413 | 414 | this->offset_ns = ((t2_ns - t1_ns) + (t3_ns - t4_ns)) / 2; 415 | this->delay_ns = (t4_b_ns - t1_b_ns) - (t3_ns - t2_ns); 416 | this->time = t4 + std::chrono::nanoseconds((long long)(offset_ns + delay_ns)); 417 | 418 | return Status::OK; 419 | } 420 | 421 | Status Client::set_win_clock(time_point_t tm) // sysinfoapi.h 422 | { 423 | SYSTEMTIME st; 424 | //GetSystemTime(>); 425 | 426 | int y, m, d, h, mm, sec, ms, us, ns; 427 | Client::extract_time_point(tm, y, m, d, h, mm, sec, ms, us, ns); 428 | 429 | st.wYear = (WORD)y; 430 | st.wMonth = (WORD)m; 431 | st.wDay = (WORD)d; 432 | st.wHour = (WORD)h; 433 | st.wMinute = (WORD)mm; 434 | st.wSecond = (WORD)sec; 435 | st.wMilliseconds = (WORD)ms; 436 | 437 | auto ret = SetLocalTime(&st); 438 | 439 | if (ret) 440 | { 441 | return Status::OK; 442 | } 443 | else 444 | { 445 | auto err = GetLastError(); 446 | if (err == 1314) 447 | return Status::ADMIN_RIGHTS_NEEDED; 448 | else 449 | return Status::SET_WIN_TIME_ERR; 450 | } 451 | } 452 | }}} --------------------------------------------------------------------------------