217 lines
5.5 KiB
Smalltalk
217 lines
5.5 KiB
Smalltalk
Object subclass: GSMDriver [
|
|
| sccp proc sapis completeSem result phoneConfig |
|
|
<category: 'osmo-gsm-operation'>
|
|
<comment: 'I create a SCCP connection and handle stuff on it. In the base class
|
|
I am just capable of handling BSSMAP Management and need to dispatch it to other
|
|
classes.'>
|
|
|
|
GSMDriver class >> new [
|
|
<category: 'private'>
|
|
^ super new initialize; yourself
|
|
]
|
|
|
|
GSMDriver class >> initWith: aSCCPConnection sapi: aSapi on: aProc phone: aPhone[
|
|
<category: 'creation'>
|
|
^ self new
|
|
sapi: aSapi on: aProc;
|
|
sccp: aSCCPConnection;
|
|
phone: aPhone;
|
|
yourself
|
|
]
|
|
|
|
initialize [
|
|
<category: 'private'>
|
|
completeSem := Semaphore new.
|
|
sapis := Dictionary new.
|
|
]
|
|
|
|
result [
|
|
^ result
|
|
]
|
|
|
|
waitForCompletion [
|
|
<category: 'accessing'>
|
|
^ completeSem wait
|
|
]
|
|
|
|
waitWithTimeout: aTimeout [
|
|
| delay |
|
|
<category: 'accessing'>
|
|
|
|
delay := Delay forSeconds: aTimeout.
|
|
delay timedWaitOn: completeSem.
|
|
]
|
|
|
|
sapi: aSapi on: aProc [
|
|
<category: 'manage'>
|
|
sapis at: aSapi put: aProc.
|
|
]
|
|
|
|
phone: aPhone [
|
|
<category: 'private'>
|
|
phoneConfig := aPhone.
|
|
]
|
|
|
|
sccp: aSCCPConnection [
|
|
sccp := aSCCPConnection
|
|
]
|
|
|
|
run [
|
|
<category: 'processing'>
|
|
"Process all messages in a thread"
|
|
|
|
proc := [
|
|
[
|
|
[
|
|
[true] whileTrue: [
|
|
| msg |
|
|
msg := sccp next.
|
|
self dispatch: msg.
|
|
].
|
|
] on: SystemExceptions.EndOfStream do: [
|
|
'Server is disconnected' printNl.
|
|
].
|
|
] ensure: [
|
|
completeSem signal.
|
|
].
|
|
] fork.
|
|
]
|
|
|
|
cleanUp [
|
|
<category: 'protected'>
|
|
]
|
|
|
|
dispatchMan: aMsg [
|
|
<category: 'private'>
|
|
aMsg type = GSM0808Helper msgClear ifTrue: [
|
|
| resp |
|
|
resp := IEMessage initWith: GSM0808Helper msgClearComp.
|
|
sccp nextPutData: (BSSAPManagement initWith: resp).
|
|
^ true
|
|
].
|
|
|
|
aMsg type = GSM0808Helper msgCipherModeCmd ifTrue: [
|
|
| resp |
|
|
resp := IEMessage initWith: GSM0808Helper msgCipherModeCmpl.
|
|
resp addIe: (GSM0808ChosenEncrIE initWith: 1).
|
|
sccp nextPutData: (BSSAPManagement initWith: resp).
|
|
^ true
|
|
].
|
|
|
|
aMsg type = GSM0808Helper msgAssRequest ifTrue: [
|
|
| resp |
|
|
"Reply with a AMR halfrate statement"
|
|
resp := IEMessage initWith: GSM0808Helper msgAssComplete.
|
|
resp addIe: (GSM0808CauseIE initWith: 0).
|
|
resp addIe: (GSM0808ChosenChannel initWith: 16r98).
|
|
resp addIe: (GSM0808ChosenEncrIE initWith: 1).
|
|
resp addIe: (GSM0808SpeechVerIE initWith: 16r25).
|
|
sccp nextPutData: (BSSAPManagement initWith: resp).
|
|
^ true
|
|
].
|
|
|
|
'Unhandled message' printNl.
|
|
aMsg inspect.
|
|
]
|
|
|
|
auKey [
|
|
^ phoneConfig auKey.
|
|
]
|
|
|
|
imsi [
|
|
^ phoneConfig imsi.
|
|
]
|
|
|
|
dispatchDTAP: aMsg sapi: aSapi [
|
|
<category: 'private'>
|
|
aMsg class messageType = GSM48MMMessage msgAuReq ifTrue: [
|
|
| auth resp |
|
|
auth := A3A8 COMP128_v3: self auKey rand: aMsg auth data.
|
|
resp := GSM48AuthResp new.
|
|
resp sres data: (auth copyFrom: 1 to: 4).
|
|
|
|
sccp nextPutData: (BSSAPDTAP initWith: resp linkIdentifier: 0).
|
|
^ true
|
|
].
|
|
|
|
sapis at: aSapi ifPresent: [:handler |
|
|
].
|
|
|
|
'Unhandled DTAP message' printNl.
|
|
aMsg inspect.
|
|
]
|
|
|
|
dispatch: aMsg [
|
|
<category: 'protected'>
|
|
aMsg class msgType = BSSAPHelper msgManagemnt
|
|
ifTrue: [
|
|
self dispatchMan: aMsg data.
|
|
]
|
|
ifFalse: [
|
|
self dispatchDTAP: aMsg data sapi: aMsg sapi.
|
|
].
|
|
aMsg inspect.
|
|
]
|
|
]
|
|
|
|
Object subclass: ProcedureBase [
|
|
| driver conn |
|
|
|
|
ProcedureBase class >> initWith: aHandler phone: aPhone [
|
|
^ self new
|
|
createConnection: aHandler phone: aPhone;
|
|
yourself
|
|
]
|
|
|
|
openConnection: aMsg sapi: aSapi phone: aPhone handler: aHandler [
|
|
| msg bssap |
|
|
msg := IEMessage initWith: GSM0808Helper msgComplL3.
|
|
msg addIe: (GSMCellIdentifier initWith: 274 mnc: 8 lac: 4099 ci: 40000).
|
|
msg addIe: (GSMLayer3Info initWith: aMsg).
|
|
|
|
bssap := BSSAPManagement initWith: msg.
|
|
|
|
conn := aHandler createConnection: bssap.
|
|
driver := GSMDriver initWith: conn sapi: aSapi on: self phone: aPhone.
|
|
'Created the driver' printNl.
|
|
]
|
|
|
|
execute [
|
|
driver run.
|
|
driver waitForCompletion.
|
|
]
|
|
]
|
|
|
|
|
|
ProcedureBase subclass: LUProcedure [
|
|
|
|
createConnection: aHandler phone: aPhone [
|
|
| lu |
|
|
|
|
lu := GSM48LURequest new.
|
|
lu mi imsi: aPhone imsi.
|
|
|
|
'LU proc started' printNl.
|
|
self openConnection: lu sapi: 0 phone: aPhone handler: aHandler.
|
|
]
|
|
|
|
execute [
|
|
super execute.
|
|
'LUProcedure is completed' printNl.
|
|
]
|
|
]
|
|
|
|
ProcedureBase subclass: CallProcedure [
|
|
createConnection: aHandler phone: aPhone [
|
|
| cm |
|
|
|
|
cm := GSM48CMServiceReq new.
|
|
self openConnection: cm sapi: 0 phone: aPhone handler: aHandler.
|
|
]
|
|
|
|
execute [
|
|
super execute.
|
|
'Call Complete' printNl.
|
|
]
|
|
]
|