2013-12-13 21:24:03 +00:00
|
|
|
; Simple Network Time Protocol implementation - per RFC 2030
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
MAX_SNTP_MESSAGES_SENT = 8
|
|
|
|
|
2018-02-23 15:36:05 +00:00
|
|
|
.include "../inc/common.inc"
|
|
|
|
.include "../inc/error.inc"
|
2013-12-13 21:24:03 +00:00
|
|
|
|
|
|
|
.export sntp_ip
|
|
|
|
.export sntp_utc_timestamp
|
|
|
|
.export sntp_get_time
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
.import ip65_process
|
|
|
|
.import ip65_error
|
|
|
|
|
|
|
|
.import udp_add_listener
|
|
|
|
.import udp_remove_listener
|
|
|
|
|
|
|
|
.import udp_callback
|
|
|
|
.import udp_send
|
|
|
|
|
|
|
|
.import udp_inp
|
|
|
|
.import output_buffer
|
|
|
|
.importzp udp_data
|
|
|
|
|
|
|
|
.import udp_send_dest
|
|
|
|
.import udp_send_src_port
|
|
|
|
.import udp_send_dest_port
|
|
|
|
.import udp_send_len
|
|
|
|
.import check_for_abort_key
|
|
|
|
.import timer_read
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
.data
|
2013-12-27 13:57:56 +00:00
|
|
|
|
|
|
|
sntp_ip: .byte $ff,$ff,$ff,$ff ; can be set to ip address of server that will be queried via sntp (default is a local LAN broadcast)
|
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
|
|
|
|
.bss
|
|
|
|
|
|
|
|
; sntp packet offsets
|
2013-12-27 13:57:56 +00:00
|
|
|
sntp_inp = udp_inp + udp_data
|
2013-12-13 21:24:03 +00:00
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
sntp_server_port = 123
|
|
|
|
sntp_client_port = 123
|
2013-12-13 21:24:03 +00:00
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
sntp_utc_timestamp: .res 4 ; will be set to seconds (only) part of utc timestamp (seconds since 00:00 on Jan 1, 1900)
|
2013-12-13 21:24:03 +00:00
|
|
|
|
|
|
|
; sntp state machine
|
2013-12-27 13:57:56 +00:00
|
|
|
sntp_initializing = 1 ; initial state
|
|
|
|
sntp_query_sent = 2 ; sent a query, waiting for a response
|
|
|
|
sntp_completed = 3 ; got a good response
|
2013-12-13 21:24:03 +00:00
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
sntp_timer: .res 1
|
|
|
|
sntp_loop_count: .res 1
|
2013-12-13 21:24:03 +00:00
|
|
|
sntp_break_polling_loop: .res 1
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
sntp_state: .res 1
|
|
|
|
sntp_message_sent_count: .res 1
|
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
|
|
|
|
.code
|
|
|
|
|
|
|
|
; query an sntp server for current UTC time
|
|
|
|
; inputs:
|
2013-12-27 13:57:56 +00:00
|
|
|
; sntp_ip must point to an SNTP server
|
|
|
|
; outputs:
|
|
|
|
; carry flag is set if there was an error, clear otherwise
|
|
|
|
; sntp_utc_timestamp: set to the number of seconds (seconds since 00:00 on Jan 1, 1900) - timezone is UTC
|
|
|
|
sntp_get_time:
|
2013-12-13 21:24:03 +00:00
|
|
|
ldax #sntp_in
|
2013-12-27 13:57:56 +00:00
|
|
|
stax udp_callback
|
2013-12-13 21:24:03 +00:00
|
|
|
ldax #sntp_client_port
|
2013-12-27 13:57:56 +00:00
|
|
|
jsr udp_add_listener
|
|
|
|
bcc :+
|
|
|
|
rts
|
|
|
|
: lda #sntp_initializing
|
2013-12-13 21:24:03 +00:00
|
|
|
sta sntp_state
|
2013-12-27 13:57:56 +00:00
|
|
|
lda #0 ; reset the "message sent" counter
|
2013-12-13 21:24:03 +00:00
|
|
|
sta sntp_message_sent_count
|
|
|
|
jsr send_sntp_query
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
@sntp_polling_loop:
|
|
|
|
lda sntp_message_sent_count
|
2013-12-27 13:57:56 +00:00
|
|
|
adc #10
|
|
|
|
sta sntp_loop_count
|
|
|
|
@outer_delay_loop:
|
2013-12-13 21:24:03 +00:00
|
|
|
lda #0
|
|
|
|
sta sntp_break_polling_loop
|
|
|
|
jsr timer_read
|
2013-12-27 13:57:56 +00:00
|
|
|
stx sntp_timer ; we only care about the high byte
|
|
|
|
|
|
|
|
@inner_delay_loop:
|
2013-12-13 21:24:03 +00:00
|
|
|
jsr ip65_process
|
|
|
|
jsr check_for_abort_key
|
|
|
|
bcc @no_abort
|
2018-02-23 15:41:33 +00:00
|
|
|
lda #IP65_ERROR_ABORTED_BY_USER
|
2013-12-13 21:24:03 +00:00
|
|
|
sta ip65_error
|
|
|
|
rts
|
2013-12-27 13:57:56 +00:00
|
|
|
@no_abort:
|
2013-12-13 21:24:03 +00:00
|
|
|
lda sntp_state
|
|
|
|
cmp #sntp_completed
|
|
|
|
beq @complete
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
lda sntp_break_polling_loop
|
|
|
|
bne @break_polling_loop
|
|
|
|
jsr timer_read
|
2013-12-27 13:57:56 +00:00
|
|
|
cpx sntp_timer ; this will tick over after about 1/4 of a second
|
2013-12-13 21:24:03 +00:00
|
|
|
beq @inner_delay_loop
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
dec sntp_loop_count
|
2013-12-27 13:57:56 +00:00
|
|
|
bne @outer_delay_loop
|
2013-12-13 21:24:03 +00:00
|
|
|
|
|
|
|
@break_polling_loop:
|
2013-12-27 13:57:56 +00:00
|
|
|
jsr send_sntp_query
|
2013-12-13 21:24:03 +00:00
|
|
|
inc sntp_message_sent_count
|
|
|
|
lda sntp_message_sent_count
|
|
|
|
cmp #MAX_SNTP_MESSAGES_SENT-1
|
|
|
|
bpl @too_many_messages_sent
|
|
|
|
jmp @sntp_polling_loop
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
@complete:
|
|
|
|
ldax #sntp_client_port
|
|
|
|
jsr udp_remove_listener
|
2013-12-13 21:24:03 +00:00
|
|
|
rts
|
|
|
|
|
|
|
|
@too_many_messages_sent:
|
|
|
|
@failed:
|
|
|
|
ldax #sntp_client_port
|
|
|
|
jsr udp_remove_listener
|
2018-02-23 15:41:33 +00:00
|
|
|
lda #IP65_ERROR_TIMEOUT_ON_RECEIVE
|
2013-12-27 13:57:56 +00:00
|
|
|
sta ip65_error
|
|
|
|
sec ; signal an error
|
2013-12-13 21:24:03 +00:00
|
|
|
rts
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
send_sntp_query:
|
|
|
|
; make a zero filled buffer
|
2013-12-13 21:24:03 +00:00
|
|
|
lda #$0
|
|
|
|
ldx #$30
|
|
|
|
stx udp_send_len
|
|
|
|
sta udp_send_len+1
|
2013-12-27 13:57:56 +00:00
|
|
|
: sta output_buffer,x
|
2013-12-13 21:24:03 +00:00
|
|
|
dex
|
|
|
|
bpl :-
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
; set the flags field
|
|
|
|
lda #$E3 ; flags - LI=11 (unknown), VN=100 (4), MODE=011 (client)
|
2013-12-13 21:24:03 +00:00
|
|
|
sta output_buffer
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
ldax #sntp_client_port
|
|
|
|
stax udp_send_src_port
|
|
|
|
ldax #sntp_server_port
|
|
|
|
stax udp_send_dest_port
|
2013-12-27 13:57:56 +00:00
|
|
|
ldx #3 ; set destination address
|
2013-12-13 21:24:03 +00:00
|
|
|
: lda sntp_ip,x
|
|
|
|
sta udp_send_dest,x
|
|
|
|
dex
|
|
|
|
bpl :-
|
|
|
|
|
|
|
|
ldax #output_buffer
|
2013-12-27 13:57:56 +00:00
|
|
|
jsr udp_send
|
2013-12-13 21:24:03 +00:00
|
|
|
bcs @error_on_send
|
|
|
|
lda #sntp_query_sent
|
|
|
|
sta sntp_state
|
2013-12-27 13:57:56 +00:00
|
|
|
@error_on_send:
|
2013-12-13 21:24:03 +00:00
|
|
|
rts
|
|
|
|
|
|
|
|
sntp_in:
|
|
|
|
ldx #3
|
|
|
|
ldy #0
|
2013-12-27 13:57:56 +00:00
|
|
|
: lda sntp_inp+$28,x ; the 'transmit' timestamp (in big end order)
|
2013-12-13 21:24:03 +00:00
|
|
|
sta sntp_utc_timestamp,y
|
|
|
|
iny
|
|
|
|
dex
|
|
|
|
bpl :-
|
2013-12-27 13:57:56 +00:00
|
|
|
|
2013-12-13 21:24:03 +00:00
|
|
|
inc sntp_break_polling_loop
|
|
|
|
lda #sntp_completed
|
2013-12-27 13:57:56 +00:00
|
|
|
sta sntp_state
|
2013-12-13 21:24:03 +00:00
|
|
|
rts
|
|
|
|
|
|
|
|
|
2013-12-27 13:57:56 +00:00
|
|
|
|
|
|
|
; -- LICENSE FOR sntp.s --
|
2013-12-13 21:24:03 +00:00
|
|
|
; The contents of this file are subject to the Mozilla Public License
|
|
|
|
; Version 1.1 (the "License"); you may not use this file except in
|
|
|
|
; compliance with the License. You may obtain a copy of the License at
|
|
|
|
; http://www.mozilla.org/MPL/
|
2013-12-27 13:57:56 +00:00
|
|
|
;
|
2013-12-13 21:24:03 +00:00
|
|
|
; Software distributed under the License is distributed on an "AS IS"
|
|
|
|
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
|
|
; License for the specific language governing rights and limitations
|
|
|
|
; under the License.
|
2013-12-27 13:57:56 +00:00
|
|
|
;
|
2013-12-13 21:24:03 +00:00
|
|
|
; The Original Code is ip65.
|
2013-12-27 13:57:56 +00:00
|
|
|
;
|
2013-12-13 21:24:03 +00:00
|
|
|
; The Initial Developer of the Original Code is Jonno Downes,
|
|
|
|
; jonno@jamtronix.com.
|
|
|
|
; Portions created by the Initial Developer are Copyright (C) 2009,2011
|
2013-12-27 13:57:56 +00:00
|
|
|
; Jonno Downes. All Rights Reserved.
|
2013-12-13 21:24:03 +00:00
|
|
|
; -- LICENSE END --
|