1 | # WARPnet Client<->Server Architecture |
---|
2 | # WARPnet Parameter Definitions |
---|
3 | # |
---|
4 | # Author: Siddharth Gupta |
---|
5 | |
---|
6 | from warpnet_client_definitions import * |
---|
7 | from warpnet_common_params import * |
---|
8 | from twisted.python import threadable |
---|
9 | import re |
---|
10 | from datetime import * |
---|
11 | import time |
---|
12 | |
---|
13 | EMU_RETRANSMIT_COUNT = 10 # Max retries to send the data struct |
---|
14 | EMU_WAIT_TIME = 30 # Time to wait before resending data structs |
---|
15 | |
---|
16 | class Emulator(): |
---|
17 | |
---|
18 | def __init__(self, factory): |
---|
19 | self.factory = factory |
---|
20 | self.updateComplete = False |
---|
21 | self.returnStatus = False |
---|
22 | |
---|
23 | def connect(self, ipaddress): |
---|
24 | self.sendMessage(SC_EMULATOR_PRESENT, {'ip': ipaddress}) |
---|
25 | |
---|
26 | def command(self, *args): |
---|
27 | #Concatenates all the user's arguments, delimited by spaces |
---|
28 | # Arguments are converted to strings if needed |
---|
29 | command = ' '.join(map(str,args)) |
---|
30 | return self.sendMessage(SC_EMULATOR_MSG_TO_BOX, {'msg': command + '\n'}, self.updateFromServer) |
---|
31 | |
---|
32 | |
---|
33 | def waitForUpdate(self): |
---|
34 | while reactor.running and not self.updateComplete: |
---|
35 | pass |
---|
36 | return self.returnStatus |
---|
37 | |
---|
38 | def updateFromServer(self, data, status): |
---|
39 | if status: |
---|
40 | if re.search('ace_success', data['msg']): |
---|
41 | self.returnStatus = True |
---|
42 | else: |
---|
43 | print data['msg'] |
---|
44 | self.returnStatus = False |
---|
45 | #raise Exception('ACE_ERROR (%s): %s ' % (datetime.now().strftime("%H:%M:%S"), data)) |
---|
46 | else: |
---|
47 | self.returnStatus = False |
---|
48 | self.updateComplete = True |
---|
49 | |
---|
50 | def sendMessage(self, sendType, dataDict, callback=None): |
---|
51 | self.updateComplete = False |
---|
52 | if callback != None: |
---|
53 | self.factory.dataQueue.append(EmulatorResponse(dataDict, callback, self.factory)) |
---|
54 | self.factory.sendDataToServer(sendType, dataDict) |
---|
55 | if not threadable.isInIOThread() and callback != None: |
---|
56 | return self.waitForUpdate() |
---|
57 | |
---|
58 | class EmulatorResponse(WaitForResponse): |
---|
59 | |
---|
60 | def __init__(self, dataDict, instanceToCall, factoryInstance): |
---|
61 | self.dataDict = dataDict |
---|
62 | self.instanceToCall = instanceToCall |
---|
63 | self.factoryInstance = factoryInstance |
---|
64 | |
---|
65 | self.resendCounter = 0 |
---|
66 | self.timeoutTimer = reactor.callLater(EMU_WAIT_TIME, self.timeoutExpired) |
---|
67 | |
---|
68 | def responseCheck(self, data): |
---|
69 | #print data |
---|
70 | if data['pktType'] == SC_EMULATOR_MSG_FROM_BOX: |
---|
71 | if self.timeoutTimer.active(): |
---|
72 | self.timeoutTimer.cancel() |
---|
73 | self.factoryInstance.removeFromQueue(self) |
---|
74 | self.instanceToCall(data, True) |
---|
75 | return True |
---|
76 | return False |
---|
77 | |
---|
78 | def timeoutExpired(self): |
---|
79 | self.resendCounter += 1 |
---|
80 | if self.resendCounter > EMU_RETRANSMIT_COUNT: |
---|
81 | self.factoryInstance.removeFromQueue(self) |
---|
82 | #print "too many timeouts, cancelling send" |
---|
83 | self.instanceToCall({'stat': C_TIMEOUT}, False) |
---|
84 | else: |
---|
85 | print "emulator resent after timeout: %s" % self.dataDict |
---|
86 | self.factoryInstance.sendDataToServer(SC_EMULATOR_MSG_TO_BOX, self.dataDict) |
---|
87 | self.timeoutTimer = reactor.callLater(EMU_WAIT_TIME, self.timeoutExpired) |
---|