|
| 1 | +#!/usr/bin/env python |
| 2 | +# |
| 3 | +# Copyright (C) 2008-2010 Istituto per l'Interscambio Scientifico I.S.I. |
| 4 | +# You can contact us by email (isi@isi.it) or write to: |
| 5 | +# ISI Foundation, Viale S. Severo 65, 10133 Torino, Italy. |
| 6 | +# |
| 7 | +# This program was written by Ciro Cattuto <ciro.cattuto@gmail.com> |
| 8 | +# |
| 9 | + |
| 10 | +# -------------------------------------------------------------------------- |
| 11 | + |
| 12 | +class Event(object): |
| 13 | + """ |
| 14 | + Base class used for all events |
| 15 | + reported by the SocioPatterns/OpenBeacon infrastructure |
| 16 | + """ |
| 17 | + __slots__ = ('t', 'ip', 'id', 'seq') |
| 18 | + |
| 19 | + def __init__(self, tstamp, ip, id, seq): |
| 20 | + self.t = tstamp |
| 21 | + self.ip = ip |
| 22 | + self.id = id |
| 23 | + self.seq = seq |
| 24 | + |
| 25 | + def get_hash(self): |
| 26 | + """ |
| 27 | + The (tag id, sequence counter) combination uniquely identifies |
| 28 | + a packet in the air. This method returns an hash value |
| 29 | + computed from the above pair. |
| 30 | + """ |
| 31 | + |
| 32 | + return hash( (self.id, self.seq) ) |
| 33 | + |
| 34 | + |
| 35 | +class Sighting(Event): |
| 36 | + """ |
| 37 | + Class for Sighting objects. |
| 38 | + A sighting is a message emitted by one tag and received |
| 39 | + (possibly in multiple copies) by the infrastructure. |
| 40 | + A sighting only contains information about the tag that trasmitted it. |
| 41 | + """ |
| 42 | + |
| 43 | + __slots__ = ('strength', 'flags', 'last_seen', 'boot_count') |
| 44 | + |
| 45 | + protocol = 24 |
| 46 | + |
| 47 | + def __init__(self, tstamp, ip, id, seq, strength, flags, last_seen=0, boot_count=0): |
| 48 | + """ |
| 49 | + Constructor of the Sighting class. |
| 50 | + Instances are typically built by an instance |
| 51 | + of the sociopatterns.Loader class, |
| 52 | + and made available as a stream using the iterator semantics. |
| 53 | +
|
| 54 | + required parameters are: |
| 55 | + |
| 56 | + tstamp -- time of the event, as a UNIX ctime integer |
| 57 | +
|
| 58 | + ip -- IP address of the reader that reported the event, |
| 59 | + represented as an unsigned 32-bit integer (10.254.0.1 is 0x0afe0001) |
| 60 | +
|
| 61 | + id -- the unique ID of the tag emitting the packet (16-bit integer) |
| 62 | +
|
| 63 | + seq -- sequence number of the packet, as a 32-bit integer. |
| 64 | + Packets with the same (id, seq) pair are duplicates reported |
| 65 | + by different readers (each packet having a different ip field). |
| 66 | +
|
| 67 | + strenght -- power level at which the RF chip of the tag |
| 68 | + was asked to trasmit. Integer from 0 (lowest power) |
| 69 | + to 3 (highest power). |
| 70 | +
|
| 71 | + flags -- one byte of flags. |
| 72 | + "Taps" on the RFID tags set bit 1. |
| 73 | + The "infected" flags of the Dublin experiment sets bit 2. |
| 74 | +
|
| 75 | + keyword parameters are: |
| 76 | +
|
| 77 | + last_seen -- the ID of the last tag that was seen |
| 78 | + by the trasmitting tag. Do no use this info for contact analysis. |
| 79 | +
|
| 80 | + boot_count -- the number of reboot cycles the tag went through |
| 81 | + (16-bit integer). The counter is incremented every time the tag |
| 82 | + reboots. When the battery of a tag runs our, multiple and frequent |
| 83 | + reboots can be observed because of brown-outs. |
| 84 | + """ |
| 85 | + |
| 86 | + Event.__init__(self, tstamp, ip, id, seq) |
| 87 | + |
| 88 | + self.strength = strength |
| 89 | + self.flags = flags |
| 90 | + self.last_seen = last_seen |
| 91 | + self.boot_count = boot_count |
| 92 | + |
| 93 | + def get_hash(self): |
| 94 | + return hash( (self.id, self.boot_count, self.seq) ) |
| 95 | + |
| 96 | + def __repr__(self): |
| 97 | + """ |
| 98 | + Returns a human-readable representation of the Sighting event, |
| 99 | + as an ASCII string. |
| 100 | + """ |
| 101 | + |
| 102 | + return 'S %ld 0x%08x %d 0x%08x %d %d %s %s' % (self.t, self.ip, self.id, self.seq, self.strength, self.flags, self.last_seen, self.boot_count) |
| 103 | + |
| 104 | + |
| 105 | +class Contact(Event): |
| 106 | + """ |
| 107 | + Class for Contact objects. |
| 108 | + A contact is a message emitted by one tag and received |
| 109 | + (possibly in multiple copies) by the infrastructure. |
| 110 | + A contact contains information about the tag that trasmitted it |
| 111 | + as well as about tags lying in its proximity. |
| 112 | + """ |
| 113 | + |
| 114 | + __slots__ = ('seen_id', 'seen_pwr', 'seen_cnt', 'flags', 'boot_count') |
| 115 | + |
| 116 | + protocol = 69 |
| 117 | + |
| 118 | + def __init__(self, tstamp, ip, id, seq, seen_id=[], seen_pwr=[], seen_cnt=[], flags=0, boot_count=0): |
| 119 | + """ |
| 120 | + Constructor of the Contact class. |
| 121 | + Instances are typically built by an instance |
| 122 | + of the sociopatterns.Loader class, |
| 123 | + and made available as a stream using the iterator semantics. |
| 124 | +
|
| 125 | + required parameters are: |
| 126 | + |
| 127 | + tstamp -- time of the event, as a UNIX ctime integer |
| 128 | +
|
| 129 | + ip -- IP address of the reader that reported the event, |
| 130 | + represented as an unsigned 32-bit integer (10.254.0.1 is 0x0afe0001) |
| 131 | +
|
| 132 | + id -- the unique ID of the tag emitting the packet (16-bit integer) |
| 133 | +
|
| 134 | + seq -- sequence number of the packet, as a 32-bit integer. |
| 135 | + Packets with the same (id, seq) pair are duplicates reported |
| 136 | + by different readers (each packet having a different ip field). |
| 137 | +
|
| 138 | + keyword parameters are: |
| 139 | +
|
| 140 | + seen_id -- list of 16-bit integers of the tags that were last seen |
| 141 | + by the reporting tag. The list contains unique tag IDs, at most |
| 142 | + 4 of them. Its length is equal to the length of seen_pwr and seen_cnt. |
| 143 | + |
| 144 | + seen_pwr -- list of integers. Each element of the list represents |
| 145 | + the strength (0..3) of the weakest packet received from the tag |
| 146 | + in the corresponding position of the seen_id list. |
| 147 | +
|
| 148 | + seen_cnt -- list of integers. Each element of the list represents |
| 149 | + the number of packets (1..7) received at the weakest power |
| 150 | + (seen_pwr) from the tag in the corresponding position of seen_id. |
| 151 | +
|
| 152 | + flags -- one byte of flags |
| 153 | +
|
| 154 | + boot_count -- the number of reboot cycles the tag went through |
| 155 | + (16-bit integer). The counter is incremented every time the tag |
| 156 | + reboots. When the battery of a tag runs our, multiple and frequent |
| 157 | + reboots can be observed because of brown-outs. |
| 158 | + """ |
| 159 | + |
| 160 | + Event.__init__(self, tstamp, ip, id, seq) |
| 161 | + |
| 162 | + self.seen_id = seen_id |
| 163 | + self.seen_pwr = seen_pwr |
| 164 | + self.seen_cnt = seen_cnt |
| 165 | + self.flags = flags |
| 166 | + self.boot_count = boot_count |
| 167 | + |
| 168 | + |
| 169 | + def __repr__(self): |
| 170 | + """ |
| 171 | + Returns a human-readable representation of the Contact event, |
| 172 | + as an ASCII string. |
| 173 | + """ |
| 174 | + |
| 175 | + clist = "" |
| 176 | + for (id2, pwr, count) in zip(self.seen_id, self.seen_pwr, self.seen_cnt): |
| 177 | + clist += " [%d(%d) #%d]" % (id2, pwr, count) |
| 178 | + |
| 179 | + return 'C %ld 0x%08x %d 0x%04x 0x%08x %d%s' % (self.t, self.ip, self.id, self.boot_count, self.seq, self.flags, clist) |
| 180 | + |
| 181 | + |
0 commit comments