m2ua: Merge the ASP changes from Pharo to GST
This commit is contained in:
parent
372c2e0f0b
commit
6f7e0bcf8d
6
Makefile
6
Makefile
|
@ -45,7 +45,11 @@ UA = \
|
||||||
ua/XUA.st
|
ua/XUA.st
|
||||||
|
|
||||||
M2UA = \
|
M2UA = \
|
||||||
m2ua/M2UAConstants.st m2ua/M2UAMSG.st m2ua/M2UATag.st m2ua/M2UAStates.st
|
m2ua/M2UAConstants.st m2ua/M2UAMSG.st m2ua/M2UATag.st m2ua/M2UAMessages.st \
|
||||||
|
m2ua/M2UAStates.st m2ua/M2UAAspStateMachine.st \
|
||||||
|
m2ua/M2UAApplicationServerProcess.st m2ua/M2UALayerManagement.st \
|
||||||
|
m2ua/M2UAExamples.st m2ua/M2UATerminology.st m2ua/M2UATests.st
|
||||||
|
|
||||||
|
|
||||||
OSMO = \
|
OSMO = \
|
||||||
osmo/LogAreaOsmo.st \
|
osmo/LogAreaOsmo.st \
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
"
|
||||||
|
(C) 2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
BlockClosure extend [
|
||||||
|
value: arg1 value: arg2 value: arg3 value: arg4 [
|
||||||
|
<category: '*OsmoNetwork'>
|
||||||
|
"Evaluate the receiver passing arg1, arg2, arg3 and arg4 as the parameters"
|
||||||
|
|
||||||
|
<category: 'built ins'>
|
||||||
|
<primitive: VMpr_BlockClosure_value>
|
||||||
|
SystemExceptions.WrongArgumentCount signal
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,507 @@
|
||||||
|
"
|
||||||
|
(C) 2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
Object subclass: M2UAApplicationServerProcess [
|
||||||
|
| socket asp_active_block asp_down_block asp_inactive_block asp_up_block error_block notify_block sctp_confirm_block sctp_released_block sctp_restarted_block sctp_status_block established state t_ack lastMsg on_state_change as_state |
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: 'I am a M2UA Application Server Process.
|
||||||
|
|
||||||
|
I have an internal state machine and a state and will be used by the
|
||||||
|
M2UA Layer. I am written for the usage in a Media Gateway Controller
|
||||||
|
and will also keep information about the Application Server itself.
|
||||||
|
|
||||||
|
If I need to be used on a Signalling Gateway (SG) I will need a dedicated
|
||||||
|
M2UA Application Server class and state machine.
|
||||||
|
|
||||||
|
I can currently only manage a single interface. The specification allows
|
||||||
|
a single ASP to send one ASPActive for one interface at a time.'>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcess class >> initWith: aService [
|
||||||
|
^self new
|
||||||
|
socketService: aService;
|
||||||
|
yourself
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAApplicationServerProcess class >> new [
|
||||||
|
^super new
|
||||||
|
initialize;
|
||||||
|
yourself
|
||||||
|
]
|
||||||
|
|
||||||
|
onError: aBlock [
|
||||||
|
"M-ERROR indication
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP or SGP reports that it has received an ERROR
|
||||||
|
message from its peer."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement'>
|
||||||
|
error_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onNotify: aBlock [
|
||||||
|
"M-NOTIFY indication
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports that it has received a NOTIFY message
|
||||||
|
from its peer."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement'>
|
||||||
|
notify_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onSctpEstablished: aBlock [
|
||||||
|
"M-SCTP_ESTABLISH confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP confirms to LM that it has established an SCTP association with an SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
sctp_confirm_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onSctpReleased: aBlock [
|
||||||
|
"M-SCTP_RELEASE confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP confirms to LM that it has released SCTP association with SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
sctp_released_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onSctpRestarted: aBlock [
|
||||||
|
"M-SCTP_RELEASE indication
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: SGP informs LM that ASP has released an SCTP association."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
sctp_restarted_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onSctpStatus: aBlock [
|
||||||
|
"M-SCTP_STATUS indication
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: M2UA reports status of SCTP association."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
sctp_status_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpEstablish [
|
||||||
|
"M-SCTP_ESTABLISH request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to establish an SCTP association with an SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
established := false.
|
||||||
|
socket stop.
|
||||||
|
socket start
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpRelease [
|
||||||
|
"M-SCTP_RELEASE request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to release an SCTP association with SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
established := false.
|
||||||
|
socket stop.
|
||||||
|
t_ack ifNotNil: [t_ack cancel]
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpStatusRequest [
|
||||||
|
"M-SCTP_STATUS request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests M2UA to report status of SCTP association."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-SCTP'>
|
||||||
|
self notYetImplemented
|
||||||
|
]
|
||||||
|
|
||||||
|
aspActive [
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
"M-ASP_ACTIVE request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to send an ASP ACTIVE message to the SGP."
|
||||||
|
|
||||||
|
| msg |
|
||||||
|
self checkNextState: M2UAAspStateActive.
|
||||||
|
msg := M2UAMSG new
|
||||||
|
class: M2UAConstants clsASPTM;
|
||||||
|
msgType: M2UAConstants asptmActiv;
|
||||||
|
addTag: self createIdentIntTag;
|
||||||
|
addTag: self createInfoTag;
|
||||||
|
yourself.
|
||||||
|
self send: msg
|
||||||
|
]
|
||||||
|
|
||||||
|
aspDown [
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
"M-ASP_DOWN request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to stop its operation and send an ASP DOWN
|
||||||
|
message to the SGP."
|
||||||
|
|
||||||
|
| msg |
|
||||||
|
self checkNextState: M2UAAspStateDown.
|
||||||
|
msg := M2UAMSG new
|
||||||
|
class: M2UAConstants clsASPSM;
|
||||||
|
msgType: M2UAConstants aspsmDown;
|
||||||
|
addTag: self createAspIdentTag;
|
||||||
|
addTag: self createInfoTag;
|
||||||
|
yourself.
|
||||||
|
self send: msg
|
||||||
|
]
|
||||||
|
|
||||||
|
aspInactive [
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
"M-ASP_INACTIVE request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to send an ASP INACTIVE message to the SGP."
|
||||||
|
|
||||||
|
| msg |
|
||||||
|
self checkNextState: M2UAAspStateInactive.
|
||||||
|
msg := M2UAMSG new
|
||||||
|
class: M2UAConstants clsASPTM;
|
||||||
|
msgType: M2UAConstants asptmInactiv;
|
||||||
|
addTag: self createIdentIntTag;
|
||||||
|
addTag: self createInfoTag;
|
||||||
|
yourself.
|
||||||
|
self send: msg
|
||||||
|
]
|
||||||
|
|
||||||
|
aspUp [
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
"M-ASP_UP request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to start its operation and send an ASP UP
|
||||||
|
message to the SGP."
|
||||||
|
|
||||||
|
| msg |
|
||||||
|
self checkNextState: M2UAAspStateInactive.
|
||||||
|
msg := M2UAMSG new
|
||||||
|
class: M2UAConstants clsASPSM;
|
||||||
|
msgType: M2UAConstants aspsmUp;
|
||||||
|
addTag: self createAspIdentTag;
|
||||||
|
addTag: self createInfoTag;
|
||||||
|
yourself.
|
||||||
|
self send: msg
|
||||||
|
]
|
||||||
|
|
||||||
|
onAspActive: aBlock [
|
||||||
|
"M-ASP_ACTIVE confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports that is has received an ASP ACTIVE
|
||||||
|
Acknowledgment message from the SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
asp_active_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onAspDown: aBlock [
|
||||||
|
"M-ASP_DOWN confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports that is has received an ASP DOWN Acknowledgment
|
||||||
|
message from the SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
asp_down_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onAspInactive: aBlock [
|
||||||
|
"M-ASP_INACTIVE confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports that is has received an ASP INACTIVE
|
||||||
|
Acknowledgment message from the SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
asp_inactive_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onAspUp: aBlock [
|
||||||
|
"M-ASP_UP confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports that it has received an ASP UP Acknowledgment
|
||||||
|
message from the SGP."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
asp_up_block := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onStateChange: aBlock [
|
||||||
|
"A generic callback for all state changes"
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagemennt-ASP'>
|
||||||
|
on_state_change := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
deregisterLinkKey [
|
||||||
|
"M-LINK_KEY_DEREG Request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to de-register Link Key with SG by sending
|
||||||
|
DEREG REQ message."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-LinkKey'>
|
||||||
|
self notYetImplemented
|
||||||
|
]
|
||||||
|
|
||||||
|
onLinkKeyDeregistered: aBlock [
|
||||||
|
"M-LINK_KEY_DEREG Confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports to LM that it has successfully received a
|
||||||
|
DEREG RSP message from SG."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-LinkKey'>
|
||||||
|
self notYetImplemented
|
||||||
|
]
|
||||||
|
|
||||||
|
onLinkKeyRegistered: aBlock [
|
||||||
|
"M-LINK_KEY_REG Confirm
|
||||||
|
Direction: M2UA -> LM
|
||||||
|
Purpose: ASP reports to LM that it has successfully received a REG
|
||||||
|
RSP message from SG."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-LinkKey'>
|
||||||
|
self notYetImplemented
|
||||||
|
]
|
||||||
|
|
||||||
|
registerLinkKey [
|
||||||
|
"M-LINK_KEY_REG Request
|
||||||
|
Direction: LM -> M2UA
|
||||||
|
Purpose: LM requests ASP to register Link Key with SG by sending REG
|
||||||
|
REQ message."
|
||||||
|
|
||||||
|
<category: 'Primitives-LayerManagement-LinkKey'>
|
||||||
|
self notYetImplemented
|
||||||
|
]
|
||||||
|
|
||||||
|
hostname: aHostname port: aPort [
|
||||||
|
"Select the SCTP hostname/port for the SG to connect to"
|
||||||
|
|
||||||
|
<category: 'configuration'>
|
||||||
|
socket
|
||||||
|
hostname: aHostname;
|
||||||
|
port: aPort
|
||||||
|
]
|
||||||
|
|
||||||
|
createAspIdentTag [
|
||||||
|
<category: 'm2ua-tags'>
|
||||||
|
^M2UATag initWith: M2UAConstants tagAspIdent data: #(1 2 3 4)
|
||||||
|
]
|
||||||
|
|
||||||
|
createIdentIntTag [
|
||||||
|
<category: 'm2ua-tags'>
|
||||||
|
^M2UATag initWith: M2UAConstants tagIdentInt data: #(0 0 0 0)
|
||||||
|
]
|
||||||
|
|
||||||
|
createInfoTag [
|
||||||
|
<category: 'm2ua-tags'>
|
||||||
|
^M2UATag initWith: M2UAConstants tagInfo
|
||||||
|
data: 'Hello from Smalltalk' asByteArray
|
||||||
|
]
|
||||||
|
|
||||||
|
callNotification: aBlock [
|
||||||
|
"Inform the generic method first, then all the others"
|
||||||
|
|
||||||
|
<category: 'private'>
|
||||||
|
on_state_change ifNotNil: [on_state_change value].
|
||||||
|
aBlock ifNotNil: [aBlock value]
|
||||||
|
]
|
||||||
|
|
||||||
|
checkNextState: nextState [
|
||||||
|
"Check if nextState and state are compatible and if not
|
||||||
|
throw an exception. TODO:"
|
||||||
|
|
||||||
|
<category: 'private'>
|
||||||
|
self state = nextState
|
||||||
|
ifTrue:
|
||||||
|
[^self error: ('M2UA ASP already in state <1p>' expandMacrosWith: state)].
|
||||||
|
(self state nextPossibleStates includes: nextState)
|
||||||
|
ifFalse:
|
||||||
|
[^self error: ('M2UA ASP illegal state transition from <1p> to <2p>.'
|
||||||
|
expandMacrosWith: state
|
||||||
|
with: nextState)]
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchData: aByteArray [
|
||||||
|
<category: 'private'>
|
||||||
|
| msg |
|
||||||
|
msg := M2UAMSG parseToClass: aByteArray.
|
||||||
|
msg dispatchOnAsp: self
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchNotification: aBlock [
|
||||||
|
<category: 'private'>
|
||||||
|
aBlock value
|
||||||
|
]
|
||||||
|
|
||||||
|
internalReset [
|
||||||
|
<category: 'private'>
|
||||||
|
self socketService: socket
|
||||||
|
]
|
||||||
|
|
||||||
|
moveToState: newState [
|
||||||
|
<category: 'private'>
|
||||||
|
((state nextPossibleStates includes: newState) or: [state = newState])
|
||||||
|
ifFalse:
|
||||||
|
[^self error: ('M2UA ASP Illegal state transition from <1p> to <2p>'
|
||||||
|
expandMacrosWith: state
|
||||||
|
with: newState)].
|
||||||
|
|
||||||
|
"TODO: general on entry, on exit"
|
||||||
|
state := newState
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpConnected [
|
||||||
|
<category: 'private'>
|
||||||
|
"The connect was issued."
|
||||||
|
|
||||||
|
| wasEstablished |
|
||||||
|
wasEstablished := established.
|
||||||
|
established := true.
|
||||||
|
state := M2UAAspStateDown.
|
||||||
|
t_ack ifNotNil: [t_ack cancel].
|
||||||
|
wasEstablished = true
|
||||||
|
ifTrue: [sctp_confirm_block ifNotNil: [sctp_confirm_block value]]
|
||||||
|
ifFalse: [sctp_restarted_block ifNotNil: [sctp_restarted_block value]]
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpReleased [
|
||||||
|
"The SCTP connection has been released."
|
||||||
|
|
||||||
|
<category: 'private'>
|
||||||
|
self moveToState: M2UAAspStateDown.
|
||||||
|
established = true ifFalse: [^self].
|
||||||
|
sctp_released_block ifNotNil: [sctp_released_block value]
|
||||||
|
]
|
||||||
|
|
||||||
|
send: aMsg [
|
||||||
|
"Forget about what we did before"
|
||||||
|
|
||||||
|
<category: 'private'>
|
||||||
|
t_ack ifNotNil: [t_ack cancel].
|
||||||
|
t_ack := TimerScheduler instance scheduleInSeconds: 2
|
||||||
|
block:
|
||||||
|
["Re-send the message"
|
||||||
|
|
||||||
|
self logNotice: ('<1p>:<2p> Sending message has timed out'
|
||||||
|
expandMacrosWith: socket hostname
|
||||||
|
with: socket port)
|
||||||
|
area: #m2ua.
|
||||||
|
self send: aMsg].
|
||||||
|
socket nextPut: aMsg toMessage asByteArray
|
||||||
|
]
|
||||||
|
|
||||||
|
initialize [
|
||||||
|
<category: 'creation'>
|
||||||
|
state := M2UAAspStateDown
|
||||||
|
]
|
||||||
|
|
||||||
|
socketService: aService [
|
||||||
|
<category: 'creation'>
|
||||||
|
socket := aService.
|
||||||
|
socket
|
||||||
|
onSctpConnect: [self sctpConnected];
|
||||||
|
onSctpReleased: [self sctpReleased];
|
||||||
|
onSctpData:
|
||||||
|
[:stream :assoc :ppid :data |
|
||||||
|
ppid = 2
|
||||||
|
ifFalse:
|
||||||
|
[^self logNotice: 'M2UAApplicationServerProcess expecting PPID 2.'
|
||||||
|
area: #m2ua].
|
||||||
|
self dispatchData: data]
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspActiveAck: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
t_ack cancel.
|
||||||
|
self moveToState: M2UAAspStateActive.
|
||||||
|
self callNotification: asp_active_block
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspDownAck: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
t_ack cancel.
|
||||||
|
as_state := nil.
|
||||||
|
self moveToState: M2UAAspStateDown.
|
||||||
|
self callNotification: asp_down_block
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspInactiveAck: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
t_ack cancel.
|
||||||
|
as_state := nil.
|
||||||
|
self moveToState: M2UAAspStateInactive.
|
||||||
|
self callNotification: asp_inactive_block
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspUpAck: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
t_ack cancel.
|
||||||
|
self moveToState: M2UAAspStateInactive.
|
||||||
|
self callNotification: asp_inactive_block
|
||||||
|
]
|
||||||
|
|
||||||
|
handleError: aMsg [
|
||||||
|
"Cancel pending operations.. because something went wrong"
|
||||||
|
|
||||||
|
<category: 'dispatch'>
|
||||||
|
t_ack cancel.
|
||||||
|
error_block ifNotNil: [error_block value: aMsg]
|
||||||
|
]
|
||||||
|
|
||||||
|
handleNotify: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
"Extract the status"
|
||||||
|
|
||||||
|
| tag type ident |
|
||||||
|
tag := aMsg findTag: M2UAConstants tagStatus.
|
||||||
|
tag ifNil: [^self].
|
||||||
|
type := (tag data ushortAt: 1) swap16.
|
||||||
|
ident := (tag data ushortAt: 3) swap16.
|
||||||
|
type = M2UAConstants ntfyKindStateChange ifTrue: [as_state := ident].
|
||||||
|
|
||||||
|
"Inform our user about it"
|
||||||
|
notify_block ifNotNil: [notify_block value: type value: ident]
|
||||||
|
]
|
||||||
|
|
||||||
|
handleUnknownMessage: aMsg [
|
||||||
|
"We got something we don't know. ignore it for now."
|
||||||
|
|
||||||
|
<category: 'dispatch'>
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
isASActive [
|
||||||
|
<category: 'status'>
|
||||||
|
^as_state = M2UAConstants ntfyStateASActive
|
||||||
|
]
|
||||||
|
|
||||||
|
isASInactive [
|
||||||
|
<category: 'status'>
|
||||||
|
^as_state = M2UAConstants ntfyStateASInactive
|
||||||
|
]
|
||||||
|
|
||||||
|
isASPending [
|
||||||
|
<category: 'status'>
|
||||||
|
^as_state = M2UAConstants ntfyStateASPending
|
||||||
|
]
|
||||||
|
|
||||||
|
state [
|
||||||
|
<category: 'accessing'>
|
||||||
|
^state
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,106 @@
|
||||||
|
"
|
||||||
|
(C) 2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
Object subclass: M2UAAspStateMachine [
|
||||||
|
| state |
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA-States'>
|
||||||
|
<comment: 'I am the Application Server Process State machine. An
|
||||||
|
pplication Server Process will create me to manage the state. My state
|
||||||
|
machine is driven by calling the selectors from the events protocol.
|
||||||
|
If you ask for an illegal state transition a DNU will be raised. Ath
|
||||||
|
this point you should probably reset what you are doing and do proper
|
||||||
|
error reporting.
|
||||||
|
|
||||||
|
This class is currently not used!'>
|
||||||
|
|
||||||
|
M2UAAspStateMachine class >> initialState [
|
||||||
|
^M2UAAspStateDown
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAAspStateMachine class >> new [
|
||||||
|
^(self basicNew)
|
||||||
|
initialize;
|
||||||
|
yourself
|
||||||
|
]
|
||||||
|
|
||||||
|
entered: aState [
|
||||||
|
aState entered
|
||||||
|
|
||||||
|
"TODO notify users of the machine"
|
||||||
|
]
|
||||||
|
|
||||||
|
initialize [
|
||||||
|
state := self class initialState on: self
|
||||||
|
]
|
||||||
|
|
||||||
|
left: aState [
|
||||||
|
aState left
|
||||||
|
|
||||||
|
"TODO notify users of the machine"
|
||||||
|
]
|
||||||
|
|
||||||
|
moveToState: aNewState [
|
||||||
|
| oldState |
|
||||||
|
oldState := state.
|
||||||
|
state := (aNewState new)
|
||||||
|
machine: self;
|
||||||
|
yourself.
|
||||||
|
self left: oldState.
|
||||||
|
self entered: state
|
||||||
|
]
|
||||||
|
|
||||||
|
state [
|
||||||
|
^state class
|
||||||
|
]
|
||||||
|
|
||||||
|
aspActive: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onAspActive: anEvent
|
||||||
|
]
|
||||||
|
|
||||||
|
aspDown: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onAspDown: anEvent
|
||||||
|
]
|
||||||
|
|
||||||
|
aspInactive: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onAspInactive: anEvent
|
||||||
|
]
|
||||||
|
|
||||||
|
aspUp: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onAspUp: anEvent
|
||||||
|
]
|
||||||
|
|
||||||
|
otherAspInAsOverrides: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onOtherAspInAsOverrides: anEvent
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpCdi: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onSctpCdi: anEvent
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpRi: anEvent [
|
||||||
|
<category: 'events'>
|
||||||
|
state onSctpRi: anEvent
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,42 @@
|
||||||
|
"
|
||||||
|
(C) 2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
Object subclass: M2UAExamples [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
createAsp [
|
||||||
|
"Create a SCTP network service"
|
||||||
|
|
||||||
|
| service asp manager |
|
||||||
|
service := SCTPNetworkService new
|
||||||
|
hostname: 'localhost';
|
||||||
|
port: 2904;
|
||||||
|
yourself.
|
||||||
|
"Create the ASP"
|
||||||
|
asp := M2UAApplicationServerProcess initWith: service.
|
||||||
|
|
||||||
|
"Create a Layer Management (LM) and start it"
|
||||||
|
manager := M2UALayerManagement new
|
||||||
|
applicationServerProcess: asp;
|
||||||
|
targetState: M2UAAspStateActive;
|
||||||
|
yourself.
|
||||||
|
manager manage
|
||||||
|
]
|
||||||
|
]
|
|
@ -0,0 +1,127 @@
|
||||||
|
"
|
||||||
|
(C) 2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
Object subclass: M2UALayerManagement [
|
||||||
|
| targetState managedProcess |
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: 'I am taking the LayerManagement control for an M2UAApplicationServiceProcess.
|
||||||
|
|
||||||
|
Currently you can tell me the ASP state this class should be in
|
||||||
|
and I will react to to the events from the ASP.'>
|
||||||
|
|
||||||
|
applicationServerProcess: aProcess [
|
||||||
|
<category: 'creation'>
|
||||||
|
managedProcess := aProcess.
|
||||||
|
managedProcess
|
||||||
|
onSctpEstablished: [self sctpEstablished];
|
||||||
|
onSctpRestarted: [self sctpEstablished];
|
||||||
|
onError: [:msg | self m2uaError: msg];
|
||||||
|
onNotify: [:type :ident | self m2uaNotify: type ident: ident];
|
||||||
|
onAspActive: [self m2uaActive];
|
||||||
|
onAspInactive: [self m2uaInactive];
|
||||||
|
onAspDown: [self m2uaDown];
|
||||||
|
onAspUp: [self m2uaUp]
|
||||||
|
]
|
||||||
|
|
||||||
|
manage [
|
||||||
|
"I begin to manage the process."
|
||||||
|
|
||||||
|
<category: 'creation'>
|
||||||
|
managedProcess
|
||||||
|
sctpRelease;
|
||||||
|
sctpEstablish
|
||||||
|
]
|
||||||
|
|
||||||
|
targetState: aState [
|
||||||
|
"Use the M2UAAspState subclasses for the states"
|
||||||
|
|
||||||
|
<category: 'creation'>
|
||||||
|
targetState := aState
|
||||||
|
]
|
||||||
|
|
||||||
|
applicationServerProcess [
|
||||||
|
<category: 'accessing'>
|
||||||
|
^managedProcess
|
||||||
|
]
|
||||||
|
|
||||||
|
m2uaActive [
|
||||||
|
"E.g if the target state is already reached"
|
||||||
|
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
managedProcess state = targetState ifTrue: [^self targetReached].
|
||||||
|
targetState = M2UAAspStateInactive
|
||||||
|
ifTrue: [managedProcess aspInactive]
|
||||||
|
ifFalse: [managedProcess aspDown]
|
||||||
|
]
|
||||||
|
|
||||||
|
m2uaDown [
|
||||||
|
"E.g if the target state is already reached"
|
||||||
|
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
managedProcess state = targetState ifTrue: [^self targetReached].
|
||||||
|
|
||||||
|
"There is only one way forward"
|
||||||
|
managedProcess aspUp
|
||||||
|
]
|
||||||
|
|
||||||
|
m2uaError: aMsg [
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
self logNotice: 'M2UA Error.' area: #m2ua
|
||||||
|
]
|
||||||
|
|
||||||
|
m2uaInactive [
|
||||||
|
"E.g if the target state is already reached"
|
||||||
|
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
managedProcess state = targetState ifTrue: [^self targetReached].
|
||||||
|
targetState = M2UAAspStateActive
|
||||||
|
ifTrue: [managedProcess aspActive]
|
||||||
|
ifFalse: [managedProcess aspDown]
|
||||||
|
]
|
||||||
|
|
||||||
|
m2uaNotify: type ident: ident [
|
||||||
|
"TODO: Check the type/ident"
|
||||||
|
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
m2uaUp [
|
||||||
|
"E.g if the target state is already reached"
|
||||||
|
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
managedProcess state = targetState ifTrue: [^self targetReached].
|
||||||
|
targetState = M2UAAspStateActive
|
||||||
|
ifTrue: [managedProcess aspActive]
|
||||||
|
ifFalse: [managedProcess aspInactive]
|
||||||
|
]
|
||||||
|
|
||||||
|
sctpEstablished [
|
||||||
|
"E.g if the target state is already reached"
|
||||||
|
|
||||||
|
<category: 'as-process-callbacks'>
|
||||||
|
managedProcess state = targetState ifTrue: [^self].
|
||||||
|
"There is only one way forward"
|
||||||
|
managedProcess aspUp
|
||||||
|
]
|
||||||
|
|
||||||
|
targetReached [
|
||||||
|
|
||||||
|
]
|
||||||
|
]
|
154
m2ua/M2UAMSG.st
154
m2ua/M2UAMSG.st
|
@ -57,6 +57,41 @@ struct m2ua_parameter_hdr {
|
||||||
yourself.
|
yourself.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
M2UAMSG class >> copyFrom: aMsg [
|
||||||
|
<category: 'parsing'>
|
||||||
|
^ self new
|
||||||
|
msgClass: aMsg msgClass;
|
||||||
|
msgType: aMsg msgType;
|
||||||
|
tags: aMsg tags;
|
||||||
|
yourself
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAMSG class >> parseToClass: aMsg [
|
||||||
|
<category: 'parsing'>
|
||||||
|
"This will attempt to parse the message into one of the
|
||||||
|
available subclasses."
|
||||||
|
|
||||||
|
| rawMsg msgClasses |
|
||||||
|
rawMsg := self parseFrom: aMsg.
|
||||||
|
|
||||||
|
"A simple class based lookup"
|
||||||
|
msgClasses :=
|
||||||
|
{M2UAASPSMMessage.
|
||||||
|
M2UAASPTMMessage.
|
||||||
|
M2UAASPMGMTMessage}.
|
||||||
|
msgClasses do:
|
||||||
|
[:msgClass |
|
||||||
|
rawMsg msgClass = msgClass messageClass
|
||||||
|
ifTrue:
|
||||||
|
[msgClass allSubclassesDo: [:class |
|
||||||
|
class messageTag = rawMsg msgType
|
||||||
|
ifTrue: [^class copyFrom: rawMsg]]]].
|
||||||
|
|
||||||
|
^self error: ('Unknown message class (<1p>) or message type (<2p>)'
|
||||||
|
expandMacrosWith: rawMsg msgClass
|
||||||
|
with: rawMsg msgType)
|
||||||
|
]
|
||||||
|
|
||||||
msgClass [
|
msgClass [
|
||||||
<category: 'accessing'>
|
<category: 'accessing'>
|
||||||
^ msg_class
|
^ msg_class
|
||||||
|
@ -67,6 +102,13 @@ struct m2ua_parameter_hdr {
|
||||||
^ msg_type
|
^ msg_type
|
||||||
]
|
]
|
||||||
|
|
||||||
|
findTag: aTag [
|
||||||
|
"I find a tag with a tag identifier"
|
||||||
|
|
||||||
|
<category: 'accessing'>
|
||||||
|
^self findTag: aTag ifAbsent: [nil]
|
||||||
|
]
|
||||||
|
|
||||||
findTag: aTag ifAbsent: aBlock [
|
findTag: aTag ifAbsent: aBlock [
|
||||||
"I find a tag with a tag identifier"
|
"I find a tag with a tag identifier"
|
||||||
<category: 'accessing'>
|
<category: 'accessing'>
|
||||||
|
@ -85,42 +127,61 @@ struct m2ua_parameter_hdr {
|
||||||
]
|
]
|
||||||
|
|
||||||
parseFrom: aStream [
|
parseFrom: aStream [
|
||||||
| version spare len end |
|
<category: 'parsing'>
|
||||||
<category: 'parsing'>
|
| len |
|
||||||
|
self parseVersion: aStream.
|
||||||
version := aStream next.
|
self parseSpare: aStream.
|
||||||
version = M2UAConstants version ifFalse: [
|
msg_class := aStream next.
|
||||||
self logError:
|
msg_type := aStream next.
|
||||||
('M2UA version is wrong <1p>.' expandMacrosWith: version) area: #m2ua.
|
len := self parseLength: aStream.
|
||||||
self error: ('M2UA version is wrong <1p>.' expandMacrosWith: version).
|
tags := self parseTags: aStream to: aStream position + len - 8
|
||||||
].
|
|
||||||
|
|
||||||
spare := aStream next.
|
|
||||||
spare = M2UAConstants spare ifFalse: [
|
|
||||||
self logError: ('M2UA spare is wrong <1p>.' expandMacrosWith: spare) area: #m2ua.
|
|
||||||
self error: ('M2UA spare is wrong <1p>.' expandMacrosWith: spare).
|
|
||||||
].
|
|
||||||
|
|
||||||
msg_class := aStream next.
|
|
||||||
msg_type := aStream next.
|
|
||||||
|
|
||||||
len := ((aStream next: 4) uintAt: 1) swap32.
|
|
||||||
aStream size - aStream position < (len - 8) ifTrue: [
|
|
||||||
self logError: ('M2UA length is not plausible <1p> <2p>.'
|
|
||||||
expandMacrosWith: len with: aStream size - aStream position)
|
|
||||||
area: #m2ua.
|
|
||||||
self error: ('M2UA length is not plausible <1p> <2p>.'
|
|
||||||
expandMacrosWith: len with: aStream size - aStream position).
|
|
||||||
].
|
|
||||||
|
|
||||||
tags := OrderedCollection new.
|
|
||||||
end := aStream position + len - 8.
|
|
||||||
|
|
||||||
[aStream position < end] whileTrue: [
|
|
||||||
tags add: (M2UATag fromStream: aStream)
|
|
||||||
].
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
parseLength: aStream [
|
||||||
|
<category: 'parsing'>
|
||||||
|
| len |
|
||||||
|
len := ((aStream next: 4) uintAt: 1) swap32.
|
||||||
|
aStream size - aStream position < (len - 8)
|
||||||
|
ifTrue:
|
||||||
|
[self
|
||||||
|
logError: ('M2UA length is not plausible <1p> <2p>.' expandMacrosWith: len
|
||||||
|
with: aStream size - aStream position)
|
||||||
|
area: #m2ua.
|
||||||
|
self
|
||||||
|
error: ('M2UA length is not plausible <1p> <2p>.' expandMacrosWith: len
|
||||||
|
with: aStream size - aStream position)].
|
||||||
|
^len
|
||||||
|
]
|
||||||
|
|
||||||
|
parseSpare: aStream [
|
||||||
|
<category: 'parsing'>
|
||||||
|
| spare |
|
||||||
|
spare := aStream next.
|
||||||
|
spare = M2UAConstants spare
|
||||||
|
ifFalse:
|
||||||
|
[self logError: ('M2UA spare is wrong <1p>.' expandMacrosWith: spare)
|
||||||
|
area: #m2ua.
|
||||||
|
self error: ('M2UA spare is wrong <1p>.' expandMacrosWith: spare)]
|
||||||
|
]
|
||||||
|
|
||||||
|
parseTags: aStream to: end [
|
||||||
|
<category: 'parsing'>
|
||||||
|
tags := OrderedCollection new.
|
||||||
|
[aStream position < end]
|
||||||
|
whileTrue: [tags add: (M2UATag fromStream: aStream)].
|
||||||
|
^tags
|
||||||
|
]
|
||||||
|
|
||||||
|
parseVersion: aStream [
|
||||||
|
<category: 'parsing'>
|
||||||
|
| version |
|
||||||
|
version := aStream next.
|
||||||
|
version = M2UAConstants version
|
||||||
|
ifFalse:
|
||||||
|
[self logError: ('M2UA version is wrong <1p>.' expandMacrosWith: version)
|
||||||
|
area: #m2ua.
|
||||||
|
self error: ('M2UA version is wrong <1p>.' expandMacrosWith: version)]
|
||||||
|
]
|
||||||
addTag: aTag [
|
addTag: aTag [
|
||||||
<category: 'encoding'>
|
<category: 'encoding'>
|
||||||
self tags add: aTag.
|
self tags add: aTag.
|
||||||
|
@ -143,5 +204,30 @@ struct m2ua_parameter_hdr {
|
||||||
aMsg putLen32: tag_data size + 8.
|
aMsg putLen32: tag_data size + 8.
|
||||||
aMsg putByteArray: tag_data.
|
aMsg putByteArray: tag_data.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class: aClass [
|
||||||
|
<category: 'creation'>
|
||||||
|
msg_class := aClass
|
||||||
|
]
|
||||||
|
|
||||||
|
msgClass: aClass [
|
||||||
|
<category: 'creation'>
|
||||||
|
self class: aClass
|
||||||
|
]
|
||||||
|
|
||||||
|
msgType: aType [
|
||||||
|
<category: 'creation'>
|
||||||
|
msg_type := aType
|
||||||
|
]
|
||||||
|
|
||||||
|
tags: aTags [
|
||||||
|
<category: 'creation'>
|
||||||
|
tags := aTags
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleUnknownMessage: self
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,217 @@
|
||||||
|
"
|
||||||
|
(C) 2011-2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
M2UAMSG subclass: M2UAASPSMMessage [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: 'Application Server Process State Maintenance (ASPSM) messages'>
|
||||||
|
|
||||||
|
M2UAASPSMMessage class >> messageClass [
|
||||||
|
^M2UAConstants clsASPSM
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAMSG subclass: M2UAASPTMMessage [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAASPTMMessage class >> messageClass [
|
||||||
|
^M2UAConstants clsASPTM
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAMSG subclass: M2UAASPMGMTMessage [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAASPMGMTMessage class >> messageClass [
|
||||||
|
^M2UAConstants clsMgmt
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPSMMessage subclass: M2UAApplicationServerProcessHeartbeatAck [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessHeartbeatAck class >> messageTag [
|
||||||
|
^M2UAConstants aspsmBeatAck
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPSMMessage subclass: M2UAApplicationServerProcessDown [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessDown class >> messageTag [
|
||||||
|
^M2UAConstants aspsmDown
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspDown: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPSMMessage subclass: M2UAApplicationServerProcessHeartbeat [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessHeartbeat class >> messageTag [
|
||||||
|
^M2UAConstants aspsmBeat
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPSMMessage subclass: M2UAApplicationServerProcessDownAck [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessDownAck class >> messageTag [
|
||||||
|
^M2UAConstants aspsmDownAck
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspDownAck: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPSMMessage subclass: M2UAApplicationServerProcessUp [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessUp class >> messageTag [
|
||||||
|
^M2UAConstants aspsmUp
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspUp: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPTMMessage subclass: M2UAApplicationServerProcessInactiveAck [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessInactiveAck class >> messageTag [
|
||||||
|
^M2UAConstants asptmInactivAck
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspInactiveAck: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPTMMessage subclass: M2UAApplicationServerProcessActive [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessActive class >> messageTag [
|
||||||
|
^M2UAConstants asptmActiv
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspActive: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPTMMessage subclass: M2UAApplicationServerProcessInactive [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessInactive class >> messageTag [
|
||||||
|
^M2UAConstants asptmInactiv
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspInactive: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPMGMTMessage subclass: M2UAApplicationServerProcessNotify [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessNotify class >> messageTag [
|
||||||
|
^M2UAConstants mgmtNtfy
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleNotify: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPMGMTMessage subclass: M2UAApplicationServerProcessError [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessError class >> messageTag [
|
||||||
|
^M2UAConstants mgmtError
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleError: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPTMMessage subclass: M2UAApplicationServerProcessActiveAck [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessActiveAck class >> messageTag [
|
||||||
|
^M2UAConstants asptmActivAck
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspActiveAck: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
M2UAASPSMMessage subclass: M2UAApplicationServerProcessUpAck [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAApplicationServerProcessUpAck class >> messageTag [
|
||||||
|
^M2UAConstants aspsmUpAck
|
||||||
|
]
|
||||||
|
|
||||||
|
dispatchOnAsp: anAsp [
|
||||||
|
<category: 'm2ua-asp-dispatch'>
|
||||||
|
anAsp handleAspUpAck: self
|
||||||
|
]
|
||||||
|
]
|
|
@ -42,6 +42,7 @@ STInST.RBProgramNodeVisitor subclass: M2UAStateMachineVisitor [
|
||||||
|
|
||||||
|
|
||||||
Object subclass: M2UAStateBase [
|
Object subclass: M2UAStateBase [
|
||||||
|
| machine |
|
||||||
|
|
||||||
<category: 'OsmoNetwork-M2UA-States'>
|
<category: 'OsmoNetwork-M2UA-States'>
|
||||||
<comment: 'I am the base class of all M2UA state machines. My direct subclasses are state machines and their subclasses are the individual states that make up the statemachine.'>
|
<comment: 'I am the base class of all M2UA state machines. My direct subclasses are state machines and their subclasses are the individual states that make up the statemachine.'>
|
||||||
|
@ -82,6 +83,31 @@ Object subclass: M2UAStateBase [
|
||||||
nextPutAll: '}';
|
nextPutAll: '}';
|
||||||
contents
|
contents
|
||||||
]
|
]
|
||||||
|
|
||||||
|
M2UAStateBase class >> on: aMachine [
|
||||||
|
"Create a new state for a machine"
|
||||||
|
|
||||||
|
^self new
|
||||||
|
machine: aMachine;
|
||||||
|
yourself
|
||||||
|
]
|
||||||
|
|
||||||
|
entered [
|
||||||
|
"The state has been entered"
|
||||||
|
]
|
||||||
|
|
||||||
|
left [
|
||||||
|
"The state has been left"
|
||||||
|
]
|
||||||
|
|
||||||
|
machine: aMachine [
|
||||||
|
machine := aMachine
|
||||||
|
]
|
||||||
|
|
||||||
|
moveToState: aNewState [
|
||||||
|
<category: 'transition'>
|
||||||
|
machine moveToState: aNewState
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,6 +173,10 @@ M2UAStateBase subclass: M2UAAspState [
|
||||||
|
|
||||||
<category: 'OsmoNetwork-M2UA-States'>
|
<category: 'OsmoNetwork-M2UA-States'>
|
||||||
<comment: 'I am the base class of the ASP State Machine from RFC 3331 on Page 61.'>
|
<comment: 'I am the base class of the ASP State Machine from RFC 3331 on Page 61.'>
|
||||||
|
|
||||||
|
M2UAAspState class >> nextPossibleStates [
|
||||||
|
^self subclassResponsibility
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,6 +186,10 @@ M2UAAspState subclass: M2UAAspStateActive [
|
||||||
<category: 'OsmoNetwork-M2UA-States'>
|
<category: 'OsmoNetwork-M2UA-States'>
|
||||||
<comment: nil>
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAAspStateActive class >> nextPossibleStates [
|
||||||
|
^ {M2UAAspStateInactive. M2UAAspStateDown}
|
||||||
|
]
|
||||||
|
|
||||||
onAspDown: anEvent [
|
onAspDown: anEvent [
|
||||||
<category: 'state-changes'>
|
<category: 'state-changes'>
|
||||||
self moveToState: M2UAAspStateDown
|
self moveToState: M2UAAspStateDown
|
||||||
|
@ -189,6 +223,10 @@ M2UAAspState subclass: M2UAAspStateDown [
|
||||||
<category: 'OsmoNetwork-M2UA-States'>
|
<category: 'OsmoNetwork-M2UA-States'>
|
||||||
<comment: nil>
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAAspStateDown class >> nextPossibleStates [
|
||||||
|
^{M2UAAspStateInactive}
|
||||||
|
]
|
||||||
|
|
||||||
onAspUp: anEvent [
|
onAspUp: anEvent [
|
||||||
<category: 'state-changes'>
|
<category: 'state-changes'>
|
||||||
^self moveToState: M2UAAspStateInactive
|
^self moveToState: M2UAAspStateInactive
|
||||||
|
@ -202,6 +240,10 @@ M2UAAspState subclass: M2UAAspStateInactive [
|
||||||
<category: 'OsmoNetwork-M2UA-States'>
|
<category: 'OsmoNetwork-M2UA-States'>
|
||||||
<comment: nil>
|
<comment: nil>
|
||||||
|
|
||||||
|
M2UAAspStateInactive class >> nextPossibleStates [
|
||||||
|
^ {M2UAAspStateActive. M2UAAspStateDown}
|
||||||
|
]
|
||||||
|
|
||||||
onAspActive: anEvent [
|
onAspActive: anEvent [
|
||||||
<category: 'state-changes'>
|
<category: 'state-changes'>
|
||||||
^self moveToState: M2UAAspStateActive
|
^self moveToState: M2UAAspStateActive
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
"
|
||||||
|
(C) 2011-2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
Object subclass: M2UATerminology [
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA'>
|
||||||
|
<comment: 'I attempt to help with the terminology for M2UA.
|
||||||
|
|
||||||
|
M2UA is defined in IETF RFC 3331 and is actually from a family
|
||||||
|
of closely related RFCs for M3UA, SUA, M2PA.
|
||||||
|
|
||||||
|
The whole idea is that one can adapt the M2UA layer from the classlic
|
||||||
|
E1/T1 timeslots to the more modern SCTP (SIGTRAN). MTP3 and above will
|
||||||
|
not notice the difference.
|
||||||
|
|
||||||
|
The communication for M2UA is between two systems, both should be
|
||||||
|
configurable as either a client or server (listening for incoming SCTP
|
||||||
|
connections).
|
||||||
|
|
||||||
|
In general the communication is between a Signalling Gateway
|
||||||
|
(SG) and a Media Gateway Controller (MGC). In our world the MGC
|
||||||
|
would is the MSC/HLR/VLR/AuC.
|
||||||
|
|
||||||
|
What makes things complicated is the cardinality of systems. There is
|
||||||
|
an Application Server (AS), this can have multiple Application Server
|
||||||
|
Processes (ASP) for one or multiple MTP links. While the RFC onlys
|
||||||
|
says that the SG should the list of ASs in practice both ends need to
|
||||||
|
do it.'>
|
||||||
|
]
|
|
@ -0,0 +1,222 @@
|
||||||
|
"
|
||||||
|
(C) 2013 by Holger Hans Peter Freyther
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"
|
||||||
|
|
||||||
|
Object subclass: M2UAASMock [
|
||||||
|
| socket |
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA-Tests'>
|
||||||
|
<comment: 'A simple mock'>
|
||||||
|
|
||||||
|
socketService: aSocket [
|
||||||
|
<category: 'creation'>
|
||||||
|
socket := aSocket
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspActive: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
| ret |
|
||||||
|
ret := M2UAMSG new
|
||||||
|
msgClass: M2UAConstants clsASPTM;
|
||||||
|
msgType: M2UAConstants asptmActivAck;
|
||||||
|
yourself.
|
||||||
|
socket sendToAsp: ret toMessage asByteArray
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspDown: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
| ret |
|
||||||
|
ret := M2UAMSG new
|
||||||
|
msgClass: M2UAConstants clsASPSM;
|
||||||
|
msgType: M2UAConstants aspsmDownAck;
|
||||||
|
yourself.
|
||||||
|
socket sendToAsp: ret toMessage asByteArray
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspInactive: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
| ret |
|
||||||
|
ret := M2UAMSG new
|
||||||
|
msgClass: M2UAConstants clsASPTM;
|
||||||
|
msgType: M2UAConstants asptmInactivAck;
|
||||||
|
yourself.
|
||||||
|
socket sendToAsp: ret toMessage asByteArray
|
||||||
|
]
|
||||||
|
|
||||||
|
handleAspUp: aMsg [
|
||||||
|
<category: 'dispatch'>
|
||||||
|
| ret |
|
||||||
|
ret := M2UAMSG new
|
||||||
|
msgClass: M2UAConstants clsASPSM;
|
||||||
|
msgType: M2UAConstants aspsmUpAck;
|
||||||
|
yourself.
|
||||||
|
socket sendToAsp: ret toMessage asByteArray
|
||||||
|
]
|
||||||
|
|
||||||
|
onData: aData [
|
||||||
|
| msg |
|
||||||
|
msg := M2UAMSG parseToClass: aData.
|
||||||
|
msg dispatchOnAsp: self
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
Object subclass: SCTPNetworkServiceMock [
|
||||||
|
| on_connect on_released on_data as asp |
|
||||||
|
|
||||||
|
<category: 'OsmoNetwork-M2UA-Tests'>
|
||||||
|
<comment: 'I mock SCTPand directly connect an AS with an ASP.'>
|
||||||
|
|
||||||
|
onSctpConnect: aBlock [
|
||||||
|
<category: 'notification'>
|
||||||
|
on_connect := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
applicationServer: anAs [
|
||||||
|
<category: 'creation'>
|
||||||
|
as := anAs
|
||||||
|
]
|
||||||
|
|
||||||
|
applicationServerProcess: anAsp [
|
||||||
|
<category: 'creation'>
|
||||||
|
asp := anAsp
|
||||||
|
]
|
||||||
|
|
||||||
|
onSctpData: aBlock [
|
||||||
|
<category: 'creation'>
|
||||||
|
on_data := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
onSctpReleased: aBlock [
|
||||||
|
<category: 'creation'>
|
||||||
|
on_released := aBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
hostname [
|
||||||
|
<category: 'management'>
|
||||||
|
^'localhost'
|
||||||
|
]
|
||||||
|
|
||||||
|
port [
|
||||||
|
<category: 'management'>
|
||||||
|
^0
|
||||||
|
]
|
||||||
|
|
||||||
|
start [
|
||||||
|
"Nothing"
|
||||||
|
|
||||||
|
<category: 'management'>
|
||||||
|
on_connect value
|
||||||
|
]
|
||||||
|
|
||||||
|
stop [
|
||||||
|
<category: 'management'>
|
||||||
|
on_released value
|
||||||
|
]
|
||||||
|
|
||||||
|
nextPut: aMsg [
|
||||||
|
as onData: aMsg
|
||||||
|
]
|
||||||
|
|
||||||
|
sendToAsp: aMsg [
|
||||||
|
on_data
|
||||||
|
value: nil
|
||||||
|
value: nil
|
||||||
|
value: 2
|
||||||
|
value: aMsg
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
TestCase subclass: M2UAApplicationServerProcessTest [
|
||||||
|
|
||||||
|
<comment: 'A M2UAApplicationServerProcessTest is a test class for testing the behavior of M2UAApplicationServerProcess'>
|
||||||
|
<category: 'OsmoNetwork-M2UA-Tests'>
|
||||||
|
|
||||||
|
testCreation [
|
||||||
|
| asp |
|
||||||
|
asp := M2UAApplicationServerProcess new
|
||||||
|
onAspActive: [];
|
||||||
|
onAspDown: [];
|
||||||
|
onAspInactive: [];
|
||||||
|
onAspUp: [];
|
||||||
|
onStateChange: [];
|
||||||
|
onError: [:msg | ];
|
||||||
|
onNotify: [:type :ident | ];
|
||||||
|
onSctpEstablished: [];
|
||||||
|
onSctpReleased: [];
|
||||||
|
onSctpRestarted: [];
|
||||||
|
onSctpStatus: [];
|
||||||
|
yourself
|
||||||
|
]
|
||||||
|
|
||||||
|
testStateTransitions [
|
||||||
|
| mock as asp |
|
||||||
|
mock := SCTPNetworkServiceMock new.
|
||||||
|
as := M2UAASMock new
|
||||||
|
socketService: mock;
|
||||||
|
yourself.
|
||||||
|
asp := M2UAApplicationServerProcess initWith: mock.
|
||||||
|
mock
|
||||||
|
applicationServer: as;
|
||||||
|
applicationServerProcess: asp.
|
||||||
|
|
||||||
|
"This works as the mock will handle this synchronously"
|
||||||
|
self assert: asp state = M2UAAspStateDown.
|
||||||
|
asp
|
||||||
|
sctpEstablish;
|
||||||
|
aspUp.
|
||||||
|
self assert: asp state = M2UAAspStateInactive.
|
||||||
|
|
||||||
|
"Now bring it down and up again"
|
||||||
|
asp aspDown.
|
||||||
|
self assert: asp state = M2UAAspStateDown.
|
||||||
|
asp
|
||||||
|
aspUp;
|
||||||
|
aspActive.
|
||||||
|
self assert: asp state = M2UAAspStateActive.
|
||||||
|
asp aspDown.
|
||||||
|
self assert: asp state = M2UAAspStateDown.
|
||||||
|
asp
|
||||||
|
aspUp;
|
||||||
|
aspActive;
|
||||||
|
aspInactive.
|
||||||
|
self assert: asp state = M2UAAspStateInactive.
|
||||||
|
asp sctpRelease.
|
||||||
|
self assert: asp state = M2UAAspStateDown
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
TestCase subclass: M2UAAspStateMachineTest [
|
||||||
|
|
||||||
|
<comment: 'A M2UAAspStateMachineTest is a test class for testing the behavior of M2UAAspStateMachine'>
|
||||||
|
<category: 'OsmoNetwork-M2UA-Tests'>
|
||||||
|
|
||||||
|
testLegalTransitions [
|
||||||
|
| machine |
|
||||||
|
machine := M2UAAspStateMachine new.
|
||||||
|
self assert: machine state = M2UAAspStateDown.
|
||||||
|
machine aspUp: 'Link is up'.
|
||||||
|
self assert: machine state = M2UAAspStateInactive.
|
||||||
|
machine aspActive: 'Active'.
|
||||||
|
self assert: machine state = M2UAAspStateActive.
|
||||||
|
machine aspInactive: 'Inactive'.
|
||||||
|
self assert: machine state = M2UAAspStateInactive.
|
||||||
|
machine aspActive: 'Active'.
|
||||||
|
self assert: machine state = M2UAAspStateActive.
|
||||||
|
machine sctpCdi: 'Connection is gone'.
|
||||||
|
self assert: machine state = M2UAAspStateDown
|
||||||
|
]
|
||||||
|
]
|
18
package.xml
18
package.xml
|
@ -9,6 +9,7 @@
|
||||||
<prereq>Parser</prereq>
|
<prereq>Parser</prereq>
|
||||||
|
|
||||||
<filein>core/Extensions.st</filein>
|
<filein>core/Extensions.st</filein>
|
||||||
|
<filein>core/ExtensionsGST.st</filein>
|
||||||
<filein>core/MessageStructure.st</filein>
|
<filein>core/MessageStructure.st</filein>
|
||||||
<filein>core/MessageBuffer.st</filein>
|
<filein>core/MessageBuffer.st</filein>
|
||||||
<filein>core/LogAreas.st</filein>
|
<filein>core/LogAreas.st</filein>
|
||||||
|
@ -28,10 +29,21 @@
|
||||||
<filein>sccp/SCCPGlobalTitleTranslation.st</filein>
|
<filein>sccp/SCCPGlobalTitleTranslation.st</filein>
|
||||||
<filein>mtp3/MTP3Messages.st</filein>
|
<filein>mtp3/MTP3Messages.st</filein>
|
||||||
<filein>ua/XUA.st</filein>
|
<filein>ua/XUA.st</filein>
|
||||||
|
|
||||||
<filein>m2ua/M2UAConstants.st</filein>
|
<filein>m2ua/M2UAConstants.st</filein>
|
||||||
<filein>m2ua/M2UAStates.st</filein>
|
<filein>m2ua/M2UAStates.st</filein>
|
||||||
<filein>m2ua/M2UATag.st</filein>
|
<filein>m2ua/M2UATag.st</filein>
|
||||||
<filein>m2ua/M2UAMSG.st</filein>
|
<filein>m2ua/M2UAMSG.st</filein>
|
||||||
|
<filein>m2ua/M2UAMessages.st</filein>
|
||||||
|
<filein>m2ua/M2UAStates.st</filein>
|
||||||
|
<filein>m2ua/M2UAAspStateMachine.st</filein>
|
||||||
|
<filein>m2ua/M2UAApplicationServerProcess.st</filein>
|
||||||
|
<filein>m2ua/M2UALayerManagement.st</filein>
|
||||||
|
<filein>m2ua/M2UATerminology.st</filein>
|
||||||
|
<filein>m2ua/M2UAExamples.st</filein>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<filein>osmo/LogAreaOsmo.st</filein>
|
<filein>osmo/LogAreaOsmo.st</filein>
|
||||||
<filein>osmo/OsmoUDPSocket.st</filein>
|
<filein>osmo/OsmoUDPSocket.st</filein>
|
||||||
<filein>osmo/OsmoCtrlLogging.st</filein>
|
<filein>osmo/OsmoCtrlLogging.st</filein>
|
||||||
|
@ -48,13 +60,16 @@
|
||||||
<sunit>Osmo.IPAGSTTests</sunit>
|
<sunit>Osmo.IPAGSTTests</sunit>
|
||||||
<sunit>Osmo.IPAMsgTests</sunit>
|
<sunit>Osmo.IPAMsgTests</sunit>
|
||||||
<sunit>Osmo.MessageBufferTest</sunit>
|
<sunit>Osmo.MessageBufferTest</sunit>
|
||||||
<sunit>Osmo.M2UAMSGTests</sunit>
|
|
||||||
<sunit>Osmo.ISUPGeneratedTest</sunit>
|
<sunit>Osmo.ISUPGeneratedTest</sunit>
|
||||||
<sunit>Osmo.OsmoUDPSocketTest</sunit>
|
<sunit>Osmo.OsmoUDPSocketTest</sunit>
|
||||||
<sunit>Osmo.TLVDescriptionTest</sunit>
|
<sunit>Osmo.TLVDescriptionTest</sunit>
|
||||||
<sunit>Osmo.CtrlGrammarTest</sunit>
|
<sunit>Osmo.CtrlGrammarTest</sunit>
|
||||||
<sunit>Osmo.CtrlParserTest</sunit>
|
<sunit>Osmo.CtrlParserTest</sunit>
|
||||||
|
|
||||||
|
<sunit>Osmo.M2UAMSGTests</sunit>
|
||||||
|
<sunit>Osmo.M2UAApplicationServerProcessTest</sunit>
|
||||||
|
<sunit>Osmo.M2UAAspStateMachineTest</sunit>
|
||||||
|
|
||||||
<sunit>Osmo.MTP3LabelTest</sunit>
|
<sunit>Osmo.MTP3LabelTest</sunit>
|
||||||
<sunit>Osmo.MTP3SLTAMSGTest</sunit>
|
<sunit>Osmo.MTP3SLTAMSGTest</sunit>
|
||||||
<sunit>Osmo.MTP3SLTMMSGTest</sunit>
|
<sunit>Osmo.MTP3SLTMMSGTest</sunit>
|
||||||
|
@ -66,6 +81,7 @@
|
||||||
<filein>isup/ISUPTests.st</filein>
|
<filein>isup/ISUPTests.st</filein>
|
||||||
<filein>ipa/IPATests.st</filein>
|
<filein>ipa/IPATests.st</filein>
|
||||||
<filein>osmo/OsmoCtrlGrammarTest.st</filein>
|
<filein>osmo/OsmoCtrlGrammarTest.st</filein>
|
||||||
|
<filein>m2ua/M2UATests.st</filein>
|
||||||
<filein>mtp3/MTP3MessagesTests.st</filein>
|
<filein>mtp3/MTP3MessagesTests.st</filein>
|
||||||
</test>
|
</test>
|
||||||
</package>
|
</package>
|
||||||
|
|
Reference in New Issue