emailler/ip65/sntp.s

205 lines
4.5 KiB
ArmAsm
Raw Normal View History

2013-12-13 21:24:03 +00:00
; Simple Network Time Protocol implementation - per RFC 2030
MAX_SNTP_MESSAGES_SENT = 8
2013-12-13 21:24:03 +00:00
.include "../inc/common.i"
2013-12-13 21:24:03 +00:00
.ifndef KPR_API_VERSION_NUMBER
.define EQU =
2013-12-13 21:24:03 +00:00
.include "../inc/kipper_constants.i"
.endif
.export sntp_ip
.export sntp_utc_timestamp
.export sntp_get_time
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-13 21:24:03 +00:00
.data
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
sntp_inp = udp_inp + udp_data
2013-12-13 21:24:03 +00:00
sntp_server_port = 123
sntp_client_port = 123
2013-12-13 21:24:03 +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
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
sntp_timer: .res 1
sntp_loop_count: .res 1
2013-12-13 21:24:03 +00:00
sntp_break_polling_loop: .res 1
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:
; 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
stax udp_callback
2013-12-13 21:24:03 +00:00
ldax #sntp_client_port
jsr udp_add_listener
bcc :+
rts
: lda #sntp_initializing
2013-12-13 21:24:03 +00:00
sta sntp_state
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-13 21:24:03 +00:00
@sntp_polling_loop:
lda sntp_message_sent_count
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
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
lda #KPR_ERROR_ABORTED_BY_USER
sta ip65_error
rts
@no_abort:
2013-12-13 21:24:03 +00:00
lda sntp_state
cmp #sntp_completed
beq @complete
2013-12-13 21:24:03 +00:00
lda sntp_break_polling_loop
bne @break_polling_loop
jsr timer_read
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-13 21:24:03 +00:00
dec sntp_loop_count
bne @outer_delay_loop
2013-12-13 21:24:03 +00:00
@break_polling_loop:
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
@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
lda #KPR_ERROR_TIMEOUT_ON_RECEIVE
sta ip65_error
sec ; signal an error
2013-12-13 21:24:03 +00:00
rts
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
: sta output_buffer,x
2013-12-13 21:24:03 +00:00
dex
bpl :-
; 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-13 21:24:03 +00:00
ldax #sntp_client_port
stax udp_send_src_port
ldax #sntp_server_port
stax udp_send_dest_port
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
jsr udp_send
2013-12-13 21:24:03 +00:00
bcs @error_on_send
lda #sntp_query_sent
sta sntp_state
@error_on_send:
2013-12-13 21:24:03 +00:00
rts
sntp_in:
ldx #3
ldy #0
: 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-13 21:24:03 +00:00
inc sntp_break_polling_loop
lda #sntp_completed
sta sntp_state
2013-12-13 21:24:03 +00:00
rts
; -- 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-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-13 21:24:03 +00:00
; The Original Code is ip65.
;
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
; Jonno Downes. All Rights Reserved.
2013-12-13 21:24:03 +00:00
; -- LICENSE END --