# Twisted imports
from twisted.internet import reactor, task
from twisted.internet.defer import Deferred
-from twisted.internet.protocol import ClientFactory
+from twisted.internet.protocol import ReconnectingClientFactory, ClientFactory
try:
from twisted.internet.ssl import ClientContextFactory
except ImportError:
self.setLineMode(extra)
return
except Exception, e:
- log.msg("Traceback - ERROR in checkMessage: " + str(e))
self.setLineMode(extra)
- return
+ raise
self.gotMessage(m)
self.setLineMode(extra)
MSNEventBase.connectionMade(self)
self._setState('CONNECTED')
self.sendLine("VER %s %s" % (self._nextTransactionID(), MSN_PROTOCOL_VERSION))
+ self.factory.resetDelay()
def connectionLost(self, reason):
self._setState('DISCONNECTED')
def handle_OUT(self, params):
checkParamLen(len(params), 1, 'OUT')
+ self.factory.stopTrying()
if params[0] == "OTH": self.multipleLogin()
elif params[0] == "SSD": self.serverGoingDown()
else: raise MSNProtocolError, "Invalid Parameters received for OUT" # debug
if self.pingCheckTask:
self.pingCheckTask.stop()
self.pingCheckTask = None
+ self.factory.stopTrying()
self.sendLine("OUT")
self.transport.loseConnection()
-class NotificationFactory(ClientFactory):
+class NotificationFactory(ReconnectingClientFactory):
"""
Factory for the NotificationClient protocol.
This is basically responsible for keeping
(the whole URL is required)
@ivar status: The status of the client -- this is generally kept
up to date by the default command handlers
+ @ivar maxRetries: The number of times the factory will reconnect
+ if the connection dies because of a network error.
"""
contacts = None
passportServer = 'https://nexus.passport.com/rdr/pprdr.asp'
status = 'FLN'
protocol = NotificationClient
+ maxRetries = 5
class SwitchboardClient(MSNEventBase):
if not message.getHeader("P2P-Dest") == self.userHandle: return
packet = message.message
binaryFields = BinaryFields(packet=packet)
- if binaryFields[0] != 0:
+ if binaryFields[5] == BinaryFields.BYEGOT:
+ pass # Ignore the ACKs to SLP messages
+ elif binaryFields[0] != 0:
slpLink = self.slpLinks.get(binaryFields[0])
if not slpLink:
# Link has been killed. Ignore
return
if slpLink.remoteUser == message.userHandle:
slpLink.handlePacket(packet)
- if binaryFields[5] == BinaryFields.ACK or binaryFields[5] == BinaryFields.BYEGOT:
+ elif binaryFields[5] == BinaryFields.ACK:
pass # Ignore the ACKs to SLP messages
else:
slpMessage = MSNSLPMessage(packet)
def bufferClosed(data):
d.callback((data,))
buffer = StringBuffer(bufferClosed)
+ buffer.error = lambda: None
slpLink = SLPLink_AvatarReceive(remoteUser=msnContact.userHandle, switchboard=self, consumer=buffer, context=msnContact.msnobj.text)
self.slpLinks[slpLink.sessionID] = slpLink
return d
self.seqID = SeqID()
def killLink(self):
+ if MSNP2PDEBUG: log.msg("killLink")
def kill():
+ if MSNP2PDEBUG: log.msg("killLink - kill()")
if not self.switchboard: return
del self.switchboard.slpLinks[self.sessionID]
self.switchboard = None
else:
if slpMessage.status == "603":
self.acceptDeferred.callback((False,))
- # SLPLink is over due to decline, error or BYE
+ if MSNP2PDEBUG: log.msg("SLPLink is over due to decline, error or BYE")
self.killLink()
def wait_data_ack(self, packet):
self.handlePacket = lambda packet: None
def handleSLPMessage(self, slpMessage):
- self.killLink() # BYE or error
+ if MSNP2PDEBUG: log.msg("BYE or error")
+ self.killLink()
def close(self):
SLPLink_Send.close(self)
FileReceive.accept(self, consumer)
if not self.switchboard: return
self.sendSLPMessage("200", "application/x-msnmsgr-sessionreqbody", {"SessionID":self.sessionID}, branch=self.initialBranch)
+ self.handlePacket = self.wait_data # Moved here because sometimes the second INVITE seems to be skipped
def handleSLPMessage(self, slpMessage):
if slpMessage.method == "INVITE": # The second invite
"Listening" : "false",\
"Hashed-Nonce": "{00000000-0000-0000-0000-000000000000}"}
self.sendSLPMessage("200", "application/x-msnmsgr-transrespbody", data, branch=slpMessage.branch)
- self.handlePacket = self.wait_data
+# self.handlePacket = self.wait_data # Moved up
else:
- self.killLink() # It's either a BYE or an error
+ if MSNP2PDEBUG: log.msg("It's either a BYE or an error")
+ self.killLink()
# FIXME, do some error handling if it was an error
def doFinished(self):
"AppID" : 1,\
"Context" : context}
self.sendSLPMessage("INVITE", "application/x-msnmsgr-sessionreqbody", data)
+ self.handlePacket = self.wait_dataprep
def handleSLPMessage(self, slpMessage):
if slpMessage.status == "200":
- self.handlePacket = self.wait_dataprep
+ pass
+ #self.handlePacket = self.wait_dataprep # Moved upwards
else:
- # SLPLink is over due to error or BYE
+ if MSNP2PDEBUG: log.msg("SLPLink is over due to error or BYE")
self.killLink()
def doFinished(self):