#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2010 Maurizio Porrato # See LICENSE.txt for copyright info from twisted.internet import reactor from frn.protocol.client import FRNClient, FRNClientFactory from frn.user import FRNUser from twisted.python import log clients = [] talking = None class FRNCrosslinkClient(FRNClient): def connectionMade(self): self.txOk = False self.txReq = False self.clientId = None FRNClient.connectionMade(self) def getClientName(self, client_id): if self.clientsById.has_key(client_id): return self.clientsById[client_id]['on'] else: return client_id def textMessageReceived(self, client, message, target): global clients if target == 'A': if client != self.clientId: for _, _, _, factory in clients: if factory != self.factory: factory.connection.sendTextMessage('', message) else: if message.startswith('!'): cmd = message[1:] if cmd == "who": for server, port, u, factory in clients: cl = [] cl.append("[%s@%s:%d]" % (u.NT,server,port)) for c in factory.connection.clients: cl.append("(%s)" % (c['on'],)) reply = ' '.join(cl) self.sendTextMessage(client, reply) def decodeTX(self, my_id): log.msg("Got TX ack for %s" % self.user.ON) self.txOk = True def stopTransmission(self): FRNClient.stopTransmission(self) log.msg("Stopped TX on %s" % self.user.ON) def goIdle(self): global talking self.txReq = False self.txOk = False talking = None self.stopTransmission() def audioFrameReceived(self, from_id, frames): global clients, talking if talking is None or talking == self: talking = self for _, _, _, factory in clients: conn = factory.connection if conn != self: if conn.txOk: conn.txReq = False conn.sendAudioFrame(frames) conn.busyTimer.reset(2.0) else: if not conn.txReq: log.msg("Requesting TX for %s" % conn.user.ON) conn.startTransmission() conn.txReq = True conn.busyTimer = conn.factory.reactor.callLater( 5.0, conn.goIdle) self.pong() def loginResponse(self, info): log.msg("%s login: %s" % (self.user.ON, info['al'])) def clientsListUpdated(self, clients): self.clients = clients self.clientsById = dict([(i['id'], i) for i in clients]) if self.clientId is None: for c in clients: if c['on'] == self.user.ON and c['bc'] == self.user.BC: self.clientId = c['id'] class FRNCrosslinkClientFactory(FRNClientFactory): protocol = FRNCrosslinkClient reactor = reactor def buildProtocol(self, addr): p = FRNClientFactory.buildProtocol(self, addr) self.connection = p return p if __name__ == '__main__': import sys from os.path import dirname, join as pjoin from ConfigParser import ConfigParser log.startLogging(sys.stderr) basedir = dirname(__file__) acfg = ConfigParser() acfg.read(['/etc/grn/accounts.conf', pjoin(basedir,'accounts.conf'), 'accounts.conf']) scfg = ConfigParser() scfg.read(['/etc/grn/servers.conf', pjoin(basedir,'servers.conf'), 'servers.conf']) argc = len(sys.argv) if argc > 1: for client_data in sys.argv[1:]: account_name, server_name, network_name = client_data.split(':',2) account_cfg = acfg.items(account_name)+[('network', network_name)] server_cfg = scfg.items(server_name) server = scfg.get(server_name, 'server') port = scfg.getint(server_name, 'port') d = dict(account_cfg) user = FRNUser( EA=d['email'], PW=d['password'], ON=d['operator'], # BC=d['transmission'], DS=d['description'], BC="Crosslink", DS=d['description'], NN=d['country'], CT=d['city'], NT=d['network']) factory = FRNCrosslinkClientFactory(user) clients.append((server, port, user, factory)) reactor.connectTCP(server, port, factory) reactor.run() # vim: set et ai sw=4 ts=4 sts=4: