|
| 1 | +# Parses packets to check for new ackrej format packets |
| 2 | +import re |
| 3 | + |
| 4 | +import logging |
| 5 | + |
| 6 | +log = logging.getLogger(__name__) |
| 7 | + |
| 8 | + |
| 9 | +def parse_ack_rej_msg_id(message: str) -> tuple[str | None, str | None, str | None, str | None]: |
| 10 | + """Parses the "new" (1999) ackrej message format. APRSlib doesn't |
| 11 | + handle it very well |
| 12 | +
|
| 13 | + Args: |
| 14 | + message (str): APRS message text to be parsed. If this text contains |
| 15 | + the new ack/rej message as _sole_ data, then the response_text field |
| 16 | + will be populated with the ack/rej, the message numbers will be assigned |
| 17 | + and the message_text itself will be None. Otherwise, the original |
| 18 | + message text will be returned |
| 19 | +
|
| 20 | + Returns: |
| 21 | + tuple[str, str, str, str]: |
| 22 | + message: str | None - original message text or None if message was an ack/rej |
| 23 | + response: str | None - ack, rej, or None |
| 24 | + sender_message_id: str | None - Sender's message ID or None |
| 25 | + err_message_id: str | None - message id for a message from te bot or None |
| 26 | + """ |
| 27 | + matches = re.search(r"^(ack|rej)(..)}(..)$", message, re.IGNORECASE) |
| 28 | + response = None |
| 29 | + sender_message_id = None |
| 30 | + err_message_id = None |
| 31 | + if matches: |
| 32 | + response = matches[1] |
| 33 | + sender_message_id = matches[2] |
| 34 | + err_message_id = matches[3] |
| 35 | + message = None |
| 36 | + log.debug("Message: %s response: %s sender_message_id: %s, err_message_id: %s", message, response, sender_message_id, err_message_id) |
| 37 | + return message, response |
| 38 | + |
| 39 | + |
| 40 | +def parse_new_ackrej_format(message: str) -> tuple[str | None, str | None, bool]: |
| 41 | + """ |
| 42 | + Have a look at the incoming APRS message and check if it |
| 43 | + contains a message no which does not follow the APRS |
| 44 | + standard (see aprs101.pdf chapter 14) |
| 45 | +
|
| 46 | + http://www.aprs.org/aprs11/replyacks.txt |
| 47 | +
|
| 48 | + but rather follow the new format |
| 49 | +
|
| 50 | + http://www.aprs.org/aprs11/replyacks.txt |
| 51 | +
|
| 52 | + Parameters |
| 53 | + ========== |
| 54 | + message_text: 'str' |
| 55 | + The original aprs message as originally extracted by aprslib |
| 56 | +
|
| 57 | + Returns |
| 58 | + ======= |
| 59 | + msg: 'str' |
| 60 | + original message OR the modified message minus message no and trailing |
| 61 | + data |
| 62 | + msg_no: 'str' |
| 63 | + Null if no message_no was present |
| 64 | + new_ackrej_format: 'bool' |
| 65 | + True if the ackrej_format has to follow the new ack-rej handling |
| 66 | + process as described in http://www.aprs.org/aprs11/replyacks.txt |
| 67 | + """ |
| 68 | + |
| 69 | + """ |
| 70 | + The following assumptions apply when handling APRS messages in general: |
| 71 | +
|
| 72 | + Option 1: no message ID present: |
| 73 | + send no ACK |
| 74 | + outgoing messages have no msg number attachment |
| 75 | +
|
| 76 | + Example data exchange 1: |
| 77 | + DF1JSL-4>APRS,TCPIP*,qAC,T2PRT::WXBOT :94043 |
| 78 | + WXBOT>APRS,qAS,KI6WJP::DF1JSL-4 :Mountain View CA. Today,Sunny High 60 |
| 79 | +
|
| 80 | + Example data exchange 2: |
| 81 | + DF1JSL-4>APRS,TCPIP*,qAC,T2SPAIN::EMAIL-2 :jsl24469@gmail.com Hallo |
| 82 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :Email sent to jsl24469@gmail.com |
| 83 | +
|
| 84 | +
|
| 85 | + Option 2: old message number format is present: (example: msg{12345) |
| 86 | + Send ack with message number from original message (ack12345) |
| 87 | + All outgoing messages have trailing msg number ( {abcde ); can be numeric or |
| 88 | + slphanumeric counter. See aprs101.pdf chapter 14 |
| 89 | +
|
| 90 | + Example data exchange 1: |
| 91 | + DF1JSL-4>APRS,TCPIP*,qAC,T2SP::EMAIL-2 :jsl24469@gmail.com Hallo{12345 |
| 92 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :ack12345 |
| 93 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :Email sent to jsl24469@gmail.com{891 |
| 94 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::EMAIL-2 :ack891 |
| 95 | +
|
| 96 | + Example data exchange 2: |
| 97 | + DF1JSL-4>APRS,TCPIP*,qAC,T2CSNGRAD::EMAIL-2 :jsl24469@gmail.com{ABCDE |
| 98 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :ackABCDE |
| 99 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :Email sent to jsl24469@gmail.com{893 |
| 100 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::EMAIL-2 :ack893 |
| 101 | +
|
| 102 | +
|
| 103 | + Option 3: new messages with message ID but without trailing retry msg ids: msg{AB} |
| 104 | + Do NOT send extra ack |
| 105 | + All outgoing messages have 2-character msg id, followed by message ID from original message |
| 106 | + Example: |
| 107 | + User sends message "Hello{AB}" to MPAD |
| 108 | + MPAD responds "Message content line 1{DE}AB" to user |
| 109 | + MPAD responds "Message content line 2{DF}AB" to user |
| 110 | +
|
| 111 | + AB -> original message |
| 112 | + DE, DF -> message IDs generated by MPAD |
| 113 | +
|
| 114 | + Example data exchange 1: |
| 115 | + DF1JSL-4>APRS,TCPIP*,qAC,T2NUERNBG::WXBOT :99801{AB} |
| 116 | + WXBOT>APRS,qAS,KI6WJP::DF1JSL-4 :Lemon Creek AK. Today,Scattered Rain/Snow and Patchy Fog 50% High 4{QL}AB |
| 117 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::WXBOT :ackQL}AB |
| 118 | + WXBOT>APRS,qAS,KI6WJP::DF1JSL-4 :0{QM}AB |
| 119 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::WXBOT :ackQM}AB |
| 120 | +
|
| 121 | + Example data exchange 2: |
| 122 | + DF1JSL-4>APRS,TCPIP*,qAC,T2SPAIN::EMAIL-2 :jsl24469@gmail.com Hallo{AB} |
| 123 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :Email sent to jsl24469@gmail.com{OQ}AB |
| 124 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::EMAIL-2 :ackOQ}AB |
| 125 | +
|
| 126 | +
|
| 127 | + Option 4: new messages with message ID and with trailing retry msg ids: msg{AB}CD |
| 128 | + We don't handle retries - therefore, apply option #3 for processing these |
| 129 | + the "CD" part gets omitted and is not used |
| 130 | +
|
| 131 | + Example data exchange 1: |
| 132 | + DF1JSL-4>APRS,TCPIP*,qAC,T2CZECH::WXBOT :99801{LM}AA |
| 133 | + WXBOT>APRS,qAS,KI6WJP::DF1JSL-4 :Lemon Creek AK. Today,Scattered Rain/Snow and Patchy Fog 50% High 4{QP}LM |
| 134 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::WXBOT :ackQP}LM |
| 135 | + WXBOT>APRS,qAS,KI6WJP::DF1JSL-4 :0{QQ}LM |
| 136 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::WXBOT :ackQQ}LM |
| 137 | +
|
| 138 | + Example data exchange 2: |
| 139 | + DF1JSL-4>APRS,TCPIP*,qAC,T2SP::EMAIL-2 :jsl24469@gmail.com Welt{DE}FG |
| 140 | + EMAIL-2>APJIE4,TCPIP*,qAC,AE5PL-JF::DF1JSL-4 :Email sent to jsl24469@gmail.com{OS}DE |
| 141 | + DF1JSL-4>APOSB,TCPIP*,qAS,DF1JSL::EMAIL-2 :ackOS}DE |
| 142 | +
|
| 143 | + """ |
| 144 | + |
| 145 | + msg = msgno = None |
| 146 | + new_ackrej_format = False |
| 147 | + |
| 148 | + # if message text is present, split up between aaaaaa{bb}cc |
| 149 | + # where aaaaaa = message text |
| 150 | + # bb = message number |
| 151 | + # cc = message retry (may or may not be present) |
| 152 | + if message: |
| 153 | + matches = re.search( |
| 154 | + r"^(.*){([a-zA-Z0-9]{2})}(\w*)$", message, re.IGNORECASE |
| 155 | + ) |
| 156 | + if matches: |
| 157 | + try: |
| 158 | + msg = matches[1].rstrip() |
| 159 | + msgno = matches[2] |
| 160 | + new_ackrej_format = True |
| 161 | + except IndexError: |
| 162 | + msg = message |
| 163 | + msgno = None |
| 164 | + new_ackrej_format = False |
| 165 | + else: |
| 166 | + msg = message |
| 167 | + else: |
| 168 | + msg = message |
| 169 | + return msg, msgno, new_ackrej_format |
0 commit comments