"""
packetbruecke-relay

minimal tcp chat-server relay for packetbruecke.
starts 14 at ports from 2413 and interval 5 up until 2473
and finally 2485. each port is one above the corresponding intended
wifi channel frequency in MHz.

One or more client can connect to a port and send line based messages
that will be sent to any other clients connected to the same port but
not to itself.

2012 Bengt Sjolen
"""

from twisted.protocols import basic
import time


class Relay(basic.LineReceiver):
    delimiter="\n"
    def connectionMade(self):
        self.factory.clients.append(self)
        print "RELAY %d: Got new client, now %d!"%(self.factory.port,len(self.factory.clients))

    def connectionLost(self, reason):
        self.factory.clients.remove(self)
        print "RELAY %d: Lost a client, %d remaining!"%(self.factory.port,len(self.factory.clients))

    def lineReceived(self, line):
        if self.factory.relay:
            clients=self.factory.relay.clients
        else:
            clients=self.factory.clients
        # send to all siblings on this port
        #print "RELAY %d: relaying %d bytes to %d clients"%(self.factory.port,len(line),max(0,len(clients)-1))
        #print "   from %s to"%(len(line),repr(self)),repr(clients)
        for c in clients:
            if c!=self:
                c.message(line)
                #c.message(line)

    def message(self, message):
        #print len(self.transport.dataBuffer)
        if len(self.transport.dataBuffer)<512*1024:
            self.transport.write(message + '\n')


from twisted.internet import protocol,reactor
from twisted.application import service, internet

PORT=1025

def CreateRelayPair(port1,port2):
    print "creating relay from port "+str(port1)+" to "+str(port2 or port1)
    factory1 = protocol.ServerFactory()
    factory1.protocol = Relay
    factory1.clients = []
    factory1.relay=None
    factory1.port=port1
    if port2:
        factory2 = protocol.ServerFactory()
        factory2.protocol = Relay
        factory2.clients = []
        factory2.relay=None
        factory2.port=port2
    if port2:
        factory1.relay=factory2
        factory2.relay=factory1

    reactor.listenTCP(port1,factory1)
    if port2:
        reactor.listenTCP(port2,factory2)
        
        


def main():
    freq=2413
    for f in range(0,14):
        factory1 = protocol.ServerFactory()
        factory1.protocol = Relay
        factory1.clients = []
        if 1:
            CreateRelayPair(freq,None)
        else:
            CreateRelayPair(freq,freq+1)
        if f == 12:
            freq+=7
        freq+=5
    reactor.run()

def main_twistd():
    factory = protocol.ServerFactory()
    factory.protocol = MyChat
    factory.clients = []

    application = service.Application("chatserver")
    internet.TCPServer(PORT, factory).setServiceParent(application)

if __name__ == '__main__':
    main()
