def pformat(self, prefix=''): head = '\n'.join([ " op hex (%s)" % len(self.head), lib.hexdump(self.head, indent=4), " decimal", lib.int_dump(self.head, indent=11) ]) date = '\n'.join([ " datetime (%s)" % self.date_str( ), lib.hexdump(self.date, indent=4) ]) body = " body (%s)" % len(self.body) if len(self.body) > 0: body = '\n'.join([ body, " hex", lib.hexdump(self.body, indent=4), " decimal", lib.int_dump(self.body, indent=11) ]) extra = [ ] hour_bits = self.date[1:] and extra_hour_bits(self.date[1]) or [ ] year_bits = self.date[4:] and extra_year_bits(self.date[4]) or [ ] day_bits = self.date[3:] and extra_hour_bits(self.date[3]) or [ ] if 1 in hour_bits: extra.append("HOUR BITS: {}".format(str(hour_bits))) if 1 in day_bits: extra.append("DAY BITS: {}".format(str(day_bits))) if 1 in year_bits: extra.append("YEAR BITS: {}".format(str(year_bits))) decoded = self.decode( ) decode_msg = '' if decoded is not None: decode_msg = '\n'.join([ '###### DECODED', '```python', '{}'.format(lib.pformat(self.decode( ))), '```', ]) if extra: extra = ' ' + ' '.join(extra) else: extra = '' return '\n'.join([ prefix, decode_msg, head, date, body, extra ])
def respond(self, raw): if len(raw) == 0: log.error("ACK is zero bytes!") # return False raise AckError("ACK is 0 bytes:\n%s" % lib.hexdump(raw)) commStatus = raw[0] # usable response assert commStatus == 1, ('commStatus: %02x expected 0x1' % commStatus) status = raw[1] # status == 102 'f' NAK, look up NAK if status == 85: # 'U' return raw[:3], raw[3:] assert False, ("NAK!!\n%s" % lib.hexdump(raw[:3]))
def parse(self, raw): """ Detect BadCRC here. Also, look for eod set. """ """ log.info('readData validating remote raw[ack]: %02x' % raw[0]) log.info('readData; foreign raw should be at least 14 bytes? %s %s' % (len(raw), len(raw) > 14)) log.info('readData; raw[retries] %s' % int(raw[3])) dl_status = int(raw[0]) if dl_status != 0x02: # this differs from the others? raise BadDeviceCommError("bad dl raw! %r" % raw) assert (int(raw[0]) == 2), repr(raw) # raw[1] != 0 # interface number !=0 # raw[2] == 5 # timeout occurred # raw[2] == 2 # NAK # raw[2] # should be within 0..4 log.info("readData ACK") lb, hb = raw[5] & 0x7F, raw[6] self.eod = (raw[5] & 0x80) > 0 """ lb, hb = raw[5] & 0x7F, raw[6] self.eod = (raw[5] & 0x80) > 0 resLength = lib.BangInt((lb, hb)) # we don't really care about the length #assert resLength < 64, ("cmd low byte count:\n%s" % lib.hexdump(raw)) data = raw[13:13+resLength] self.packet = data log.info('%s:eod:found eod (%s)' % (self, self.eod)) log.info('found packet len(%s), link expects(%s)' % (len(self.packet), resLength)) assert len(data) == resLength head = raw[13:] crc = raw[-1] # crc check if crc == 0 and len(data) > 1: log.warn('bad zero CRC?') expected_crc = CRC8(data) if crc != expected_crc: msg = ':'.join( [ 'ReadRadio:BAD ACK:found raw[crc]: %#04x' % (crc), 'expected_crc(data): %#04x' % (expected_crc), 'raw:\n%s\n' % (lib.hexdump(raw)), 'head:\n%s\n' % (lib.hexdump(head)), 'data:\n%s\n' % (lib.hexdump(data)) ] ) log.info(msg) log.info("XXX:IGNORE:BadCRC:returning empty message, sleep .100, avoid errors.") time.sleep(.100) return bytearray( ) raise BadCRC(msg) assert crc == expected_crc return data
def getData(self): data = self.data log.info("READ pump settings:\n%s" % lib.hexdump(data)) auto_off_duration_hrs = data[0] alarm = self.alarm(data[1]) audio_bolus_enable = data[2] == 1 audio_bolus_size = 0 if audio_bolus_enable: audio_bolus_size = data[3] / 10.0 variable_bolus_enable = data[4] == 1 #MM23 is different maxBolus = data[5]/ 10.0 # MM512 and up maxBasal = lib.BangInt(data[6:8]) / 40 timeformat = data[8] insulinConcentration = {0: 100, 1: 50}[data[9]] patterns_enabled = data[10] == 1 selected_pattern = data[11] rf_enable = data[12] == 1 block_enable = data[13] == 1 """ # MM12 insulin_action_type = data[17] == 0 and 'Fast' or 'Regular' """ #MM15 insulin_action_type = data[17] low_reservoir_warn_type = data[18] low_reservoir_warn_point = data[19] keypad_lock_status = data[20] return locals( )
def getData(self): data = self.data log.info("XXX: READ cur page number:\n%s" % lib.hexdump(data)) if len(data) == 1: return int(data[0]) result = dict(page= lib.BangLong(data[0:4]), glucose=data[5], isig=data[7]) return result
def parse_time(self): mid = unmask_m_midnight(self.date) try: self.datetime = date = datetime(*mid) return date except ValueError, e: print "ERROR", e, mid, lib.hexdump(self.date) pass
def getData(self): data = self.data log.info("READ totals today:\n%s" % lib.hexdump(data)) totals = { 'today': lib.BangInt(data[0:2]) / 10.0, 'yesterday': lib.BangInt(data[2:4]) / 10.0 } return totals
def getData(self): data = self.data ids = [ ] ids.append( str(data[0:6]) ) ids.append( str(data[6:12]) ) ids.append( str(data[12:18]) ) log.info("READ radio ACL:\n%s" % lib.hexdump(data)) return ids
def download_page(self, x): log.info('comm:XXX:READ HISTORY DATA page number: %r' % (x)) comm = commands.ReadHistoryData(serial=self.device.serial, params=[ x ] ) self.device.execute(comm) page = comm.getData( ) comm.save(prefix=self.log_format) log.info("XXX: READ HISTORY DATA page number %r!!:\n%s" % (x, lib.hexdump(page))) time.sleep(.100)
def parse_midnight (data): mid = unmask_m_midnight(data) oneday = relativedelta(days=1) try: date = datetime(*mid) + oneday return date except ValueError, e: print "ERROR", e, lib.hexdump(data) pass
def power_control(self, minutes=None): log.info('BEGIN POWER CONTROL %s' % self.serial) # print "PowerControl SERIAL", self.serial response = self.query(commands.PowerControl, minutes=minutes) power = self.command log.info('manually download PowerControl serial %s' % self.serial) data = self.stick.download( ) log.info("ENDING manual download:\n%s" % lib.hexdump(data)) return data
def clear_buffer(self): bad = bytearray( ) raw = bytearray( ) for attempt in xrange( 3 ): segments = [ ] segs_vs_raw = 'segments[{0}],total_segments[{1}]:raw[{2}]' seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log_head = "XXX:clear_buffer[attempt][%s]" % (attempt) log.debug('INTERFACE STATS:\n%s' % lib.pformat(self.interface_stats( ))) log.info(":".join([ log_head, log_detail, "BEGIN ", "first poll" ])) size = self.poll_size( ) end_poll = ':'.join( [ log_head, log_detail, "END first poll %s" % (size), "SHOULD DOWNLOAD ", str(size != 0) ] ) log.info(end_poll) if size == 0: break seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.info("%s:download the size? %s:%s" % (log_head, size, log_detail)) while size > 14: seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log_head = "XXX:clear_buffer[attempt][%s]" % (attempt) log.info( ':'.join([ "%s size:%s" % (log_head, size), log_detail, "clear_buffer BUFFER self.download( )" ])) try: segment = self.download( ) raw.extend(segment) segments.append(segment) seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.info(":".join([ "%s:tx:found" % (log_head), log_detail, 'len(raw)', str(len(raw)), 'expected', str(size), 'len(segment)', str(len(segment)) ])) except BadCRC, e: seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.critical('%s:IGNORING:%s:%s' % (log_head, log_detail, e)) seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.info(':'.join([ "%s downloaded %s segment" % (log_head, len(raw)), log_detail, "RAW:\n%s" % lib.hexdump(raw) ])) size = self.poll_size( ) log.debug("INTERFACE STATS:\n%s" % lib.pformat(self.interface_stats( ))) if raw: return raw
def getData (self): # return self.model.decode_carb_ratios(self.data[:]) units = self.data[0] labels = { 1 : 'grams', 2: 'exchanges' } fixed = self.data[1] data = self.data[1:1+(8 *2)] print lib.hexdump(data) return dict(schedule=self.decode_ratios(data[1:], units=units), units=labels.get(units), first=self.data[0]) # xxx: remove schedule = [ ] for x in range(len(data)/ 2): start = x * 2 end = start + 2 (i, r) = data[start:end] ratio = int(r) if units == 2: ratio = r / 10.0 schedule.append(dict(x=x, i=i, offset=i*30, ratio=ratio, r=r)) return dict(schedule=schedule, units=labels.get(units), first=self.data[0])
def download(self): """ Download a single page, copy paste from elsewhere. """ log.info("read HISTORY DATA") comm = commands.ReadHistoryData(serial=self.device.serial, page=0) self.device.execute(comm) log.info('comm:READ history data page!!!:\n%s' % (lib.hexdump(comm.getData( )))) comm.save(prefix=self.log_format)
def getData(self): data = self.data log.info("XXX: READ cur page number:\n%s" % lib.hexdump(data)) if len(data) == 1: return int(data[0]) page = lib.BangLong(data[0:4]) # https://bitbucket.org/bewest/carelink/src/419fbf23495a/ddmsDTWApplet.src/minimed/ddms/deviceportreader/MMX15.java#cl-157 if page <= 0 or page > 36: page = 36 return page
def respond(self, raw): if len(raw) == 0: log.error("ReadRadio ACK is zero bytes!") # return False raise AckError("ACK is 0 bytes: %s" % lib.hexdump(raw)) log.info('readData validating remote raw[ack]: %02x' % raw[0]) log.info('readData; foreign raw should be at least 14 bytes? %s %s' % (len(raw), len(raw) > 14)) log.info('readData; raw[retries] %s' % int(raw[3])) dl_status = int(raw[0]) if dl_status != 0x02: # this differs from the others? raise BadDeviceCommError("bad dl raw! %r" % raw) assert (int(raw[0]) == 2), repr(raw) return raw[:1], raw
def get_pages(device): log.info("read cur page number") comm = ReadCurPageNumber(serial=device.serial ) device.execute(comm) pages = comm.getData( ) log.info('attempting to read %s pages of history' % pages) for x in range(pages + 1): log.info('comm:READ HISTORY DATA page number: %r' % (x)) comm = ReadHistoryData(serial=device.serial, params=[ x ] ) device.execute(comm) page = comm.getData( ) log.info("XXX: READ HISTORY DATA!!:\n%s" % lib.hexdump(page)) time.sleep(.100)
def getData(self): data = self.data log.info("XXX: READ cur page number:\n%s" % lib.hexdump(data)) # MM12 does not support this command, but has 31 pages # Thanks to @amazaheri page = 32 if len(data) == 1: return int(data[0]) if len(data) > 3: page = lib.BangLong(data[0:4]) # https://bitbucket.org/bewest/carelink/src/419fbf23495a/ddmsDTWApplet.src/minimed/ddms/deviceportreader/MMX15.java#cl-157 if page <= 0 or page > 36: page = 36 return page
def getData(self): data = self.data temp = { 0: 'absolute', 1: 'percent' }[self.data[0]] status = dict(temp=temp) if temp is 'absolute': rate = lib.BangInt(data[2:4])/40.0 duration = lib.BangInt(data[4:6]) status.update(rate=rate, duration=duration) if temp is 'percent': rate = int(data[1]) duration = lib.BangInt(data[4:6]) status.update(rate=rate, duration=duration) log.info("READ temporary basal:\n%s" % lib.hexdump(data)) return status
def getData(self): data = self.data log.info("READ pump settings:\n%s" % lib.hexdump(data)) if len(data) < 2: log.info("pump settings: unsupported version, sorry") return data auto_off_duration_hrs = data[0] alarm = self.alarm(data[1]) audio_bolus_enable = data[2] == 1 audio_bolus_size = 0 if audio_bolus_enable: audio_bolus_size = data[3] / 10.0 variable_bolus_enable = data[4] == 1 #MM23 is different maxBolus = data[5]/ 10.0 # MM512 and up maxBasal = lib.BangInt(data[6:8]) / 40.0 timeformat = data[8] insulinConcentration = {0: 100, 1: 50}[data[9]] patterns_enabled = data[10] == 1 selected_pattern = data[11] rf_enable = data[12] == 1 block_enable = data[13] == 1 temp_basal = self.temp_basal_type(data[14:16]) paradigm_enabled = data[16] """ # MM12 insulin_action_type = data[17] == 0 and 'Fast' or 'Regular' """ #MM15 # insulin_action_type = data[17] insulin_action_curve = data[17] low_reservoir_warn_type = data[18] low_reservoir_warn_point = data[19] keypad_lock_status = data[20] values = locals( ) # safety values.pop('self') values.pop('data') return values
def readlines( self ): r = self.serial.readlines( ) io.info( 'usb.read.len: %s\n%s' % ( len( r ), lib.hexdump( bytearray( ''.join( r ) ) ) ) ) return r
def read( self, c ): r = self.serial.read( c ) io.info( 'usb.read.len: %s' % ( len( r ) ) ) io.info( 'usb.read.raw:\n%s' % ( lib.hexdump( bytearray( r ) ) ) ) return r
def write( self, string ): r = self.serial.write( string ) io.info( 'usb.write.len: %s\n%s' % ( len( string ), lib.hexdump( bytearray( string ) ) ) ) return r
def getData(self): data = self.data log.info("READ remaining insulin:\n%s" % lib.hexdump(data)) return lib.BangInt(data[0:2]) / 10.0
def getData(self): data = self.data rate = lib.BangInt(data[2:4]) / 40.0 duration = lib.BangInt(data[4:6]) log.info("READ temporary basal:\n%s" % lib.hexdump(data)) return {'rate': rate, 'duration': duration}
def getData(self): data = self.data log.debug("READ FIRMWARE HEX:\n%s" % lib.hexdump(data)) return str(data.split( chr(0x0b) )[0]).strip( )
log.info('get signal strength of %s' % stick) signal = 0 while signal < 50: signal = stick.signal_strength() log.info('we seem to have found a nice signal strength of: %s' % signal) log.info(""" at this point, we could issue remote commands to a medical device, let's inspect the interfaces""".strip()) #log.info(pformat(stick.usb_stats( ))) #log.info(pformat(stick.radio_stats( ))) log.info(pformat(stick.interface_stats())) """ size = stick.poll_size( ) log.info("can we poll the size? %s" % (size)) if size > 14: log.info("DOWNLOADING %s TO CLEAR BUFFER" % size) log.info('\n'.join(["can we download ?", lib.hexdump(stick.download( ))])) """ log.info("CLEAR BUFFERS") extra = stick.clear_buffer() if extra: log.info(lib.hexdump(extra)) else: log.info("NO PENDING BUFFER") log.info("DONE CLEARING BUFFERS") log.info("INTERFACE STATS:\n%s" % pformat(stick.interface_stats())) log.info("howdy! all done looking at the stick") ##### # EOF
log.info('get signal strength of %s' % stick) signal = 0 while signal < 50: signal = stick.signal_strength( ) log.info('we seem to have found a nice signal strength of: %s' % signal) log.info(""" at this point, we could issue remote commands to a medical device, let's inspect the interfaces""".strip( )) #log.info(pformat(stick.usb_stats( ))) #log.info(pformat(stick.radio_stats( ))) log.info(pformat(stick.interface_stats( ))) """ size = stick.poll_size( ) log.info("can we poll the size? %s" % (size)) if size > 14: log.info("DOWNLOADING %s TO CLEAR BUFFER" % size) log.info('\n'.join(["can we download ?", lib.hexdump(stick.download( ))])) """ log.info("CLEAR BUFFERS") extra = stick.clear_buffer( ) if extra: log.info(lib.hexdump(extra)) else: log.info("NO PENDING BUFFER") log.info("DONE CLEARING BUFFERS") log.info("INTERFACE STATS:\n%s" % pformat(stick.interface_stats( ))) log.info("howdy! all done looking at the stick") ##### # EOF
def clear_buffer(self): """ An alternative download solution. This can be helpful in scenarios where a prior run seems crashed your process, but the radio is still transmitting and receiving data. Running this method collects data from the radio until it's done receiving, more or less, at which point you should be free to try again. """ bad = bytearray() raw = bytearray() for attempt in xrange(3): segments = [] segs_vs_raw = 'segments[{0}],total_segments[{1}]:raw[{2}]' seg_stats = (len(segments), sum(map(len, segments)), len(raw)) log_detail = segs_vs_raw.format(*seg_stats) log_head = "XXX:clear_buffer[attempt][%s]" % (attempt) log.debug('INTERFACE STATS:\n%s' % lib.pformat(self.interface_stats())) log.info(":".join([log_head, log_detail, "BEGIN ", "first poll"])) size = self.poll_size() end_poll = ':'.join([ log_head, log_detail, "END first poll %s" % (size), "SHOULD DOWNLOAD ", str(size != 0) ]) log.info(end_poll) if size == 0: break seg_stats = (len(segments), sum(map(len, segments)), len(raw)) log_detail = segs_vs_raw.format(*seg_stats) log.info("%s:download the size? %s:%s" % (log_head, size, log_detail)) while size > 14: seg_stats = (len(segments), sum(map(len, segments)), len(raw)) log_detail = segs_vs_raw.format(*seg_stats) log_head = "XXX:clear_buffer[attempt][%s]" % (attempt) log.info(':'.join([ "%s size:%s" % (log_head, size), log_detail, "clear_buffer BUFFER self.download( )" ])) try: segment = self.download() raw.extend(segment) segments.append(segment) seg_stats = (len(segments), sum(map(len, segments)), len(raw)) log_detail = segs_vs_raw.format(*seg_stats) log.info(":".join([ "%s:tx:found" % (log_head), log_detail, 'len(raw)', str(len(raw)), 'expected', str(size), 'len(segment)', str(len(segment)) ])) except BadCRC, e: seg_stats = (len(segments), sum(map(len, segments)), len(raw)) log_detail = segs_vs_raw.format(*seg_stats) log.critical('%s:IGNORING:%s:%s' % (log_head, log_detail, e)) seg_stats = (len(segments), sum(map(len, segments)), len(raw)) log_detail = segs_vs_raw.format(*seg_stats) log.info(':'.join([ "%s downloaded %s segment" % (log_head, len(raw)), log_detail, "RAW:\n%s" % lib.hexdump(raw) ])) size = self.poll_size() log.debug("INTERFACE STATS:\n%s" % lib.pformat(self.interface_stats())) if raw: return raw
def getData(self): data = self.data log.info("XXX: READ cur page number:\n%s" % lib.hexdump(data)) if len(data) == 1: return int(data[0]) return lib.BangLong(data[0:4])
def getData(self): data = self.data log.info("READ contrast:\n%s" % lib.hexdump(data)) return data
def getData(self): data = self.data rate = lib.BangInt(data[2:4])/40.0 duration = lib.BangInt(data[4:6]) log.info("READ temporary basal:\n%s" % lib.hexdump(data)) return { 'rate': rate, 'duration': duration }
def hexdump(self): return lib.hexdump(self.data)
def hexdump (self): return lib.hexdump(self.data)
def getData(self): data = self.data log.info("READ remaining insulin:\n%s" % lib.hexdump(data)) return lib.BangInt(data[self.startByte:self.endByte])/self.basalStrokes
def clear_buffer(self): """ An alternative download solution. This can be helpful in scenarios where a prior run seems crashed your process, but the radio is still transmitting and receiving data. Running this method collects data from the radio until it's done receiving, more or less, at which point you should be free to try again. """ bad = bytearray( ) raw = bytearray( ) for attempt in xrange( 3 ): segments = [ ] segs_vs_raw = 'segments[{0}],total_segments[{1}]:raw[{2}]' seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log_head = "XXX:clear_buffer[attempt][%s]" % (attempt) log.debug('INTERFACE STATS:\n%s' % lib.pformat(self.interface_stats( ))) log.info(":".join([ log_head, log_detail, "BEGIN ", "first poll" ])) size = self.poll_size( ) end_poll = ':'.join( [ log_head, log_detail, "END first poll %s" % (size), "SHOULD DOWNLOAD ", str(size != 0) ] ) log.info(end_poll) if size == 0: break seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.info("%s:download the size? %s:%s" % (log_head, size, log_detail)) while size > 14: seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log_head = "XXX:clear_buffer[attempt][%s]" % (attempt) log.info( ':'.join([ "%s size:%s" % (log_head, size), log_detail, "clear_buffer BUFFER self.download( )" ])) try: segment = self.download( ) raw.extend(segment) segments.append(segment) seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.info(":".join([ "%s:tx:found" % (log_head), log_detail, 'len(raw)', str(len(raw)), 'expected', str(size), 'len(segment)', str(len(segment)) ])) except BadCRC, e: seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.critical('%s:IGNORING:%s:%s' % (log_head, log_detail, e)) seg_stats = ( len(segments), sum(map(len, segments)), len(raw) ) log_detail = segs_vs_raw.format(*seg_stats) log.info(':'.join([ "%s downloaded %s segment" % (log_head, len(raw)), log_detail, "RAW:\n%s" % lib.hexdump(raw) ])) size = self.poll_size( ) log.debug("INTERFACE STATS:\n%s" % lib.pformat(self.interface_stats( ))) if raw: return raw
def read_history_0(self): log.info("read HISTORY DATA") comm = commands.ReadHistoryData(serial=self.serial, page=0) self.execute(comm) log.info('comm:READ history data page!!!:\n%s' % (lib.hexdump(comm.getData())))
def getData(self): data = self.data log.debug("READ FIRMWARE HEX:\n%s" % lib.hexdump(data)) return str(data.split(chr(0x0b))[0]).strip()
def readlines(self): r = super(type(self), self).readlines() self.log.info('read: %s\n%s' % (len(r), lib.hexdump(bytearray(''.join(r))))) return r