2 # -*- coding: utf-8 -*-
4 # Copyright 2010 Maurizio Porrato <maurizio.porrato@gmail.com>
5 # See LICENSE.txt for copyright info
8 from frn
.protocol
.client
import FRNClient
, FRNClientFactory
9 from frn
.user
import FRNUser
10 from twisted
.internet
import reactor
, task
11 from twisted
.internet
.defer
import DeferredList
12 from twisted
.python
import log
14 from Queue
import Queue
15 from twisted
.internet
.task
import LoopingCall
18 from twisted
.internet
.protocol
import ProcessProtocol
20 class StreamingProtocol(ProcessProtocol
):
22 _silenceFrame
= open("sounds/silence-gsm.gsm", "rb").read()
25 self
._frames
= Queue()
26 self
._streamTimer
= LoopingCall
.withCount(self
.sendStreamFrame
)
28 def connectionMade(self
):
29 log
.msg("Streaming process started")
30 self
._streamTimer
.start(0.20)
32 def inConnectionLost(self
):
33 log
.msg("connection lost")
34 self
._streamTimer
.stop()
36 def processExited(self
, status
):
37 log
.msg("Streaming process exited (%s)" % str(status
))
39 def sendStreamFrame(self
, count
):
40 for i
in range(count
):
41 if self
._frames
.empty():
42 frames
= self
._silenceFrame
44 frames
= self
._frames
.get_nowait()
45 self
.transport
.write(frames
)
47 def feed(self
, frame
):
48 self
._frames
.put_nowait(frame
)
51 self
.transport
.closeStdin()
54 STREAM_CMD
="""tools/gsmstream.sh"""
56 class FRNStream(FRNClient
):
59 self
._stream
= StreamingProtocol()
61 def connectionMade(self
):
62 FRNClient
.connectionMade(self
)
63 reactor
.spawnProcess(self
._stream
, "bash", ["bash", "-c", STREAM_CMD
], os
.environ
)
65 def connectionLost(self
, reason
):
66 FRNClient
.connectionLost(self
, reason
)
69 def getClientName(self
, client_id
):
70 if self
.clientsById
.has_key(client_id
):
71 return self
.clientsById
[client_id
]['ON']
75 def audioFrameReceived(self
, from_id
, frames
):
76 self
._stream
.feed(frames
)
79 def loginResponse(self
, info
):
80 log
.msg("Login: %s" % info
['AL'])
82 def clientsListUpdated(self
, clients
):
83 self
.clients
= clients
84 self
.clientsById
= dict([(i
['ID'], i
) for i
in clients
])
87 class FRNStreamFactory(FRNClientFactory
):
92 if __name__
== '__main__':
94 from os
.path
import dirname
, join
as pjoin
95 from ConfigParser
import ConfigParser
97 log
.startLogging(sys
.stderr
)
99 basedir
= dirname(__file__
)
101 acfg
= ConfigParser()
102 acfg
.read(['/etc/grn/accounts.conf',
103 pjoin(basedir
,'accounts.conf'), 'accounts.conf'])
105 scfg
= ConfigParser()
106 scfg
.read(['/etc/grn/servers.conf',
107 pjoin(basedir
,'servers.conf'), 'servers.conf'])
111 server_name
, network_name
= sys
.argv
[2].split(':',1)
112 account_cfg
= acfg
.items(sys
.argv
[1])+[('network', network_name
)]
113 server_cfg
= scfg
.items(server_name
)
114 server
= scfg
.get(server_name
, 'server')
115 port
= scfg
.getint(server_name
, 'port')
117 d
= dict(account_cfg
)
120 PW
=d
['password'], ON
=d
['operator'],
121 BC
=d
['transmission'], DS
=d
['description'],
122 NN
=d
['country'], CT
=d
['city'], NT
=d
['network'])
123 reactor
.connectTCP(server
, port
, FRNStreamFactory(user
))
127 # vim: set et ai sw=4 ts=4 sts=4: