25 A collection of classes which wrap our @ref C-Classes and provide Pythonic interfaces
30 from AssimCtypes
import AddrFrame, CstringFrame, UnknownFrame, ConfigValue, IpPortFrame, \
31 FrameSet, PacketDecoder, guint8, IntFrame, ConfigContext, SignFrame, \
32 proj_class_live_object_count, proj_class_dump_live_objects, CONFIGNAME_CMAPORT
34 from AssimCtypes
import POINTER, cast, addressof, pointer, string_at, create_string_buffer, \
35 c_char_p, byref, memmove, badfree, \
36 g_free, GSList, GDestroyNotify, g_slist_length, g_slist_next, struct__GSList, \
40 Frame, AssimObj, NetAddr, SeqnoFrame, \
41 frame_new, addrframe_new, \
42 nvpairframe_new, frameset_new, frameset_append_frame, frameset_prepend_frame, \
43 seqnoframe_new, cstringframe_new, unknownframe_new, \
44 ipportframe_netaddr_new, ipportframe_ipv4_new, ipportframe_ipv6_new, \
45 frameset_construct_packet, frameset_get_flags, frameset_set_flags, frameset_clear_flags, \
47 LLDP_TLV_END, LLDP_TLV_CHID, LLDP_TLV_PID, LLDP_TLV_TTL, LLDP_TLV_PORT_DESCR, \
48 LLDP_TLV_SYS_NAME, LLDP_TLV_SYS_DESCR, LLDP_TLV_SYS_CAPS, LLDP_TLV_MGMT_ADDR, \
49 LLDP_TLV_ORG_SPECIFIC, \
50 LLDP_ORG802_1_VLAN_PVID, LLDP_ORG802_1_VLAN_PORTPROTO, LLDP_ORG802_1_VLAN_NAME, \
51 LLDP_ORG802_1_VLAN_PROTOID, LLDP_ORG802_3_PHY_CONFIG, LLDP_ORG802_3_POWERVIAMDI, \
52 LLDP_ORG802_3_LINKAGG, LLDP_ORG802_3_MTU, \
53 LLDP_PIDTYPE_ALIAS, LLDP_PIDTYPE_IFNAME, LLDP_PIDTYPE_LOCAL, LLDP_CHIDTYPE_ALIAS, \
54 LLDP_CHIDTYPE_IFNAME, LLDP_CHIDTYPE_LOCAL, LLDP_CHIDTYPE_MACADDR, \
55 LLDP_CHIDTYPE_COMPONENT, LLDP_CHIDTYPE_NETADDR, \
56 ADDR_FAMILY_IPV4, ADDR_FAMILY_IPV6, ADDR_FAMILY_802, \
57 is_valid_lldp_packet, is_valid_cdp_packet, \
58 netaddr_ipv4_new, netaddr_ipv6_new, netaddr_dns_new, netaddr_mac48_new, netaddr_mac64_new, \
59 proj_class_classname, \
60 assimobj_new, intframe_new, signframe_new, packetdecoder_new, configcontext_new, \
61 configcontext_new_JSON_string, netio_new, netioudp_new, reliableudp_new,\
62 netio_is_dual_ipv4v6_stack, create_setconfig, create_sendexpecthb, \
69 CFG_EEXIST, CFG_CFGCTX, CFG_CFGCTX, CFG_STRING, CFG_NETADDR, CFG_FRAME, CFG_INT64, CFG_ARRAY, \
70 CFG_FLOAT, CFG_BOOL, DEFAULT_FSP_QID
73 from frameinfo
import FrameTypes, FrameSetTypes
80 'Just a handy collection of POINTER() objects'
83 NetAddr = POINTER(NetAddr)
84 Frame = POINTER(Frame)
85 AddrFrame = POINTER(AddrFrame)
86 IntFrame = POINTER(IntFrame)
87 SeqnoFrame = POINTER(SeqnoFrame)
88 CstringFrame = POINTER(CstringFrame)
89 UnknownFrame = POINTER(UnknownFrame)
90 SignFrame = POINTER(SignFrame)
91 FrameSet = POINTER(FrameSet)
92 ConfigContext = POINTER(ConfigContext)
93 ConfigValue = POINTER(ConfigValue)
94 IpPortFrame = POINTER(IpPortFrame)
95 guint8 = POINTER(guint8)
96 GSList = POINTER(GSList)
100 Increment the reference count to an AssimObj (_not_ a pyAssimObj)
101 Need to call CCref under the following circumstances:
102 When we are creating an object that points to another underlying C-class object
103 which already has a permanent reference to it somewhere else
104 For example, if we're returning a pyNetAddr object that points to a NetAddr object
105 that's in a ConfigContext object. If we don't, then when our pyNetAddr object goes
106 out of scope, then the underlying NetAddr object will be freed, even though there's
107 a reference to it in the ConfigContext object. Conversely, if the ConfigContext
108 object goes out of scope first, then the our pyNetAddr object could become invalid.
110 Do not call it when you've constructed a new object that there were no previous pointers
114 while (type(base)
is not AssimObj):
115 base = base.baseclass
119 'Unref an AssimObj object (or subclass)'
121 while (type(base)
is not AssimObj):
122 base = base.baseclass
127 Class for interpreting switch discovery data via LLDP or CDP
128 Currently only LLDP is fully implemented.
131 LLDP_TLV_END: (
'END',
True),
132 LLDP_TLV_CHID: (
'ChassisId',
True),
133 LLDP_TLV_PID: (
'PortId',
True),
134 LLDP_TLV_TTL: (
'TTL',
True),
135 LLDP_TLV_PORT_DESCR: (
'PortDescription',
False),
136 LLDP_TLV_SYS_NAME: (
'SystemName',
True),
137 LLDP_TLV_SYS_DESCR: (
'SystemDescription',
True),
138 LLDP_TLV_SYS_CAPS: (
'SystemCapabilities',
True),
139 LLDP_TLV_MGMT_ADDR: (
'ManagementAddress',
True),
140 LLDP_TLV_ORG_SPECIFIC: (
'(OrgSpecific)',
True),
143 LLDP_ORG802_1_VLAN_PVID: (
'VlanPvId',
False),
144 LLDP_ORG802_1_VLAN_PORTPROTO: (
'VlanPortProtocol',
False),
145 LLDP_ORG802_1_VLAN_NAME: (
'VlanName',
False),
146 LLDP_ORG802_1_VLAN_PROTOID: (
'VlanProtocolId',
False),
149 LLDP_ORG802_3_PHY_CONFIG: (
'PhysicalConfiguration',
False),
150 LLDP_ORG802_3_POWERVIAMDI: (
'PowerViaMDI',
False),
151 LLDP_ORG802_3_LINKAGG: (
'LinkAggregation',
False),
152 LLDP_ORG802_3_MTU: (
'MTU',
False),
159 def _byte0(pktstart):
160 'Return the first (zeroth) byte from a memory blob'
161 return int(cast(pktstart, cClass.guint8)[0])
164 def _byte1addr(pktstart):
165 'Return the address of byte 1 in a memory blob'
166 addr = addressof(pktstart.contents) + 1
167 return pointer(type(pktstart.contents).from_address(addr))
170 def _byteN(pktstart, n):
171 'Return the Nth byte from a memory blob'
172 return int(cast(pktstart, cClass.guint8)[n])
175 def _byteNaddr(pktstart, n):
176 'Return the address of the Nth byte in a memory blob'
177 addr = addressof(pktstart.contents) + n
178 return pointer(type(pktstart.contents).from_address(addr))
181 def _decode_netaddr(addrstart, addrlen):
182 'Return an appropriate pyNetAddr object corresponding to the given memory blob'
183 byte0 = pySwitchDiscovery._byte0(addrstart)
184 byte1addr = pySwitchDiscovery._byte1addr(addrstart)
186 if byte0 == ADDR_FAMILY_IPV6:
190 elif byte0 == ADDR_FAMILY_IPV4:
194 elif byte0 == ADDR_FAMILY_802:
199 if Cnetaddr
is not None:
200 return str(
pyNetAddr(
None, Cstruct=Cnetaddr))
205 'Return a JSON packet corresponding to the given switch discovery packet'
207 return pySwitchDiscovery._decode_lldp(host, interface, wallclock, pktstart, pktend)
209 return pySwitchDiscovery._decode_cdp(host, interface, wallclock, pktstart, pktend)
210 raise ValueError(
'Malformed Switch Discovery Packet')
213 def _decode_lldp_chid(tlvptr, tlvlen):
214 'Decode the LLDP CHID field, and return an appropriate value'
215 chidtype = pySwitchDiscovery._byte0(tlvptr)
217 if (chidtype == LLDP_CHIDTYPE_COMPONENT
or chidtype == LLDP_CHIDTYPE_ALIAS
218 or chidtype == LLDP_CHIDTYPE_IFNAME
or chidtype == LLDP_CHIDTYPE_LOCAL):
219 sloc = pySwitchDiscovery._byte1addr(tlvptr)
220 value = string_at(sloc, tlvlen-1)
221 elif chidtype == LLDP_CHIDTYPE_MACADDR:
222 byte1addr = pySwitchDiscovery._byte1addr(tlvptr)
228 if Cmacaddr
is not None:
229 value =
pyNetAddr(
None, Cstruct=Cmacaddr)
230 elif chidtype == LLDP_CHIDTYPE_NETADDR:
231 byte1addr = pySwitchDiscovery._byte1addr(tlvptr)
232 value = pySwitchDiscovery._decode_netaddr(byte1addr, tlvlen-1)
237 def _decode_lldp(host, interface, wallclock, pktstart, pktend):
238 'Decode LLDP packet into a JSON discovery packet'
240 'ConnectsToHost': host,
241 'ConnectsToInterface': interface,
246 'discovertype':
'#LinkDiscovery',
247 'description':
'Link Level Switch Discovery (lldp)',
248 'source':
'_decode_lldp()',
250 'localtime': str(wallclock),
255 sourcemacptr = pySwitchDiscovery._byteNaddr(cast(pktstart, cClass.guint8), 6)
259 sourcemac =
pyNetAddr(
None, Cstruct=Cmacaddr)
263 while this
and this < pktend:
268 if tlvtype
not in pySwitchDiscovery.lldpnames:
269 print >> sys.stderr,
'Cannot find tlvtype %d' % tlvtype
272 (tlvname, isswitchinfo) = pySwitchDiscovery.lldpnames[tlvtype]
274 if (tlvtype == LLDP_TLV_PORT_DESCR
or tlvtype == LLDP_TLV_SYS_NAME
or
275 tlvtype == LLDP_TLV_SYS_DESCR):
276 value = string_at(tlvptr, tlvlen)
278 elif tlvtype == LLDP_TLV_PID:
279 pidtype = pySwitchDiscovery._byte0(tlvptr)
280 if (pidtype == LLDP_PIDTYPE_ALIAS
or pidtype == LLDP_PIDTYPE_IFNAME
281 or pidtype == LLDP_PIDTYPE_LOCAL):
282 sloc = pySwitchDiscovery._byte1addr(tlvptr)
283 value = string_at(sloc, tlvlen-1)
285 elif tlvtype == LLDP_TLV_CHID:
286 value = pySwitchDiscovery._decode_lldp_chid(tlvptr, tlvlen)
288 elif tlvtype == LLDP_TLV_MGMT_ADDR:
289 addrlen = pySwitchDiscovery._byte0(tlvptr)
290 byte1addr = pySwitchDiscovery._byte1addr(tlvptr)
291 value = pySwitchDiscovery._decode_netaddr(byte1addr, addrlen)
293 elif tlvtype == LLDP_TLV_ORG_SPECIFIC:
294 print >> sys.stderr,
'Found LLDP org-specific extensions (not processed)'
296 if value
is not None:
297 if tlvtype == LLDP_TLV_PID:
298 switchinfo[
'ports'][value] = thisportinfo
300 while len(numericpart) > 0
and not numericpart.isdigit():
301 numericpart = numericpart[1:]
302 if len > 0
and numericpart.isdigit():
303 thisportinfo[
'_PORTNO'] = int(numericpart)
306 switchinfo[tlvname] = value
308 thisportinfo[tlvname] = value
310 thisportinfo[
'sourceMAC'] = sourcemac
315 def _decode_cdp(host, interface, wallclock, pktstart, pktend):
316 'Decode CDP packet into a JSON discovery packet'
318 'ConnectsToHost': host,
319 'ConnectsToInterface': interface,
324 'discovertype':
'#LinkDiscovery',
325 'description':
'Link Level Switch Discovery (cdp)',
326 'source':
'_decode_cdp()',
328 'localtime': str(wallclock),
332 thisportinfo = thisportinfo
341 'The base object for all the C-class objects'
343 'Create a base pyAssimObj object'
345 if (Cstruct
is not None):
346 assert type(Cstruct)
is not int
353 "Return the 'C' class name for this object"
357 'Convert this AssimObj into a printable string'
361 while (type(base)
is not AssimObj):
362 base = base.baseclass
363 cstringret = base.toString(self.
_Cstruct)
364 ret = string_at(cstringret)
370 'Free up the underlying Cstruct for this pyAssimObj object.'
379 print >> sys.stderr,
"Attempt to free something already freed(%s)" % str(self.
_Cstruct)
380 traceback.print_stack()
385 'Return the reference count for this object'
387 while (hasattr(base,
'baseclass')):
388 base = base.baseclass
389 return base._refcount
392 '''This class represents the Python version of our C-class @ref NetAddr
393 - represented by the struct _NetAddr.
395 def __init__(self, addrstring, port=None, Cstruct=None):
396 '''This constructor needs a list of integers of the right length as its first argument.
397 The length of the list determines the type of address generated.
399 6 bytes == MAC address
400 8 bytes == MAC address
401 16 bytes == ipv6 address
402 This is slightly sleazy but it should work for the forseeable future.
407 if (Cstruct
is not None):
408 assert type(Cstruct)
is not int
409 pyAssimObj.__init__(self, Cstruct=Cstruct)
417 if isinstance(addrstring, unicode)
or isinstance(addrstring, pyNetAddr):
418 addrstring = str(addrstring)
419 if isinstance(addrstring, str):
422 raise ValueError(
'Illegal NetAddr initial value: "%s"' % addrstring)
425 pyAssimObj.__init__(self, Cstruct=cs)
428 alen = len(addrstring)
429 addr = create_string_buffer(alen)
432 for i
in range(0, alen):
437 elif type(asi)
is unicode:
444 pyAssimObj.__init__(self, Cstruct=NA)
454 raise ValueError(
'Invalid address length - not 4, 6, 8, or 16')
457 'Return the port (if any) for this pyNetAddr object'
459 while (type(base)
is not NetAddr):
460 base = base.baseclass
464 'Return the port (if any) for this pyNetAddr object'
466 while (type(base)
is not NetAddr):
467 base = base.baseclass
471 'Return the type of address for this pyNetAddr object'
473 while (type(base)
is not NetAddr):
474 base = base.baseclass
478 "Return the number of bytes necessary to represent this pyNetAddr object on the wire."
480 while (type(base)
is not NetAddr):
481 base = base.baseclass
485 'Return True if this address is a local address'
487 while (type(base)
is not NetAddr):
488 base = base.baseclass
492 'Return an equivalent IPv6 address to the one that was given. Guaranteed to be a copy'
494 while (type(base)
is not NetAddr):
495 base = base.baseclass
496 newcs = cast(base.toIPv6(self.
_Cstruct), cClass.NetAddr)
497 return pyNetAddr(
None, Cstruct=newcs, port=port)
500 'Return a canonical representation of this NetAddr'
502 while (type(base)
is not NetAddr):
503 base = base.baseclass
504 cstringret = base.canonStr(self.
_Cstruct)
505 ret = string_at(cstringret)
511 "Return True if the two pyNetAddrs are equal"
512 if not other._Cstruct
or not self.
_Cstruct:
515 while (type(base)
is not NetAddr):
516 base = base.baseclass
517 return base.equal(self.
_Cstruct, other._Cstruct)
520 'Return a hash value for the given pyNetAddr'
524 while (type(base)
is not NetAddr):
525 base = base.baseclass
530 '''This class represents the Python version of our C-class @ref Frame
531 - represented by the struct _Frame.
532 This class is a base class for several different pyFrame subclasses.
533 Each of these various pyFrame subclasses have a corresponding C-class @ref Frame subclass.
534 The purpose of these pyFrames and their subclasses is to talk on the wire with our C code in our
537 Deliberately leaving out the updatedata() C-class member function - at least for now.
538 I suspect that the Python code will only need the corresponding calls in a @ref FrameSet
539 - which would then update the corresponding @ref Frame member functions...
549 "Initializer for the pyFrame object."
552 frametype = initval.tlvtype
553 except(AttributeError):
554 frametype = int(initval)
556 pyAssimObj.__init__(self, Cstruct=
frame_new(frametype, 0))
558 pyAssimObj.__init__(self, Cstruct=Cstruct)
561 "Return the TLV type for the pyFrame object."
563 while (type(base)
is not Frame):
564 base = base.baseclass
568 "Return the length of this frame in bytes (TLV length)."
570 while (type(base)
is not Frame):
571 base = base.baseclass
575 'Return a C-style pointer to the underlying raw TLV data (if any)'
577 while (type(base)
is not Frame):
578 base = base.baseclass
579 return cast(base.value, c_char_p)
582 'Return a C-style pointer to the underlying raw TLV data (if any)'
584 while (type(base)
is not Frame):
585 base = base.baseclass
586 return cast(base.value+base.length, c_char_p)
589 'Return the amount of space this frame needs - including type and length'
591 while (type(base)
is not Frame):
592 base = base.baseclass
593 return base.dataspace(self.
_Cstruct)
596 "Return True if this Frame is valid"
598 while (type(base)
is not Frame):
599 base = base.baseclass
603 return (int(base.isvalid(self.
_Cstruct,
None,
None)) != 0)
606 'Assign a chunk of memory to the Value portion of this Frame'
608 if type(value)
is str:
609 valbuf = create_string_buffer(vlen+1)
610 for i
in range(0, vlen):
613 valbuf[vlen] = chr(0)
616 valbuf = create_string_buffer(vlen)
617 for i
in range(0, vlen):
622 memmove(valptr, valbuf, vlen)
623 while (type(base)
is not Frame):
624 base = base.baseclass
625 base.setvalue(self.
_Cstruct, valptr, vlen, cast(
None, GDestroyNotify))
628 'Dump out this Frame (using C-class "dump" member function)'
630 while (type(base)
is not Frame):
631 base = base.baseclass
632 base.dump(self.
_Cstruct, cast(prefix, c_char_p))
635 'Convert this Frame to a string'
637 while (type(base)
is not AssimObj):
638 base = base.baseclass
639 cstringret = base.toString(self.
_Cstruct)
640 ret = string_at(cstringret)
642 return '%s: %s' % (FrameTypes.get(self.
frametype())[1] , ret)
646 'Unmarshalls a binary blob (Cstruct) into a Frame'
647 frameptr = cast(frameptr, cClass.Frame)
649 frametype = frameptr[0].type
651 pyclassname =
"py" + Cclassname
652 if Cclassname ==
'NetAddr':
653 statement =
"%s(%d, None, Cstruct=cast(frameptr, cClass.%s))" \
654 % (pyclassname, frametype, Cclassname)
655 elif Cclassname == Cclassname ==
'IpPortFrame':
656 statement =
"%s(%d, None, None, Cstruct=cast(frameptr, cClass.%s))" \
657 % (pyclassname, frametype, Cclassname)
659 statement =
"%s(%d, Cstruct=cast(frameptr, cClass.%s))" \
660 % (pyclassname, frametype, Cclassname)
662 return eval(statement)
665 '''This class represents the Python version of our C-class AddrFrame
666 - represented by the struct _AddrFrame.
668 def __init__(self, frametype, addrstring=None, port=None, Cstruct=None):
669 "Initializer for the pyAddrFrame object."
672 if isinstance(addrstring, pyNetAddr):
677 if addrstring
is not None:
678 Cstruct[0].setnetaddr(Cstruct, self._pyNetAddr._Cstruct)
681 assert addrstring
is None
683 addrlen = Cstruct[0].baseclass.length - 2
684 assert addrlen == 4
or addrlen == 6
or addrlen == 8
or addrlen == 16 \
685 , (
"addrlen is %d" % addrlen)
686 addrstr = Cstruct[0].baseclass.value+2
687 addrstring = create_string_buffer(addrlen)
688 memmove(addrstring, addrstr, addrlen)
690 pyFrame.__init__(self, frametype, Cstruct=Cstruct)
693 'Return the Address type for this AddrFrame'
694 return self._pyNetAddr.addrtype()
697 'Return the pyNetAddr for this AddrFrame'
701 return (
"pyAddrFrame(%s, (%s))" \
705 '''This class represents the Python version of our C-class IpPortFrame
706 - represented by the struct _IpPortFrame.
708 def __init__(self, frametype, addrstring, port=None, Cstruct=None):
709 "Initializer for the pyIpPortFrame object."
712 if isinstance(addrstring, pyNetAddr):
716 raise ValueError(
"invalid initializer")
719 addrlen = len(addrstring)
722 raise ValueError(
"Invalid initializer.")
723 addrstr = create_string_buffer(addrlen)
724 for j
in range(0, addrlen):
725 addrstr[j] = chr(addrstring[j])
731 raise ValueError(
'Bad address length: %d' % addrlen)
734 raise ValueError(
"zero port")
736 raise ValueError(
"invalid initializer")
740 assert addrstring
is None
741 addrlen = Cstruct[0].baseclass.length - 4
742 if addrlen != 4
and addrlen != 16:
743 raise ValueError(
"Bad addrlen: %d" % addrlen)
744 port = Cstruct[0].port
746 addrstr = Cstruct[0].baseclass.value+4
747 addrstring = create_string_buffer(addrlen)
748 memmove(addrstring, addrstr, addrlen)
750 pyFrame.__init__(self, frametype, Cstruct=Cstruct)
753 'Return the Address type of this pyIpPortFrame'
754 return self._pyNetAddr.addrtype()
757 'Return the NetAddr of this pyIpPortFrame'
761 'Return the port of this pyIpPortFrame'
766 '''This class represents the Python version of our C-class CstringFrame
767 - represented by the struct _CstringFrame.
768 This class represents a Frame standard NUL-terminated C string.
770 def __init__(self, frametype, initval=None, Cstruct=None):
771 '''Constructor for pyCstringFrame object - initial value should be something
772 that looks a lot like a Python string'''
775 pyFrame.__init__(self, frametype, Cstruct)
776 if initval
is not None:
780 'Return the String part of this pyCstringFrame'
782 while (
not hasattr(base,
'value')):
783 base = base.baseclass
784 return string_at(base.value)
787 '''This class represents the Python version of our IntFrame C-class
788 - represented by the struct _IntFrame.
789 This class represents an integer of 1, 2, 3, 4 or 8 bytes.
791 def __init__(self, frametype, initval=None, intbytes=4, Cstruct=None):
792 '''Constructor for pyIntFrame object
793 - initial value should be something that looks a lot like an integer'''
798 raise ValueError, (
"Invalid integer size (%d) in pyIntFrame constructor" % intbytes)
799 pyFrame.__init__(self, frametype, Cstruct=Cstruct)
800 if initval
is not None:
804 '''Return the integer value of this pyIntFrame. (implemented by the
805 underlying IntFrame object)'''
809 'Return a string representation of this pyIntFrame (the integer value).'
810 return (
"pyIntFrame(%s, (%d))" % (FrameTypes.get(self.
frametype())[1], int(self)))
813 'Return the integer value of this pyIntFrame - same as __int__.'
817 '''Set the value of this pyIntFrame to the given integer value.
818 Note that this value is range checked by the underlying IntFrame implementation.
823 '''Return the number of bytes in the integer underlying this pyIntFrame object.
824 (implemented by underlying IntFrame object)'''
828 "Class for a Frame type we don't recognize"
830 'Initializer for pyUnknownFrame'
833 pyFrame.__init__(self, frametype, Cstruct)
836 'Class for a Sequence Number Frame - for reliable UDP packet transmission.'
837 def __init__(self, frametype, initval=None, Cstruct=None):
838 'Initializer for pySeqnoFrame'
844 raise ValueError,
"Constructor error for PySeqnoFrame()"
845 pyFrame.__init__(self, frametype, Cstruct=Cstruct)
846 if initval
is not None:
851 'Set the request ID portion of this SeqnoFrame'
855 'Set the Queue ID portion of this SeqnoFrame'
859 'Get the request ID portion of this SeqnoFrame'
863 'Get the Queue ID portion of this SeqnoFrame'
867 'Compare this pySeqnoFrame to another pySeqnoFrame'
869 while (type(lhsbase)
is not SeqnoFrame):
870 lhsbase = lhsbase.baseclass
871 return lhsbase.equal(self.
_Cstruct, rhs._Cstruct)
874 'Convert this pySeqnoFrame to a String'
875 return (
"pySeqNo(%s: (%d, %d))" \
879 '''Class for Digital Signature Frames
880 - for authenticating data (subclasses will authenticate senders)'''
882 'Initializer for pySignFrame'
887 raise ValueError, (
"Invalid checksum type (%s) for PySignFrame()" % gchecksumtype)
888 pyFrame.__init__(self, initval=FRAMETYPE_SIG, Cstruct=Cstruct)
891 'Class for a Frame containing a single name/value pair'
892 def __init__(self, frametype, name, value, Cstruct=None):
893 'Initializer for pyNVpairFrame'
898 raise ValueError, (
"Invalid NVpair initializer for pyNVPairFrame()")
899 pyFrame.__init__(self, initval=frametype, Cstruct=Cstruct)
902 'Return the name portion of a pyNVpairFrame'
903 return string_at(self.
_Cstruct[0].name)
906 'Return the name portion of a pyNVpairFrame'
907 return string_at(self.
_Cstruct[0].value)
913 'Class for Frame Sets - for collections of Frames making up a logical packet'
915 'Initializer for pyFrameSet'
918 pyAssimObj.__init__(self, Cstruct=Cstruct)
921 'Append a frame to the end of a @ref FrameSet'
925 'Prepend a frame before the first frame in a @ref FrameSet'
929 'Construct packet from curent frameset + special prefix frames'
932 if cryptframe
is not None:
933 cf = cryptframe._Cstruct
934 if compressframe
is not None:
935 cmpf = compressframe._Cstruct
939 'Return frameset type of this FrameSet'
943 'Return current flags for this FrameSet'
947 "'OR' the given flags into the set of flags for this FrameSet"
951 "Clear the given flags for this FrameSet"
955 'Dump out the given frameset'
959 'Return the constructed packet for this pyFrameSet'
961 raise ValueError,
"No packet constructed for frameset"
965 'Return the number of Frames in this pyFrameSet'
971 curframe = self.
_Cstruct[0].framelist
975 curframe = g_slist_next(curframe)
979 "Fail - we don't implement this"
980 raise NotImplementedError(
"FrameSet does not implement __delitem__()")
983 "Fail - we don't implement this"
984 raise NotImplementedError(
"FrameSet does not implement __getitem__()")
987 "Fail - we don't implement this"
988 raise NotImplementedError(
"FrameSet does not implement __setitem__()")
991 'Generator yielding the set of pyFrames in this pyFrameSet'
992 curframe = self.
_Cstruct[0].framelist
994 cast(curframe[0].data, struct__GSList._fields_[0][1])
995 yieldval = pyFrame.Cstruct2Frame(cast(curframe[0].data, cClass.Frame))
996 if not yieldval.isvalid():
997 print "OOPS! Constructed frame from iter() is not valid"
1000 curframe = g_slist_next(curframe)
1003 'Convert this pyFrameSet to a String'
1006 for frame
in self.
iter():
1007 result +=
'%s%s' % (comma, str(frame))
1014 'Class for Decoding packets - for returning an array of FrameSets from a physical packet.'
1016 'Initializer for pyPacketDecoder'
1019 pyAssimObj.__init__(self, Cstruct=Cstruct)
1022 'Make a list of FrameSets out of a packet.'
1024 while (type(base)
is not PacketDecoder):
1025 base = base.baseclass
1026 fs_gslistint = base.pktdata_to_framesetlist(self.
_Cstruct, pktlocation[0], pktlocation[1])
1027 return pyPacketDecoder.fslist_to_pyfs_array(fs_gslistint)
1031 'Converts a GSList of FrameSets to a python array of pyFrameSets'
1032 fs_gslist = cast(listheadint, cClass.GSList)
1036 cfs = cast(curfs[0].data, cClass.FrameSet)
1038 frameset_list.append(fs)
1039 curfs = g_slist_next(curfs)
1040 g_slist_free(fs_gslist)
1041 return frameset_list
1045 'Class for Holding configuration information.'
1049 'Initializer for pyConfigContext'
1052 if (isinstance(init, str)
or isinstance(init, unicode)):
1055 raise ValueError(
'Bad JSON [%s]' % str(init))
1059 pyAssimObj.__init__(self, Cstruct=Cstruct)
1060 if init
is not None:
1061 for key
in init.keys():
1062 self[key] = init[key]
1066 'Return the integer associated with "name"'
1070 'Set the integer associated with "name"'
1074 'Return the boolean associated with "name"'
1078 'Set the boolean associated with "name"'
1082 'Return the NetAddr associated with "name"'
1085 naddr = cast(naddr, cClass.NetAddr)
1089 raise IndexError(
"No such NetAddr value [%s]" % name)
1092 'Set the @ref NetAddr associated with "name"'
1096 'Return the Frame associated with "name"'
1100 return pyFrame.Cstruct2Frame(faddr)
1101 raise IndexError(
"No such Frame value [%s]" % name)
1104 'Set the @ref Frame associated with "name"'
1108 'Return the pyConfigContext object associated with "name"'
1111 caddr = cast(caddr, cClass.ConfigContext)
1115 raise IndexError(
"No such ConfigContext value [%s]" % name)
1118 'Set the @ref ConfigContext associated with "name"'
1122 'Return the string associated with "name"'
1125 return string_at(ret)
1126 raise IndexError(
"No such String value [%s]" % name)
1129 'Return the string associated with "name"'
1133 'Return the array value associated with "name"'
1140 data = cast(curlist[0].data, cClass.ConfigValue)
1146 curlist = g_slist_next(curlist)
1150 'Return the set of keys for this object'
1155 l.append(string_at(curkey[0].data))
1156 curkey = g_slist_next(curkey)
1157 g_slist_free(keylist)
1161 '''Return the enumeration type of this particular key
1162 @todo Convert these enums to python types'''
1167 'return True if it has the given key'
1169 return ktype != CFG_EEXIST
1172 'return True if our object contains the given key'
1174 return ktype != CFG_EEXIST
1177 'Return the number of items in this pyConfigContext'
1179 llen = g_slist_length(keylist)
1180 g_slist_free(keylist)
1184 "Fail - we don't implement this"
1185 raise NotImplementedError(
"pyConfigContext does not implement __delitem__()")
1188 'Return a value associated with "name"'
1192 if ktype == CFG_EEXIST:
1193 traceback.print_stack()
1194 raise IndexError(
"No such value [%s] in [%s]" % (name, str(self)))
1195 elif ktype == CFG_CFGCTX:
1197 elif ktype == CFG_STRING:
1199 elif ktype == CFG_NETADDR:
1201 elif ktype == CFG_FRAME:
1203 elif ktype == CFG_INT64:
1205 elif ktype == CFG_BOOL:
1207 elif ktype == CFG_ARRAY:
1214 'Set a value associated with "name" - in the appropriate table'
1215 if isinstance(value, str):
1217 if isinstance(value, pyNetAddr):
1218 return self.
setaddr(name, value)
1219 if isinstance(value, pyFrame):
1221 if isinstance(value, pyConfigContext):
1223 self.
setint(name, int(value))
1226 'A Python wrapper for a C implementation of something like a Python Dictionary'
1228 'Initializer for pyConfigValue - now a subclass of pyAssimObj'
1229 pyAssimObj.__init__(self, Cstruct=Cstruct)
1232 'Convert the given pyConfigValue to a String'
1236 'Return the value of this object'
1239 if vtype == CFG_BOOL:
1240 ret = self.
_Cstruct[0].u.intvalue != 0
1241 elif vtype == CFG_INT64:
1242 ret = int(self.
_Cstruct[0].u.intvalue)
1243 elif vtype == CFG_STRING:
1244 ret = str(self.
_Cstruct[0].u.strvalue)
1245 elif vtype == CFG_FLOAT:
1246 ret = float(self.
_Cstruct[0].u.floatvalue)
1247 elif vtype == CFG_CFGCTX:
1251 elif vtype == CFG_NETADDR:
1255 elif vtype == CFG_FRAME:
1257 ret = pyFrame.Cstruct2Frame(self.
_Cstruct[0].u.framevalue)
1258 elif vtype == CFG_ARRAY:
1261 this = self.
_Cstruct[0].u.arrayvalue
1263 dataptr = cast(this[0].data, struct__GSList._fields_[0][1])
1264 dataptr = cast(dataptr, cClass.ConfigValue)
1268 this = g_slist_next(this)
1270 raise ValueError(
'Invalid valtype (%s)in pyConfigValue object' % self._Cstruct.valtype)
1274 'A Network I/O object - with a variety of subclasses'
1275 def __init__(self, configobj, packetdecoder, Cstruct=None):
1276 'Initializer for pyNetIO'
1279 Cstruct =
netio_new(0, configobj._Cstruct, packetdecoder._Cstruct)
1284 while (
not hasattr(base,
'_configinfo')):
1285 base = base.baseclass
1287 CCref(base._configinfo)
1288 pyAssimObj.__init__(self, Cstruct=Cstruct)
1291 'Set this NetIO object to blocking IO mode'
1293 while (
not hasattr(base,
'setblockio')):
1294 base = base.baseclass
1295 return base.setblockio(self.
_Cstruct, int(mode))
1298 'Return the file descriptor for this pyNetIO object'
1300 while (
not hasattr(base,
'getfd')):
1301 base = base.baseclass
1305 'Bind the socket underneath this NetIO object to the given address'
1307 while (
not hasattr(base,
'bindaddr')):
1308 base = base.baseclass
1309 return base.bindaddr(self.
_Cstruct, addr._Cstruct, silent)
1312 'Return the socket underlying this NetIO object'
1314 while (
not hasattr(base,
'bindaddr')):
1315 base = base.baseclass
1316 boundaddr = base.boundaddr(self.
_Cstruct)
1318 ret =
pyNetAddr(
None, Cstruct=boundaddr)
1323 'Join the underlying socket to the given multicast address'
1325 while (
not hasattr(base,
'mcastjoin')):
1326 base = base.baseclass
1327 return base.mcastjoin(self.
_Cstruct, addr._Cstruct,
None)
1330 'Return the max packet size for this pyNetIO'
1332 while (
not hasattr(base,
'getmaxpktsize')):
1333 base = base.baseclass
1334 return base.getmaxpktsize(self.
_Cstruct)
1337 'Set the max packet size for this pyNetIO'
1339 while (
not hasattr(base,
'setmaxpktsize')):
1340 base = base.baseclass
1341 return base.setmaxpktsize(self.
_Cstruct, int(size))
1344 'Return the compression frame for this pyNetIO - may be None'
1347 while (
not hasattr(base,
'compressframe')):
1348 base = base.baseclass
1349 return base.compressframe(self.
_Cstruct)
1352 'Return the encryption frame for this pyNetIO - may be None'
1355 while (
not hasattr(base,
'cryptframe')):
1356 base = base.baseclass
1357 return base.cryptframe(self.
_Cstruct)
1360 'Return the digital signature frame for this pyNetIO'
1362 while (
not hasattr(base,
'signframe')):
1363 base = base.baseclass
1367 'Send the (collection of) frameset(s) out on this pyNetIO'
1368 if destaddr.port() == 0:
1369 raise ValueError(
"Zero Port in sendframesets: destaddr=%s" % str(destaddr))
1370 if not isinstance(framesetlist, collections.Sequence):
1371 framesetlist = (framesetlist, )
1373 while (
not hasattr(base,
'sendaframeset')):
1374 base = base.baseclass
1377 for frameset
in framesetlist:
1378 base.sendaframeset(self.
_Cstruct, destaddr._Cstruct, frameset._Cstruct)
1381 'Reliably send the (collection of) frameset(s) out on this pyNetIO (if possible)'
1382 if destaddr.port() == 0:
1383 raise ValueError(
"Zero Port in sendreliablefs: destaddr=%s" % str(destaddr))
1384 if not isinstance(framesetlist, collections.Sequence):
1385 framesetlist = (framesetlist, )
1387 while (
not hasattr(base,
'sendaframeset')):
1388 base = base.baseclass
1389 for frameset
in framesetlist:
1390 success = base.sendareliablefs(self.
_Cstruct, destaddr._Cstruct, qid, frameset._Cstruct)
1392 raise IOError(
"sendareliablefs(%s, %s) failed." % (destaddr, frameset))
1395 'ACK (acknowledge) this frameset - (presumably sent reliably).'
1398 while (
not hasattr(base,
'ackmessage')):
1399 base = base.baseclass
1400 base.ackmessage(self.
_Cstruct, destaddr._Cstruct, frameset._Cstruct)
1403 'Close (reset) our connection to this address'
1406 while (
not hasattr(base,
'closeconn')):
1407 base = base.baseclass
1408 base.closeconn(self.
_Cstruct, qid, destaddr._Cstruct)
1411 'Close (reset) our connection to this address'
1414 while (
not hasattr(base,
'closeconn')):
1415 base = base.baseclass
1416 base.addalias(self.
_Cstruct, fromaddr._Cstruct, toaddr._Cstruct)
1419 '''Receive a collection of framesets read from this pyNetIO - all from the same Address.
1420 @return The return value is a tuple (address, framesetlist). '''
1424 while (
not hasattr(base,
'recvframesets')):
1425 base = base.baseclass
1427 netaddr = cast(netaddrint, cClass.NetAddr)
1428 netaddr[0].baseclass.unref(netaddr)
1431 fs_gslistint = base.recvframesets(self.
_Cstruct, byref(netaddr))
1432 fslist = pyPacketDecoder.fslist_to_pyfs_array(fs_gslistint)
1433 if netaddr
and len(fslist) > 0:
1436 address =
pyNetAddr(
None, Cstruct=netaddr)
1439 return (address, fslist)
1443 'Return True if our OS supports a dual IPv4/IPv6 stack'
1447 'UDP version of the pyNetIO abstract base class'
1448 def __init__(self, config, packetdecoder, Cstruct=None):
1449 'Initializer for pyNetIOudp'
1452 Cstruct =
netioudp_new(0, config._Cstruct, packetdecoder._Cstruct)
1454 raise ValueError(
"Invalid parameters to pyNetIOudp constructor")
1455 pyNetIO.__init__(self, config, packetdecoder, Cstruct=Cstruct)
1458 'Reliable UDP version of the pyNetIOudp abstract base class'
1459 def __init__(self, config, packetdecoder, rexmit_timer_uS=0, Cstruct=None):
1460 'Initializer for pyReliableUDP'
1463 Cstruct =
reliableudp_new(0, config._Cstruct, packetdecoder._Cstruct, rexmit_timer_uS)
1465 raise ValueError(
"Invalid parameters to pyReliableUDP constructor")
1466 pyNetIOudp.__init__(self, config, packetdecoder, Cstruct=Cstruct)
1469 'Miscellaneous functions to create certain useful pyFrameSets'
1472 'Do-nothing init function'
1477 'Create a setconfig FrameSet'
1483 'Create a Send/Expect heartbeat FrameSet'
1485 , address._Cstruct, 1)
1486 fs = cast(ucfs, cClass.FrameSet)