blob: 25e7c762aa9059fd58067706f162a509adfc6772 [file] [log] [blame]
Dan Talaycof75360a2010-02-05 22:22:54 -08001import socket
2import select
3
4## This module provides library to send and receive messages to NOX's messenger
5#
6# This is a rewrite of noxmsg.py from OpenRoads (OpenFlow Wireless)
7#
8# @author ykk (Stanford University)
9# @date January, 2010
10# @see messenger
11
12def stringarray(string):
13 """Output array of binary values in string.
14 """
15 arrstr = ""
16 if (len(string) != 0):
17 for i in range(0,len(string)):
18 arrstr += "%x " % struct.unpack("=B",string[i])[0]
19 return arrstr
20
21def printarray(string):
22 """Print array of binary values
23 """
24 print "Array of length "+str(len(string))
25 print stringarray(string)
26
27class channel:
28 """TCP channel to communicate to NOX with.
29 """
30 def __init__(self,ipAddr,portNo=2603,debug=False):
31 """Initialize with socket
32 """
33 ##Socket reference for channel
34 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
35 self.sock.connect((ipAddr,portNo))
36 self.debug = debug
37 ##Internal buffer for receiving
38 self.__buffer = ""
39 ##Internal reference to header
40 self.__header = messenger_msg()
41
42 def baresend(self, msg):
43 """Send bare message"""
44 self.sock.send(msg)
45
46 def send(self,msg):
47 """Send message
48 """
49 msgh = messenger_msg()
50 remaining = msgh.unpack(msg)
51 if (msgh.length != len(msg)):
52 msgh.length = len(msg)
53 msg = msgh.pack()+remaining
54 self.baresend(msg)
55 if (self.debug):
56 printarray(msg)
57
58 def receive(self, recvLen=0,timeout=0):
59 """Receive command
60 If length == None, nonblocking receive (return None or message)
61 With nonblocking receive, timeout is used for select statement
62
63 If length is zero, return single message
64 """
65 if (recvLen==0):
66 #Receive full message
67 msg=""
68 length=len(self.__header)
69 while (len(msg) < length):
70 msg+=self.sock.recv(1)
71 #Get length
72 if (len(msg) == length):
73 self.__header.unpack(msg)
74 length=self.__header.length
75 return msg
76 elif (recvLen==None):
77 #Non-blocking receive
78 ready_to_read = select.select([self.sock],[],[],timeout)[0]
79 if (ready_to_read):
80 self.__buffer += self.sock.recv(1)
81 if (len(self.__buffer) >= len(self.__header)):
82 self.__header.unpack(self.__buffer)
83 if (self.__header.length == len(self.__buffer)):
84 msg = self.__buffer
85 self.__buffer = ""
86 return msg
87 return None
88 else:
89 #Fixed length blocking receive
90 return self.sock.recv(recvLen)
91
92 def __del__(self):
93 """Terminate connection
94 """
95 emsg = messenger_msg()
96 emsg.type = MSG_DISCONNECT
97 emsg.length = len(emsg)
98 self.send(emsg.pack())
99 self.sock.shutdown(1)
100 self.sock.close()
101
102class sslChannel(channel):
103 """SSL channel to communicate to NOX with.
104 """
105 def __init__(self, ipAddr, portNo=1304,debug=False):
106 """Initialize with SSL sock
107 """
108 NOXChannel.__init__(self, ipAddr, portNo,debug)
109 ##Reference to SSL socket for channel
110 self.sslsock = socket.ssl(self.sock)
111
112 def baresend(self, msg):
113 """Send bare message"""
114 self.sslsock.write(msg)
115