]> git.llucax.com Git - z.facultad/66.09/etherled.git/blob - cliente/etherled/packet.py
Implementado el checksum de UDP, tanto para paquetes recibidos como para
[z.facultad/66.09/etherled.git] / cliente / etherled / packet.py
1 #!/usr/bin/env python
2 # -*- coding: iso-8859-1 -*-
3 # vim: set expandtab tabstop=4 shiftwidth=4 :
4 #----------------------------------------------------------------------------
5 #                               Etherled
6 #----------------------------------------------------------------------------
7 # This file is part of etherled.
8 #
9 # etherled is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as published by the Free
11 # Software Foundation; either version 2 of the License, or (at your option)
12 # any later version.
13 #
14 # etherled is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU General Public License along
20 # with etherled; if not, write to the Free Software Foundation, Inc., 59
21 # Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 #----------------------------------------------------------------------------
23 # Creado:  sáb oct 29 00:45:52 ART 2005
24 # Autores: Leandro Lucarella <llucare@fi.uba.ar>
25 #----------------------------------------------------------------------------
26
27 # Tipos de operación
28 TYPE_GET = 0
29 TYPE_SET = 1
30
31 # Variables
32 VAR_MATRIX = 0
33
34 # Limites
35 MAX_ID = 8
36 MAX_VAR = 8
37
38 class ParityError(ValueError):
39     pass
40
41 class Packet(object):
42
43     def __init__(self, type, var=None, id=None, data=None):
44         if isinstance(type, str):
45             self.fromStr(type)
46         else:
47             self.type = type 
48             self.var = var
49             self.id = id
50             self.data = data
51
52     def fromStr(self, string):
53         header = ord(string[0])
54         self.type = header >> 7
55         self.var = (header & 0x70) >> 4
56         self.id = (header & 0x0E) >> 1
57         par = header & 0x01
58         if self.par != par:
59             raise ParityError
60         self.data = string[1:] or None
61
62     def __str__(self):
63         header = self._header_to_int()
64         data = ''
65         if self.data is not None:
66             data = self.data
67         return chr(header) + data
68
69     def __repr__(self):
70         return "Packet(type=%d, var=%d, id=%d, data=%s)" \
71             % (self.type, self.var, self.id, repr(self.data))
72
73     def __len__(self):
74         return len(str(self))
75
76     def __eq__(self, p):
77         return self.type == p.type and self.var == p.var and self.id == p.id
78
79     def _header_to_int(self):
80         res = (self.type << 7) + (self.var << 4) + (self.id << 1)
81         return res + self.par
82
83     def _getPar(self):
84         par = self.type
85         for i in xrange(3):
86             par += int((self.var & (1 << i)) != 0)
87         for i in xrange(3):
88             par += int((self.id & (1 << i)) != 0)
89         return par % 2
90
91     def _getType(self):
92         return self._type
93
94     def _setType(self, type):
95         if type != TYPE_GET and type != TYPE_SET:
96             raise ValueError, "type debe ser Packet.GET o Packet.SET"
97         self._type = type
98
99     def _getVar(self):
100         return self._var
101
102     def _setVar(self, var):
103         if var < 0 and var >= self.MAX_VAR:
104             raise ValueError, "var debe estar entre 0 y %d" % self.MAX_VAR-1
105         self._var = var
106
107     def _getId(self):
108         return self._id
109
110     def _setId(self, id):
111         if id < 0 and id >= self.MAX_ID:
112             raise ValueError, "id debe estar entre 0 y %d" % self.MAX_ID-1
113         self._id = id
114
115     type = property(_getType, _setType, doc="Tipo de operación")
116     var = property(_getVar, _setVar, doc="Variable con la cual operar")
117     id = property(_getId, _setId, doc="Identificador del paquete")
118     par = property(_getPar, doc="Paridad de la cabecera del paquete")
119
120 class ClientPacket(Packet):
121
122     def __init__(self, type, var=None, id=None, data=None):
123         if isinstance(type, str):
124             self.fromStr(type)
125         else:
126             Packet.__init__(self, type, var, id, data)
127             if type == TYPE_GET and data is not None:
128                 raise ValueError, "El paquete a enviar por el cliente no " \
129                     "puede contener datos si es de tipo GET"
130
131     def fromStr(self, string):
132         Packet.fromStr(self, string)
133         if self.type == TYPE_SET and self.data is not None:
134             raise ValueError, "El paquete recibido por el cliente no " \
135                 "puede contener datos si es de tipo SET"
136
137 class ServerPacket(Packet):
138
139     def __init__(self, type, var=None, id=None, data=None):
140         if isinstance(type, str):
141             self.fromStr(type)
142         else:
143             Packet.__init__(self, type, var, id, data)
144             if type == TYPE_SET and data is not None:
145                 raise ValueError, "El paquete a enviar por el servidor no " \
146                     "puede contener datos si es de tipo SET"
147
148     def fromStr(self, string):
149         Packet.fromStr(self, string)
150         if self.type == TYPE_GET and self.data is not None:
151             raise ValueError, "El paquete recibido por el cliente no " \
152                 "puede contener datos si es de tipo GET"
153
154 # Prueba
155 if __name__ == '__main__':
156     assert str(Packet(1, 7, 7)) == '\xFF'
157     assert str(Packet(0, 0, 0)) == '\x00'
158     assert str(Packet(1, 1, 1)) == '\x93'
159     assert str(Packet(TYPE_SET, VAR_MATRIX, 2)) == '\x84'
160     assert str(Packet(TYPE_GET, 4, 0)) == 'A'
161     assert str(Packet(TYPE_GET, 4, 0, 'hola')) == 'Ahola'
162     p = Packet(TYPE_GET, 4, 0, 'hola')
163     assert Packet(str(p)) == p
164     print "OK!"
165