Files
demeter/esp/microcoapy/coap_reader.py

89 lines
2.4 KiB
Python

from . import coap_macros as macros
from .coap_option import CoapOption
def parseOption(packet, runningDelta, buffer, i):
option = CoapOption()
headlen = 1
errorMessage = (False, runningDelta, i)
if buffer is None:
return errorMessage
buflen = len(buffer) - i
if buflen < headlen:
return errorMessage
delta = (buffer[i] & 0xF0) >> 4
length = buffer[i] & 0x0F
if delta == 15 or length == 15:
return errorMessage
if delta == 13:
headlen += 1
if buflen < headlen:
return errorMessage
delta = buffer[i + 1] + 13
i += 1
elif delta == 14:
headlen += 2
if buflen < headlen:
return errorMessage
delta = ((buffer[i + 1] << 8) | buffer[i + 2]) + 269
i += 2
if length == 13:
headlen += 1
if buflen < headlen:
return errorMessage
length = buffer[i + 1] + 13
i += 1
elif length == 14:
headlen += 2
if buflen < headlen:
return errorMessage
length = ((buffer[i + 1] << 8) | buffer[i + 2]) + 269
i += 2
endOfOptionIndex = (i + 1 + length)
if endOfOptionIndex > len(buffer):
return errorMessage
option.number = delta + runningDelta
option.buffer = buffer[i + 1:i + 1 + length]
packet.options.append(option)
return (True, runningDelta + delta, endOfOptionIndex)
def parsePacketHeaderInfo(buffer, packet):
packet.version = (buffer[0] & 0xC0) >> 6
packet.type = (buffer[0] & 0x30) >> 4
packet.tokenLength = buffer[0] & 0x0F
packet.method = buffer[1]
packet.messageid = 0xFF00 & (buffer[2] << 8)
packet.messageid |= 0x00FF & buffer[3]
def parsePacketOptionsAndPayload(buffer, packet):
bufferLen = len(buffer)
if (macros._COAP_HEADER_SIZE + packet.tokenLength) < bufferLen:
delta = 0
bufferIndex = macros._COAP_HEADER_SIZE + packet.tokenLength
while (len(packet.options) < macros._MAX_OPTION_NUM) and \
(bufferIndex < bufferLen) and \
(buffer[bufferIndex] != 0xFF):
(status, delta, bufferIndex) = parseOption(packet, delta, buffer, bufferIndex)
if status is False:
return False
if ((bufferIndex + 1) < bufferLen) and (buffer[bufferIndex] == 0xFF):
packet.payload = buffer[bufferIndex + 1:]
else:
packet.payload = None
return True