📄 pdu.asm
字号:
inc r22 ; increment char counter
rcall PDUReadOctet ; r17 = PID
tst r16 ; test for error during PDUReadOctet
brne SD_to ; if r16!=0 goto error
rcall PDUReadOctet ; r17 = DCS (Coding Scheme)
tst r16 ; test for error during PDUReadOctet
brne SD_to ; if r16!=0 goto error
; test for 8-Bit Alphabet - it's not supported
sbrs r17,(1<<2) ; skip if bit is set
;rjmp SD_to ;;; TODO: jump of 8-Bit Alphabet
; skip the 7 time octets (Y M D H M Sc TZ)
ldi r18,7
SD_TM_L1:
rcall PDUReadOctet
tst r16
brne SD_to
dec r18
tst r18
brne SD_TM_L1
rcall PDUReadOctet ; r17 = UDL User Data Length
tst r16 ; test for error during PDUReadOctet
brne SD_to ; if r16!=0 goto error
mov r18,r17 ; store UDL in r18
;;;mov r16,r17
;;;rcall ModemSendItoA ; dbg
; and now - the funny part...
; r16 = error flag
; r18 = i=udl = counter
clr r20 ; r20 = bit=0;
clr r21 ; r21 = avail=0;
ser r17 ; r17 = stream
; r19 = out
clr r6 ; store carry in bit 0 of r6 -> carry=0;
clr r22 ; character counter
SD_decl2:
tst r21
brne SD_decl3 ; if (avail!=0) goto decl3;
; if (hl=='\0') goto exit;
; hh=pdu[cnt++];
; hl=pdu[cnt++];
rcall PDUReadOctet ; r17 = stream=octet2int(hh,hl);
tst r16 ; test for error during PDUReadOctet
brne SD_to ; if r16!=0 goto error
ldi r21,8 ; avail=8;
SD_decl3:
ror r6 ; restore carry
ror r17 ; ROR(&stream,&carry);
ror r19 ; ROR(&out,&carry);
rol r6 ; store carry
dec r21 ; avail--;
inc r20 ; bit++;
cpi r20,7 ; if (bit<7) goto decl4;
brlo SD_decl4
ror r6 ; restore carry
clc ; carry=0;
ror r19 ; rotate right through carry - ROR(&out,&carry);
rol r6 ; store carry
cpi r22,SMSPARSEMAXLEN-1
breq SD_skipstore
st Y+,r19 ; printf("%c",out);
inc r22 ; inc char - counter
SD_skipstore:
clr r19 ; out=0;
clr r20 ; bit=0;
dec r18 ; i--;
tst r18
breq SD_P_End ; if (i==0) goto exit;
SD_decl4:
rjmp SD_decl2 ; goto decl2;
SD_P_End:
ldi r20,$00 ; success return value
rjmp SD_end
SD_to:
ldi r20,$01
SD_end:
; store terminating null to string
ldi r16,$00
st Y,r16
pop YH
pop YL
pop r22
pop r21
pop r19
pop r18
pop r17
pop r16
pop r6
ret
;-----------------------------------------------------------
; SMSParse
;-----------------------------------------------------------
; Reads the answer from AT+CMGR
;
; Input
; Y-Registers: Point to SRAM-Area with at least SMSPARSMAXCHAR
; bytes
;
; Output:
; r20 = 0 success or !=0 if error
; *Y=<sendernumber>\t<message>\0
;
; Answer is: +CMGR:<stat>,<data>,<len>$0D$A
; <stat>=0 means new or unread Message
; if len!=0 followed by the PDU
; all followed by $0D$0A and again $0D$0A
; last OK$0D$0A
SMSParse:
push r16
push r17
push r19
push YL
push YH
; skip to character after ':' from "+CMGR:"
ldi r16,':'
call ModemUartWaitChar
cpi r20,$01
brne SMSP_Error
; read <stat>
; ATOI reads the ',' after the last digit of <stat>
call ModemReadATOI ; read message <stat>
;;; rcall ModemSendItoA ; dbg - echo
; stat=0 indicates unread or empty message
cpi r16,$00
brne SMSP_End ; jump to return if stat != 0
; skip <data> field
ldi r16,','
call ModemUartWaitChar
cpi r20,$01
brne SMSP_Error
; read the message length
; ATOI reads the $0D after the last digit <len>
call ModemReadATOI ; read message <len>
;;; rcall ModemSendItoA ; dbg
; check for empty message
cpi r16,$00
breq SMSP_END ; yes - no further parsing
; read message pdu data
; skip to $0A character (after the <len>$0D)
ldi r16,$0A
call ModemUartWaitChar
cpi r20,$01
brne SMSP_Error ; jump to return if timeouted
rcall SMSDecodePDUtoRAM ; reads PDU from UART to RAM at Y, error-code in r20
rjmp SMSP_End
SMSP_Error:
ldi r20,$01
SMSP_End:
pop YH
pop YL
pop r19
pop r17
pop r16
ret
;-----------------------------------------------------------
; SMSProcessUnread
;-----------------------------------------------------------
; Reads SMSes from the Mobile Device Storage
; if message is marked unread (=new message) messages
; gets parsed, all messages are deleted from ME storage
; after processing to free memory for new messages
;
; Output:
; r20 - Result Code (not impl.)
;
; Command to read a Message: AT+CMGR=<idx> where idx=1..CMGRMAXIDX
; on Siemens TC35
SMSProcessUnread:
push r16
push r17
push r20
push YL
push YH
push ZL
push ZH
ldi r17,$01
call ModemUartFlush ; flush the UART Read-Buffer
rcall SMSSetPDUMode ; set to SMS Format to PDU Mode
SMSPU_L1:
; send Read Command "at+cgmr="
ldi ZL,LOW(2*GSM_CMGR)
ldi ZH,HIGH(2*GSM_CMGR)
call ModemSendCmdFlash
mov r16,r17 ; copy Message Index
call ModemSendItoA ; send Message Index in ME-Memory as ASCII
ldi r16,$0D
rcall PDUUartSendByte ; send <CR> 0x0d '\r'
ldi YL,LOW(SMSWorkArea)
ldi YH,HIGH(SMSWorkArea)
rcall SMSParse ; Read and Parse Answer PDU
;;rcall MenuUartSendRamSeq ; dbg
tst r20 ; return of 0 in r20 indicates success
brne SMS_PU_FAIL ; branch if failed
rcall SMSProcessMsg ; call the function that processes
; the parsing-result at Y (Number\nMessage\0)
; rcall ModemUartFlush ; flush the UART
SMS_PU_FAIL:
call ModemUartWaitOK ; Wait for "OK" from modem
; delete the Message from ME-Memory
; send Delete Command "at+cmgd="
ldi ZL,LOW(2*GSM_CMGD)
ldi ZH,HIGH(2*GSM_CMGD)
call ModemSendCmdFlash
; send Message Index in ME-Memory
mov r16,r17
call ModemSendItoA
; send <CR> 0x0d '\r'
ldi r16,$0D
rcall PDUUartSendByte
call ModemUartWaitOK
call ModemUartFlush ; flush the UART
lds r16,SMSReq ; test if something is to be done
tst r16
brne SMSPU_End ; break loop
inc r17
cpi r17,CMGRMAXIDX+1
brlo SMSPU_L1
SMSPU_End:
pop ZH
pop ZL
pop YH
pop YL
pop r20
pop r17
pop r16
ret
; Read SMS from ME Storage
GSM_CMGR:
.db "AT+CMGR=",$00,$00
; Delete SMS in ME Storage
GSM_CMGD:
.db "AT+CMGD=",$00,$00
;--------------------------------------------------------
; SMSCheckCodeInEEprom
; Checks it the fist byte in EEProm at postion
; EEPASSCODE is a $FF (Chip-Erase EEprom content)
; and if empty set to a default Passcode located at
; label SMSDEFAULTCODE in program flash memory
SMSCheckCodeInEEprom:
push r16
push r24
push r25
push ZL
push ZH
ldi r24,LOW(EEPASSCODE) ; r25:r24 Pointer to Passcode in
ldi r25,HIGH(EEPASSCODE) ; EEPROM
call EEReadByte ; load first char of code
cpi r16,$FF ; compare with $FF (empty)
brne SMSCC_end ; not $FF -> branch
ldi ZL,LOW(2*SMSDEFAULTCODE) ; load address of
ldi ZH,HIGH(2*SMSDEFAULTCODE) ; default code
cli
call EEWriteSeqFromFlash ; copy Flash Z to EEprom r25:r24
sei
SMSCC_end:
pop ZH
pop ZL
pop r25
pop r24
pop r16
ret
SMSDEFAULTCODE:
.db "9999",$00,$00
;=========================================
; EEPROM Labels for PASSCODE
.eseg
EEPassCode: .byte 6
.cseg
;--------------------------------------------------------
; SMSProcessMsg
; Process the Message Stored in Y
; Format Number\rMessage\0
;
; the parese the message for the following
; <code><space><commandchar><space><parameters>
; cchar par partyp does
; S ID char SMSReq="S", SMSRp1=ID as char
; L ID char SMSReq="L", SMSRp1=ID as char
; N ONSw Bit-Mask SMSReq="N", SMSRp1=OnSW as byte
; F OFFSw Bit-Mask SMSReq="F", SMSRp1=OffSW as byte
; A - - SMSReq="T"
; Z - - SMSReq="Z"
; P Pinnumber+1,State SMSReq="P", SMSP1=UpperNibble=Pnum,LN=state 0|1
;
; 1 S = send (S)tatus
; 2 L = (L)og-Level (for sending Status)
; 3 N = Switch o(N) all Pins with 1 in Mask LSB first
; 4 F = Switch o(F)f - " -
; 5 A = Switch (A)ll Pins on
; 6 Z = Switch all Pins off - (Z)ero
; 7 P = Swich one (P)in
SMSProcessMsg:
push r16
push r17
push r18
push r24
push r25
push YL
push YH
;;;; call MenuUartSendRamSeq ;;;; dbg
; out of reach workaround
rjmp SPro_L1
SPro_End2:
jmp SPro_End
SPro_L1:
; skip number and go to Message (after separtor $0D)
ld r16,Y+
cpi r16,$0D
breq SPro_Msg ; found separtor -> goto processing
cpi r16,$00
breq SPro_End2 ; branch if End-Of-String
cpi r16,$FF
breq SPro_End2 ; paranoia
rjmp SPro_L1 ; loop
SPro_Msg:
; check for valid SMS code
ldi r24,LOW(EEPassCode) ; pointer to passcode
ldi r25,HIGH(EEPassCode)
clr r18 ; init counter
SPro_CodeL1:
call EEReadPlus ; read byte from EEprom at r25:r24 in r16
; and increment r25:r24
ld r17,Y+ ; get character from Message
tst r17 ; already end of text?
breq SPro_End2 ; yes - branch
cp r17,r16 ; compare
brne SPro_End2 ; branch if wrong Password
inc r18
cpi r18,$04 ; code is 4 chars long
brne SPro_CodeL1 ; until code processed
ld r17,Y+ ; skip Code/Command separator ($0D)
tst r17
breq SPro_End2
clr r17
sts SMSReq,r17 ; init to "no Request"
sts SMSRp1,r17 ; clear parameter
ld r17,Y+ ; load Command Char
tst r17
breq SPro_End2
; case (r17):
SPro_r1: ; Status
cpi r17,'S'
brne SPro_r2
sts SMSReq,r17
clr r16
sts SMSRp1,r16 ; default to no parameter
ld r17,Y+ ; skip separator
tst r17 ; test for EOL
breq SPRO_End2
ld r17,Y+ ; load parameter
tst r17 ; test for "no parameter"
breq SPro_End
sts SMSRp1,r17 ; store parameter
rjmp SPro_End2 ; break
SPro_r2: ; Log-level
cpi r17,'L'
brne SPro_r3
ld r17,Y+ ; skip separator
tst r17 ; test for EOL
breq SPro_End
ld r17,Y+ ; load parameter
tst r17 ; test for "no parameter"
breq SPro_End
sts SMSRp1,r17 ; store parameter
ldi r16,'L'
sts SMSReq,r16
rjmp SPro_End ; break
SPro_r3: ; oN - Mask
cpi r17,'N'
brne SPro_r4
SPro_r4:
cpi r17,'F' ; oFf - Mask
brne SPro_r5
SPro_r5: ; Set-All
cpi r17,'A'
brne SPro_r6
sts SMSReq,r17
rjmp SPro_End
SPro_r6: ; Zero-All
cpi r17,'Z'
brne SPro_r7
sts SMSReq,r17
rjmp SPro_End
SPro_r7: ; Pin
cpi r17,'P'
brne SPro_r8
ld r17,Y+ ; skip separator
tst r17 ; test for EOL
breq SPro_End
ld r17,Y+ ; load parameter Pin-Number(0-xxx)
tst r17 ; test for "no parameter"
breq SPro_End
subi r17,'0' ; make char to number
andi r17,0b00001111 ; mask parameter > $0F
swap r17 ; put pin-number in upper nibble
ld r16,Y+ ; skip separator ($20)
tst r16 ; test for EOL
breq SPro_End
ld r16,Y+ ; load parameter switch value
tst r16 ; test for "no parameter"
breq SPro_End
subi r16,'0' ; make char to number
andi r16,0b00000001 ; mask
or r17,r16 ; Pin to upper nibble, switch-state to lower
sts SMSRp1,r17 ; store parameter
ldi r17,'P'
sts SMSReq,r17
rjmp SPro_End
SPro_r8:
SPro_End:
;;; call MAINProcRequests ;;; dbg
pop YH
pop YL
pop r25
pop r24
pop r18
pop r17
pop r16
ret
; Process - Flags
.dseg
SMSReq: .byte 1
SMSRp1: .byte 1
.cseg
;--------------------------------------------------------
; SMSDebugProcessMsg
; Test Process copy message from Flash to Ram at Y
; Format Number\nMessage\0
SMSDebugProcessMsg:
push YL
push YH
push ZL
push ZH
ldi ZL,LOW(2*SMSTestMsg) ; source
ldi ZH,HIGH(2*SMSTestMsg)
ldi YL,LOW(SMSWorkArea) ; destination
ldi YH,HIGH(SMSWorkArea)
call EEFlashSeqToRAM ; copy
rcall SMSProcessMsg ; test processing
pop ZH
pop ZL
pop YH
pop YL
ret
SMSTestMsg:
.db "+49171123456",$0D,"9999 P 5 1",$00
;;.db "+49171123456",$0D,"9999 S",$00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -