DreamTeam/thinkgear: Difference between revisions

From Noisebridge
Jump to navigation Jump to search
No edit summary
No edit summary
Line 18: Line 18:
   if nextpos < len(buffer) && buffer[nextpos] == syncval:
   if nextpos < len(buffer) && buffer[nextpos] == syncval:
     synced = True
     synced = True
# packet = buffer[syncpos:]  # may or may not yield a complete packet, depending on syncpos and buffer size
# paclen = len(packet)
# assert paclen > 2
# test already done in loop above, this is superfluous
# synced = (syncval == packet[0] == packet[1])
# assert synced


lenpos = syncpos + synclen
lenpos = syncpos + synclen
lenlen = 1
lenlen = 1


# paylen = packet[lenpos]
paylen = buffer[syncpos+2]
paylen = buffer[syncpos+2]
assert paylen < 170  #  note 170 is 0xaa - just coincidentally?
assert paylen < 170  #  note 170 is 0xaa - just coincidentally?
Line 37: Line 28:
# needs rest of expected "paylen" data + checksum from next buffer
# needs rest of expected "paylen" data + checksum from next buffer
expected_len = paylen + 4
expected_len = paylen + 4
lastpos = len(buffer) - 1
if expected_len > lastpos - syncpos:
  # need rest of packet from next buffer
if len(packet) < expected_len:
if len(packet) < expected_len:
   need_len = expected_len - len(packet)
   need_len = expected_len - len(packet)
   buffer = get_next_buffer()
   buffer = get_next_buffer()
   packet.extend(buffer[:needlen])
   packet.extend(buffer[:needlen])

Revision as of 00:44, 30 May 2013


syncval = 0xaa

syncpos = 0
synclen = 2

synced = False
while not synced:
  buffer = get_next_buffer()
  if buffer.count(syncval) < 2:
    continue
  try:
    syncpos = buffer.index(syncval)
  except ValueError:
    print "no sync wtf???"
  nextpos = syncpos + 1
  if nextpos < len(buffer) && buffer[nextpos] == syncval:
    synced = True

lenpos = syncpos + synclen
lenlen = 1

paylen = buffer[syncpos+2]
assert paylen < 170  #  note 170 is 0xaa - just coincidentally?

# now can examine paylen and if necessary handle case where packet is not complete
# needs rest of expected "paylen" data + checksum from next buffer
expected_len = paylen + 4

lastpos = len(buffer) - 1

if expected_len > lastpos - syncpos:
  # need rest of packet from next buffer

if len(packet) < expected_len:
  need_len = expected_len - len(packet)

  buffer = get_next_buffer()
  packet.extend(buffer[:needlen])
  # would be good to store this for the next time, so don't have to re-iterate looking for next sync

loadpos = lenpos + lenlen
checkpos = loadpos + paylen 

payload = packet[loadpos:checkpos] # slice so payload is a copy.
paycheck = packet[checkpos]

assert paycheck == 0xff & ~( sum(payload) & 0xff )

codons = {
  0x02: ('POOR_SIGNAL', 1),
  0x04: ('ATTENTION', 1),
  0x05: ('MEDITATION', 1),
  0x16: ('BLINK_EVENT', 1),
  0x55: ('EXTENDED_CODE', 1),
  0x80: ('RAW_EEG', 2),
  0x83: ('ASIC_POWER', 24),
  0xaa: ('SYNC', 172) 
}

getdatalen = lambda x, y:y[x][1]
ptr = payload
codelen = 1 # unless extended code, not handled here.
codepos = 0
datalen = 0

def testdatalen(datalen, codetype):
  if datalen > 1:
    assert codetype >= 0x80
  else:
    assert codetype < 0x80

nextpos = 0

while nextpos < paylen:
  codepos = nextpos
  codetype = ptr[codepos]
  assert codetype in codons
  assert codetype != 0x55 # we don't handle extended code bytes.
  datalen = getdatalen(codetype, codons)
  nextpos = codepos + codelen
  datapos = nextpos
  nextpos = datapos + datalen

  if nextpos >= paylen:
    break

  dataval = ptr[datapos:nextpos]

newpos = datapos + datalen


def syncromesh():
  buffer = init_buffer()
  paylen = 0

  while True:
    synced_buffer_portion = discard_until_sync(buffer)
    expected_paylen = synced_buffer_portion[0]  # written by device, packet is 4 bytes larger including 2 sync bytes
    assert expected_paylen < 170
    complete_packet_len = expected_paylen + 1
    buflen = len(synced_buffer_portion)
    if buflen < expected_paylen:
      # copy remaining buffer
      packet = synced_buffer_portion[:]
      # will need to "extend" packet with data from next buffer
      buffer = get_next_buffer
      expected_remaining = expected_paylen - buflen
      packet.extend(buffer[:expected_remaining])
      assert len(packet) == expected_
      
# want function to loop, reading buffer, writing packets

# initial state, before loop:
# unsynced buffer (contains fractional packet, sync signal, then possibly complete packet/s)
# blank packet

# So, discard buffer contents before first sync signal

# begin loop
#  at beginning of loop, have blank packet and synced buffer position
#  write from buffer to packet
#  until either
#    A) buffer end reached
#    B) logical packet content end reached
#    C) new sync signal detected (either before or at - or after! - logical packet end)

    What is "logical packet end" ?
    It is max 171 bytes after sync
    (total 173 bytes = 2 sync, 1 len, payload max 169 and 1 checksum byte)
    Precise length should be the data paylen value written by device + 4

  if A) buffer end reached
  then, still in loop, get new buffer, keep writing packet

  if B) "logical packet end" according to device-written "paylen" byte
  then, send packet, start new blank packet

  if C) sync signal detected before "logical packet end"
  then, handle (apparent) dropped packet and/or logic error
  - Code this logic last, just flag dropped packet for now
  Log incomplete packet for analysis separate from "good" data
  and start new blank packet