port mncc_test2 and gsm_call_fsm to pykka Actor framework
This commit is contained in:
parent
3d66bfbeee
commit
0679cd4b97
|
@ -7,34 +7,35 @@ import pykka
|
||||||
from fysom import Fysom
|
from fysom import Fysom
|
||||||
from mncc_sock import mncc_msg, mncc_number
|
from mncc_sock import mncc_msg, mncc_number
|
||||||
|
|
||||||
class GsmCallFsm(object):
|
class GsmCallFsm(pykka.ThreadingActor):
|
||||||
last_callref = 0
|
last_callref = 0
|
||||||
|
|
||||||
def get_next_callref(self):
|
def _get_next_callref(self):
|
||||||
GsmCallFsm.last_callref = GsmCallFsm.last_callref + 1
|
GsmCallFsm.last_callref = GsmCallFsm.last_callref + 1
|
||||||
return GsmCallFsm.last_callref;
|
return GsmCallFsm.last_callref;
|
||||||
|
|
||||||
def printstatechange(self, e):
|
def _printstatechange(self, e):
|
||||||
print 'GsmCallFsm(%s): event: %s, src: %s, dst: %s' % (self.name, e.event, e.src, e.dst)
|
print 'GsmCallFsm(%s): event: %s, src: %s, dst: %s' % (self.name, e.event, e.src, e.dst)
|
||||||
|
|
||||||
def onmncc_setup_req(self, e):
|
def _onmncc_setup_req(self, e):
|
||||||
msg = mncc_msg(msg_type = mncc.MNCC_SETUP_REQ, callref = self.callref,
|
msg = mncc_msg(msg_type = mncc.MNCC_SETUP_REQ, callref = self.callref,
|
||||||
fields = mncc.MNCC_F_CALLED | mncc.MNCC_F_CALLING,
|
fields = mncc.MNCC_F_CALLED | mncc.MNCC_F_CALLING,
|
||||||
calling = mncc_number(self.calling),
|
calling = mncc_number(self.calling),
|
||||||
called = mncc_number(self.called))
|
called = mncc_number(self.called))
|
||||||
self.mncc.send(msg)
|
self.mncc_ref.tell({'type': 'send', 'msg': msg})
|
||||||
print 'GsmCallFsm(%s): mncc_setup_req event: %s, src: %s, dst: %s' % (self.name, e.event, e.src, e.dst)
|
print 'GsmCallFsm(%s): mncc_setup_req event: %s, src: %s, dst: %s' % (self.name, e.event, e.src, e.dst)
|
||||||
|
|
||||||
def onmncc_setup_cnf(self, e):
|
def _onmncc_setup_cnf(self, e):
|
||||||
# send MNCC_SETUP_COMPL_REQ to MNCC interface, causing
|
# send MNCC_SETUP_COMPL_REQ to MNCC interface, causing
|
||||||
# CC-CONNECT-ACK to be sent to MS
|
# CC-CONNECT-ACK to be sent to MS
|
||||||
msg = mncc_msg(msg_type = mncc.MNCC_SETUP_COMPL_REQ)
|
msg = mncc_msg(msg_type = mncc.MNCC_SETUP_COMPL_REQ)
|
||||||
self.mncc.send(msg)
|
self.mncc_ref.tell({'send', msg})
|
||||||
|
|
||||||
def __init__(self, name, mncc):
|
def __init__(self, name, mncc_ref):
|
||||||
|
super(GsmCallFsm, self).__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.mncc = mncc;
|
self.mncc_ref = mncc_ref;
|
||||||
self.callref = self.get_next_callref()
|
self.callref = self._get_next_callref()
|
||||||
self.fsm = Fysom(initial = 'NULL',
|
self.fsm = Fysom(initial = 'NULL',
|
||||||
events = [
|
events = [
|
||||||
# MT call setup
|
# MT call setup
|
||||||
|
@ -77,11 +78,11 @@ class GsmCallFsm(object):
|
||||||
|
|
||||||
('mncc_rel_cnf', 'RELEASE_REQUEST', 'NULL')
|
('mncc_rel_cnf', 'RELEASE_REQUEST', 'NULL')
|
||||||
],
|
],
|
||||||
callbacks = [('onmncc_setup_req', self.onmncc_setup_req),
|
callbacks = [('onmncc_setup_req', self._onmncc_setup_req),
|
||||||
('onmncc_setup_cnf', self.onmncc_setup_cnf),
|
('onmncc_setup_cnf', self._onmncc_setup_cnf),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.fsm.onchangestate = self.printstatechange
|
self.fsm.onchangestate = self._printstatechange
|
||||||
|
|
||||||
def start_mt_call(self, calling, called):
|
def start_mt_call(self, calling, called):
|
||||||
self.calling = calling
|
self.calling = calling
|
||||||
|
@ -89,50 +90,59 @@ class GsmCallFsm(object):
|
||||||
self.fsm.mncc_setup_req()
|
self.fsm.mncc_setup_req()
|
||||||
|
|
||||||
# MT call
|
# MT call
|
||||||
def do_mncc_rel_ind(self, mncc_msg):
|
def _do_mncc_rel_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_rel_ind(mncc_msg)
|
self.fsm.mncc_rel_ind(mncc_msg)
|
||||||
def do_mncc_call_conf_ind(self, mncc_msg):
|
def _do_mncc_call_conf_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_call_conf_ind(mncc_msg)
|
self.fsm.mncc_call_conf_ind(mncc_msg)
|
||||||
def do_mncc_alert_ind(self, mncc_msg):
|
def _do_mncc_alert_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_allert_ind(mncc_msg)
|
self.fsm.mncc_allert_ind(mncc_msg)
|
||||||
def do_mncc_setup_cnf(self, mncc_msg):
|
def _do_mncc_setup_cnf(self, mncc_msg):
|
||||||
self.fsm.mncc_setup_cnf(mncc_msg)
|
self.fsm.mncc_setup_cnf(mncc_msg)
|
||||||
|
|
||||||
# MO call
|
# MO call
|
||||||
def do_mncc_setup_ind(self, mncc_msg):
|
def _do_mncc_setup_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_setup_ind(mncc_msg)
|
self.fsm.mncc_setup_ind(mncc_msg)
|
||||||
def do_mncc_setup_compl_ind(self, mncc_msg):
|
def _do_mncc_setup_compl_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_setup_compl_ind(mncc_msg)
|
self.fsm.mncc_setup_compl_ind(mncc_msg)
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
def do_mncc_disc_ind(self, mncc_msg):
|
def _do_mncc_disc_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_disc_ind(mncc_msg)
|
self.fsm.mncc_disc_ind(mncc_msg)
|
||||||
def do_mncc_rel_ind(self, mncc_msg):
|
def _do_mncc_rel_ind(self, mncc_msg):
|
||||||
self.fsm.mncc_rel_ind(mncc_msg)
|
self.fsm.mncc_rel_ind(mncc_msg)
|
||||||
def do_mncc_rel_cnf(self, mncc_msg):
|
def _do_mncc_rel_cnf(self, mncc_msg):
|
||||||
self.fsm.mncc_rel_cnf(mncc_msg)
|
self.fsm.mncc_rel_cnf(mncc_msg)
|
||||||
|
|
||||||
func_by_type = {
|
_func_by_type = {
|
||||||
# MT call
|
# MT call
|
||||||
mncc.MNCC_REL_IND: do_mncc_rel_ind,
|
mncc.MNCC_REL_IND: _do_mncc_rel_ind,
|
||||||
mncc.MNCC_CALL_CONF_IND: do_mncc_call_conf_ind,
|
mncc.MNCC_CALL_CONF_IND: _do_mncc_call_conf_ind,
|
||||||
mncc.MNCC_ALERT_IND: do_mncc_alert_ind,
|
mncc.MNCC_ALERT_IND: _do_mncc_alert_ind,
|
||||||
mncc.MNCC_SETUP_CNF: do_mncc_setup_cnf,
|
mncc.MNCC_SETUP_CNF: _do_mncc_setup_cnf,
|
||||||
|
|
||||||
# MO call
|
# MO call
|
||||||
mncc.MNCC_SETUP_IND: do_mncc_setup_ind,
|
mncc.MNCC_SETUP_IND: _do_mncc_setup_ind,
|
||||||
mncc.MNCC_SETUP_COMPL_IND: do_mncc_setup_compl_ind,
|
mncc.MNCC_SETUP_COMPL_IND: _do_mncc_setup_compl_ind,
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
mncc.MNCC_DISC_IND: do_mncc_disc_ind,
|
mncc.MNCC_DISC_IND: _do_mncc_disc_ind,
|
||||||
mncc.MNCC_REL_IND: do_mncc_rel_ind,
|
mncc.MNCC_REL_IND: _do_mncc_rel_ind,
|
||||||
mncc.MNCC_REL_CNF: do_mncc_rel_cnf,
|
mncc.MNCC_REL_CNF: _do_mncc_rel_cnf,
|
||||||
}
|
}
|
||||||
|
|
||||||
def lookup_method(self, mncc_msg_type):
|
def _lookup_method(self, mncc_msg_type):
|
||||||
return self.func_by_type[mncc_msg_type]
|
return self._func_by_type[mncc_msg_type]
|
||||||
|
|
||||||
def handle_mncc(self, mncc_msg):
|
def _handle_mncc(self, mncc_msg):
|
||||||
if mncc_msg.callref != self.callref:
|
if mncc_msg.callref != self.callref:
|
||||||
raise Exception('mncc', 'Callref not for this GsmCallFsm')
|
raise Exception('mncc', 'Callref not for this GsmCallFsm')
|
||||||
self.lookup_method(mncc_msg.msg_type)(self, mncc_msg)
|
self._lookup_method(mncc_msg.msg_type)(self, mncc_msg)
|
||||||
|
|
||||||
|
# pykka Actor message receiver
|
||||||
|
def on_receive(self, message):
|
||||||
|
if message['type'] == 'mncc':
|
||||||
|
msg = message['msg']
|
||||||
|
if msg.callref == self.callref:
|
||||||
|
return self._handle_mncc(msg)
|
||||||
|
else:
|
||||||
|
raise Exception('mncc', 'Unknown message %s' % message)
|
||||||
|
|
|
@ -2,14 +2,39 @@
|
||||||
|
|
||||||
from gsm_call_fsm import GsmCallFsm
|
from gsm_call_fsm import GsmCallFsm
|
||||||
from mncc_sock import MnccSocket
|
from mncc_sock import MnccSocket
|
||||||
|
import pykka
|
||||||
|
import logging
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class MnccActor(pykka.ThreadingActor):
|
||||||
|
def __init__(self, mncc_sock):
|
||||||
|
super(MnccActor, self).__init__()
|
||||||
|
self.mncc_sock = mncc_sock
|
||||||
|
|
||||||
|
def on_receive(self, message):
|
||||||
|
print 'MnccActor Received %s' % message
|
||||||
|
if message['type'] == 'send':
|
||||||
|
mncc_sock.send(message['msg'])
|
||||||
|
|
||||||
|
|
||||||
|
def sigint_handler(signum, frame):
|
||||||
|
pykka.ActorRegistry.stop_all()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, sigint_handler)
|
||||||
|
|
||||||
mncc_sock = MnccSocket()
|
mncc_sock = MnccSocket()
|
||||||
|
mncc_act = MnccActor.start(mncc_sock)
|
||||||
|
|
||||||
call = GsmCallFsm('foo', mncc_sock)
|
call_proxy = GsmCallFsm.start('foo', mncc_act).proxy()
|
||||||
#call.fsm.mncc_setup_req()
|
call_proxy.start_mt_call("1234", "6789")
|
||||||
call.start_mt_call("1234", "6789")
|
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
msg = mncc_sock.recv()
|
msg = mncc_sock.recv()
|
||||||
# FIXME: look-up the call based on msg.callref
|
print "Received %s from MNCC, broadcasting to Call FSMs" % msg
|
||||||
call.handle_mncc(msg)
|
# FIXME: we simply broadcast to all calls
|
||||||
|
pykka.ActorRegistry.broadcast({'type': 'mncc', 'msg': msg}, GsmCallFsm)
|
||||||
|
#pykka.ActorRegistry.broadcast({'type': 'mncc', 'msg': msg})
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
import os, sys
|
|
||||||
from twisted.python.log import startLogging
|
|
||||||
from twisted.python.filepath import FilePath
|
|
||||||
from twisted.internet.defer import Deferred
|
|
||||||
from twisted.internet.protocol import Factory, BaseProtocol
|
|
||||||
from twisted.internet.endpoints import UNIXClientEndpoint
|
|
||||||
from twisted.internet import reactor
|
|
||||||
|
|
||||||
import mncc
|
|
||||||
import ctypes
|
|
||||||
|
|
||||||
class mncc_msg(mncc.gsm_mncc):
|
|
||||||
def send(self):
|
|
||||||
return buffer(self)[:]
|
|
||||||
def receive(self, bytes):
|
|
||||||
fit = min(len(bytes), ctypes.sizeof(self))
|
|
||||||
ctypes.memmove(ctypes.addressof(self), bytes, fit)
|
|
||||||
|
|
||||||
def mncc_number(number, num_type = 0, num_plan = 0, num_present = 1, num_screen = 0):
|
|
||||||
return mncc.gsm_mncc_number(number = number, type = num_type,
|
|
||||||
plan = num_plan, present = num_present,
|
|
||||||
screen = num_screen)
|
|
||||||
|
|
||||||
class MnccProtocol(BaseProtocol):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.whenDisconnected = Deferred()
|
|
||||||
|
|
||||||
def dataReceived(self, data):
|
|
||||||
print 'received "%s"' % data
|
|
||||||
ms = mncc_msg()
|
|
||||||
ms.receive(data)
|
|
||||||
|
|
||||||
def connectionLost(self, reason):
|
|
||||||
self.whenDisconnected.callback(None)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
address = FilePath('/tmp/bsc_mncc')
|
|
||||||
startLogging(sys.stdout)
|
|
||||||
|
|
||||||
factory = Factory()
|
|
||||||
factory.protocol = MnccProtocol
|
|
||||||
factory.quiet = True
|
|
||||||
|
|
||||||
endpoint = UnixClientEndpoint(reactor, address.path)
|
|
||||||
connected = endpoint.connect(factory)
|
|
||||||
|
|
||||||
def succeded(client):
|
|
||||||
print "succeeded"
|
|
||||||
return client.whenDisconnected
|
|
||||||
def failed(reason):
|
|
||||||
print "Could not connect:", reason.getErrorMessage()
|
|
||||||
def disconnected(ignored):
|
|
||||||
print "disconnected"
|
|
||||||
reactor.stop()
|
|
||||||
|
|
||||||
connected.addCallbacks(succeeded, failed)
|
|
||||||
connected.addCallback(disconnected)
|
|
||||||
|
|
||||||
reactor.run()
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
import pykka
|
|
||||||
|
|
||||||
class Greeter(pykka.ThreadingActor):
|
|
||||||
def on_receive(self, message):
|
|
||||||
print('Hi there, you sent %s' % message)
|
|
||||||
|
|
||||||
actor_ref = Greeter.start()
|
|
||||||
|
|
||||||
actor_ref.tell({'msg': 'Hi!'})
|
|
||||||
|
|
||||||
actor_ref.stop()
|
|
Loading…
Reference in New Issue