From 13ff09f42164d31c6a8621791d7b687e0cbba7d2 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 4 Jun 2014 07:35:43 +0530 Subject: [PATCH] CLI: Added BLOB RPC support to python binding; updated the binding example to use the RPC; added a convenience method - saveCaptureBuffer() to DroneProxy --- binding/core.py | 11 +++++++++++ binding/example.py | 31 +++++++++++++++++++++++++++++-- binding/rpc.py | 18 ++++++++++++++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/binding/core.py b/binding/core.py index a25d965..994d236 100644 --- a/binding/core.py +++ b/binding/core.py @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see +import os from rpc import OstinatoRpcChannel, OstinatoRpcController import protocols.protocol_pb2 as ost_pb @@ -40,9 +41,19 @@ class DroneProxy(object): def connect(self): self.channel.connect(self.host, self.port) + def disconnect(self): + self.channel.disconnect() + def callRpcMethod(self, method_name, request): controller = OstinatoRpcController() ost_pb.OstService_Stub.__dict__[method_name]( self.stub, controller, request, None) return controller.response + def saveCaptureBuffer(self, buffer, file_name): + f= open(file_name, 'wb') + f.write(buffer) + f.flush() + os.fsync(f.fileno()) + f.close() + diff --git a/binding/example.py b/binding/example.py index 54d13ef..2150222 100644 --- a/binding/example.py +++ b/binding/example.py @@ -1,7 +1,10 @@ +#! /usr/bin/env python + # standard modules +import logging +import os import sys import time -import logging # ostinato modules - prepend 'ostinato.' to the module names when using # an installed package i.e ostinato.core and ostinato.protocols.xxx @@ -88,7 +91,10 @@ try: drone.clearStats(tx_port) drone.clearStats(rx_port) - # start transmit + # start capture and transmit + log.info('starting capture') + drone.startCapture(rx_port) + time.sleep(1) log.info('starting transmit') drone.startTx(tx_port) @@ -96,6 +102,12 @@ try: log.info('waiting for transmit to finish ...') time.sleep(7) + # stop transmit and capture + log.info('stopping transmit') + drone.stopTx(tx_port) + log.info('stopping capture') + drone.stopCapture(rx_port) + # get tx/rx stats log.info('retreiving stats') tx_stats = drone.getStats(tx_port) @@ -106,6 +118,21 @@ try: log.info('tx pkts = %d, rx pkts = %d' % (tx_stats.port_stats[0].tx_pkts, rx_stats.port_stats[0].rx_pkts)) + # retrieve and dump received packets + log.info('getting Rx capture buffer') + buff = drone.getCaptureBuffer(rx_port.port_id[0]) + drone.saveCaptureBuffer(buff, 'capture.pcap') + log.info('dumping Rx capture buffer') + os.system('tshark -r capture.pcap') + os.remove('capture.pcap') + + # delete streams + log.info('deleting tx_stream %d' % stream_id.stream_id[0].id) + drone.deleteStream(stream_id) + + # bye for now + drone.disconnect() + except Exception, ex: log.exception(ex) sys.exit(1) diff --git a/binding/rpc.py b/binding/rpc.py index 6da362f..1d68ad2 100644 --- a/binding/rpc.py +++ b/binding/rpc.py @@ -31,13 +31,20 @@ class OstinatoRpcChannel(RpcChannel): def connect(self, host, port): self.sock.connect((host, port)) + def disconnect(self): + self.sock.close() + def CallMethod(self, method, controller, request, response_class, done): OST_PB_MSG_HDR_SIZE = 8 OST_PB_MSG_TYPE_REQUEST = 1 + OST_PB_MSG_TYPE_RESPONSE = 2 + OST_PB_MSG_TYPE_BLOB = 3 + req = request.SerializeToString() self.sock.sendall(struct.pack('>HHI', OST_PB_MSG_TYPE_REQUEST, method.index, len(req)) + req) + # receive and parse header hdr = '' while len(hdr) < OST_PB_MSG_HDR_SIZE: chunk = self.sock.recv(OST_PB_MSG_HDR_SIZE - len(hdr)) @@ -47,6 +54,7 @@ class OstinatoRpcChannel(RpcChannel): (type, method, resp_len) = struct.unpack('>HHI', hdr) + # receive and parse the actual response message resp = '' while len(resp) < resp_len: chunk = self.sock.recv(resp_len - len(resp)) @@ -54,8 +62,14 @@ class OstinatoRpcChannel(RpcChannel): raise RuntimeError("socket connection broken") resp = resp + chunk - response = response_class() - response.ParseFromString(resp) + if type == OST_PB_MSG_TYPE_RESPONSE: + response = response_class() + response.ParseFromString(resp) + elif type == OST_PB_MSG_TYPE_BLOB: + response = resp + else: + print 'unsupported msg type %d received in respone to %s' % \ + type, method.name controller.response = response