| import socket |
| import select |
| |
| ## This module provides library to send and receive messages to NOX's messenger |
| # |
| # This is a rewrite of noxmsg.py from OpenRoads (OpenFlow Wireless) |
| # |
| # @author ykk (Stanford University) |
| # @date January, 2010 |
| # @see messenger |
| |
| def stringarray(string): |
| """Output array of binary values in string. |
| """ |
| arrstr = "" |
| if (len(string) != 0): |
| for i in range(0,len(string)): |
| arrstr += "%x " % struct.unpack("=B",string[i])[0] |
| return arrstr |
| |
| def printarray(string): |
| """Print array of binary values |
| """ |
| print "Array of length "+str(len(string)) |
| print stringarray(string) |
| |
| class channel: |
| """TCP channel to communicate to NOX with. |
| """ |
| def __init__(self,ipAddr,portNo=2603,debug=False): |
| """Initialize with socket |
| """ |
| ##Socket reference for channel |
| self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| self.sock.connect((ipAddr,portNo)) |
| self.debug = debug |
| ##Internal buffer for receiving |
| self.__buffer = "" |
| ##Internal reference to header |
| self.__header = messenger_msg() |
| |
| def baresend(self, msg): |
| """Send bare message""" |
| self.sock.send(msg) |
| |
| def send(self,msg): |
| """Send message |
| """ |
| msgh = messenger_msg() |
| remaining = msgh.unpack(msg) |
| if (msgh.length != len(msg)): |
| msgh.length = len(msg) |
| msg = msgh.pack()+remaining |
| self.baresend(msg) |
| if (self.debug): |
| printarray(msg) |
| |
| def receive(self, recvLen=0,timeout=0): |
| """Receive command |
| If length == None, nonblocking receive (return None or message) |
| With nonblocking receive, timeout is used for select statement |
| |
| If length is zero, return single message |
| """ |
| if (recvLen==0): |
| #Receive full message |
| msg="" |
| length=len(self.__header) |
| while (len(msg) < length): |
| msg+=self.sock.recv(1) |
| #Get length |
| if (len(msg) == length): |
| self.__header.unpack(msg) |
| length=self.__header.length |
| return msg |
| elif (recvLen==None): |
| #Non-blocking receive |
| ready_to_read = select.select([self.sock],[],[],timeout)[0] |
| if (ready_to_read): |
| self.__buffer += self.sock.recv(1) |
| if (len(self.__buffer) >= len(self.__header)): |
| self.__header.unpack(self.__buffer) |
| if (self.__header.length == len(self.__buffer)): |
| msg = self.__buffer |
| self.__buffer = "" |
| return msg |
| return None |
| else: |
| #Fixed length blocking receive |
| return self.sock.recv(recvLen) |
| |
| def __del__(self): |
| """Terminate connection |
| """ |
| emsg = messenger_msg() |
| emsg.type = MSG_DISCONNECT |
| emsg.length = len(emsg) |
| self.send(emsg.pack()) |
| self.sock.shutdown(1) |
| self.sock.close() |
| |
| class sslChannel(channel): |
| """SSL channel to communicate to NOX with. |
| """ |
| def __init__(self, ipAddr, portNo=1304,debug=False): |
| """Initialize with SSL sock |
| """ |
| NOXChannel.__init__(self, ipAddr, portNo,debug) |
| ##Reference to SSL socket for channel |
| self.sslsock = socket.ssl(self.sock) |
| |
| def baresend(self, msg): |
| """Send bare message""" |
| self.sslsock.write(msg) |
| |