aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-08-02 20:33:16 +0200
committerHarald Welte <laforge@gnumonks.org>2010-08-02 20:35:16 +0200
commit6f9b5139f34d222a4e6348f0bdccc3a75aa341ec (patch)
treefcf8bd9c9719c138da6630758ad110f40780187f
parentc24b0a10c250595a8e96240b4118ea2ea7b077f5 (diff)
re-work MAP patching into recursive/overloaded functions
this renders a much cleaner solution
-rw-r--r--src/tcap_udp_server.erl219
1 files changed, 112 insertions, 107 deletions
diff --git a/src/tcap_udp_server.erl b/src/tcap_udp_server.erl
index 9abc03f..a7f2393 100644
--- a/src/tcap_udp_server.erl
+++ b/src/tcap_udp_server.erl
@@ -37,50 +37,137 @@ init(ServerPort) ->
% patch a UpdateGprsLocationArg and replace SGSN number and SGSN address
% !!! TESTING ONLY !!!
-patch_UpdateGprsLocationArg(Arg) ->
- Arg1 = Arg#'UpdateGprsLocationArg'{'sgsn-Number' = ?PATCH_SGSN_NUMBER},
- Arg1#'UpdateGprsLocationArg'{'sgsn-Address' = ?PATCH_SGSN_ADDRESS}.
-
+patch(#'UpdateGprsLocationArg'{} = P) ->
+ P#'UpdateGprsLocationArg'{'sgsn-Number'= ?PATCH_SGSN_NUMBER,
+ 'sgsn-Address' = ?PATCH_SGSN_ADDRESS};
% Some other SGSN is sendingu us a GPRS location update. In the response,
% we indicate teh HLR number, which we need to masquerade
-patch_UpdateGprsLocationRes(Arg) ->
- Arg#'UpdateGprsLocationRes'{'hlr-Number' = ?PATCH_HLR_NUMBER}.
+patch(#'UpdateGprsLocationRes'{} = P) ->
+ P#'UpdateGprsLocationRes'{'hlr-Number' = ?PATCH_HLR_NUMBER};
% Some other MSC/VLR is sendingu us a GSM location update. In the response,
% we indicate teh HLR number, which we need to masquerade
-patch_UpdateLocationRes(Arg) ->
- Arg#'UpdateLocationRes'{'hlr-Number' = ?PATCH_HLR_NUMBER}.
+patch(#'UpdateLocationRes'{} = P) ->
+ P#'UpdateLocationRes'{'hlr-Number' = ?PATCH_HLR_NUMBER};
% HLR responds to VLR's MAP_RESTORE_REQ (i.e. it has lost information)
-patch_RestoreDataRes(Arg) ->
- Arg#'RestoreDataRes'{'hlr-Number' = ?PATCH_HLR_NUMBER}.
+patch(#'RestoreDataRes'{} = P) ->
+ P#'RestoreDataRes'{'hlr-Number' = ?PATCH_HLR_NUMBER};
% HLR sends subscriber data to VLR/SGSN, including CAMEL info
-patch_InsertSubscriberDataArg(Arg) ->
- VlrCamel = Arg#'InsertSubscriberDataArg'.'vlrCamelSubscriptionInfo',
- Arg1 = Arg#'InsertSubscriberDataArg'{'vlrCamelSubscriptionInfo' = patch_vlrCamelSubscrInfo(VlrCamel)},
- %SgsnCamel = Arg#'InsertSubscriberDataArg'.'sgsn-CAMEL-SubscriptionInfo',
- %Arg#'InsertSubscriberDataArg'{'sgsn-CAMEL-SubscriptionInfo' = patch_sgsnCamelSubscrInfo(SgsnCamel)},
- Arg1.
+patch(#'InsertSubscriberDataArg'{'vlrCamelSubscriptionInfo'=VlrCamel,
+ 'sgsn-CAMEL-SubscriptionInfo'=SgsnCamel} = Arg) ->
+ Arg#'InsertSubscriberDataArg'{'vlrCamelSubscriptionInfo'=patch(VlrCamel),
+ 'sgsn-CAMEL-SubscriptionInfo'=patch(SgsnCamel)};
+
+% HLR sends subscriber data to gsmSCF
+patch(#'AnyTimeSubscriptionInterrogationRes'{'camel-SubscriptionInfo'=Csi} = P) ->
+ P#'AnyTimeSubscriptionInterrogationRes'{'camel-SubscriptionInfo'=patch(Csi)};
+patch(asn1_NOVALUE) ->
+ asn1_NOVALUE;
% CAMEL related parsing
+% this is part of the InsertSubscriberData HLR -> VLR
+patch(#'VlrCamelSubscriptionInfo'{'o-CSI'=Ocsi, 'mo-sms-CSI'=MoSmsCsi,
+ 'mt-sms-CSI'=MtSmsCsi, 'ss-CSI'=SsCsi} = P) ->
+ P#'VlrCamelSubscriptionInfo'{'o-CSI'=patch(Ocsi),
+ 'mo-sms-CSI'=patch(MoSmsCsi),
+ 'mt-sms-CSI'=patch(MtSmsCsi),
+ 'ss-CSI'=patch(SsCsi)};
+
+% this is part of the InsertSubscriberData HLR -> SGSN
+patch(#'SGSN-CAMEL-SubscriptionInfo'{'gprs-CSI'=GprsCsi,
+ 'mo-sms-CSI'=MoSmsCsi,
+ 'mt-sms-CSI'=MtSmsCsi} = P) ->
+ P#'SGSN-CAMEL-SubscriptionInfo'{'gprs-CSI'=patch(GprsCsi),
+ 'mo-sms-CSI'=patch(MoSmsCsi),
+ 'mt-sms-CSI'=patch(MtSmsCsi)};
+
+% this is part of the Anytime Subscription Interrogation Result HLR->gsmSCF
+patch(#'CAMEL-SubscriptionInfo'{'o-CSI'=Ocsi,
+ 'd-CSI'=Dcsi,
+ 't-CSI'=Tcsi,
+ 'vt-CSI'=Vtcsi,
+ %'tif-CSI'=Tifcsi,
+ 'gprs-CSI'=GprsCsi,
+ 'mo-sms-CSI'=MoSmsCsi,
+ 'ss-CSI'=SsCsi,
+ 'm-CSI'=Mcsi,
+ 'mt-sms-CSI'=MtSmsCsi,
+ 'mg-csi'=MgCsi,
+ 'o-IM-CSI'=OimCsi,
+ 'd-IM-CSI'=DimCsi,
+ 'vt-IM-CSI'=VtImCsi} = P) ->
+ P#'CAMEL-SubscriptionInfo'{'o-CSI'=patch(Ocsi),
+ 'd-CSI'=patch(Dcsi),
+ 't-CSI'=patch(Tcsi),
+ 'vt-CSI'=patch(Vtcsi),
+ 'gprs-CSI'=patch(GprsCsi),
+ 'mo-sms-CSI'=patch(MoSmsCsi),
+ 'ss-CSI'=patch(SsCsi),
+ 'm-CSI'=patch(Mcsi),
+ 'mt-sms-CSI'=patch(MtSmsCsi),
+ 'mg-csi'=patch(MgCsi),
+ 'o-IM-CSI'=patch(OimCsi),
+ 'd-IM-CSI'=patch(DimCsi),
+ 'vt-IM-CSI'=patch(VtImCsi)};
+
+patch(#'T-CSI'{'t-BcsmCamelTDPDataList'=TdpList} = P) ->
+ P#'T-CSI'{'t-BcsmCamelTDPDataList'=patch_tBcsmCamelTDPDataList(TdpList)};
+patch(#'M-CSI'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'M-CSI'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
+patch(#'MG-CSI'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'MG-CSI'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
+patch(#'O-CSI'{'o-BcsmCamelTDPDataList'=TdpList} = P) ->
+ P#'O-CSI'{'o-BcsmCamelTDPDataList'=patch_oBcsmCamelTDPDataList(TdpList)};
+patch(#'D-CSI'{'dp-AnalysedInfoCriteriaList'=List} = P) ->
+ P#'D-CSI'{'dp-AnalysedInfoCriteriaList'=patch_AnInfoCritList(List)};
+patch(#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=TdpList} = P) ->
+ P#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=patch_SmsCamelTDPDataList(TdpList)};
+patch(#'SS-CSI'{'ss-CamelData'=Sscd} = P) ->
+ P#'SS-CSI'{'ss-CamelData'=patch(Sscd)};
+patch(#'GPRS-CSI'{'gprs-CamelTDPDataList'=TdpList} = P) ->
+ P#'GPRS-CSI'{'gprs-CamelTDPDataList'=patch_GprsCamelTDPDataList(TdpList)};
+patch(#'SS-CamelData'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'SS-CamelData'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
+patch(#'O-BcsmCamelTDPData'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'O-BcsmCamelTDPData'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
+patch(#'SMS-CAMEL-TDP-Data'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'SMS-CAMEL-TDP-Data'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
+patch(#'GPRS-CamelTDPData'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'GPRS-CamelTDPData'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
+patch(#'DP-AnalysedInfoCriterium'{'gsmSCF-Address'=GsmScfAddr} = P) ->
+ P#'DP-AnalysedInfoCriterium'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS}.
+
patch_oBcsmCamelTDPDataList(List) ->
% we reverse the origianl list, as the tail recursive _acc function
% will invert the order of components again
patch_oBcsmCamelTDPDataList_acc(lists:reverse(List), []).
patch_oBcsmCamelTDPDataList_acc([], NewList) -> NewList;
patch_oBcsmCamelTDPDataList_acc([TdpData|Tail], NewList) ->
- case TdpData of
- #'O-BcsmCamelTDPData'{'gsmSCF-Address'=ScfAddr} ->
- NewTdpData = TdpData#'O-BcsmCamelTDPData'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
- _ ->
- NewTdpData = TdpData
- end,
+ NewTdpData = patch(TdpData#'O-BcsmCamelTDPData'{}),
patch_oBcsmCamelTDPDataList_acc(Tail, [NewTdpData|NewList]).
+patch_tBcsmCamelTDPDataList(List) ->
+ % we reverse the origianl list, as the tail recursive _acc function
+ % will invert the order of components again
+ patch_tBcsmCamelTDPDataList_acc(lists:reverse(List), []).
+patch_tBcsmCamelTDPDataList_acc([], NewList) -> NewList;
+patch_tBcsmCamelTDPDataList_acc([TdpData|Tail], NewList) ->
+ NewTdpData = patch(TdpData#'T-BcsmCamelTDPData'{}),
+ patch_tBcsmCamelTDPDataList_acc(Tail, [NewTdpData|NewList]).
+
+patch_AnInfoCritList(List) ->
+ % we reverse the origianl list, as the tail recursive _acc function
+ % will invert the order of components again
+ patch_AnInfoCritList_acc(lists:reverse(List), []).
+patch_AnInfoCritList_acc([], NewList) -> NewList;
+patch_AnInfoCritList_acc([Crit|Tail], NewList) ->
+ NewCrit = patch(Crit#'DP-AnalysedInfoCriterium'{}),
+ patch_AnInfoCritList_acc(Tail, [NewCrit|NewList]).
patch_GprsCamelTDPDataList(List) ->
% we reverse the origianl list, as the tail recursive _acc function
@@ -88,107 +175,25 @@ patch_GprsCamelTDPDataList(List) ->
patch_GprsCamelTDPDataList_acc(lists:reverse(List), []).
patch_GprsCamelTDPDataList_acc([], NewList) -> NewList;
patch_GprsCamelTDPDataList_acc([TdpData|Tail], NewList) ->
- case TdpData of
- #'GPRS-CamelTDPData'{'gsmSCF-Address'=ScfAddr} ->
- NewTdpData = TdpData#'GPRS-CamelTDPData'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
- _ ->
- NewTdpData = TdpData
- end,
+ NewTdpData = patch(TdpData#'GPRS-CamelTDPData'{}),
patch_GprsCamelTDPDataList_acc(Tail, [NewTdpData|NewList]).
-
patch_SmsCamelTDPDataList(List) ->
% we reverse the origianl list, as the tail recursive _acc function
% will invert the order of components again
patch_SmsCamelTDPDataList_acc(lists:reverse(List), []).
patch_SmsCamelTDPDataList_acc([], NewList) -> NewList;
patch_SmsCamelTDPDataList_acc([TdpData|Tail], NewList) ->
- case TdpData of
- #'SMS-CAMEL-TDP-Data'{'gsmSCF-Address'=ScfAddr} ->
- NewTdpData = TdpData#'SMS-CAMEL-TDP-Data'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS};
- _ ->
- NewTdpData = TdpData
- end,
+ NewTdpData = patch(TdpData#'SMS-CAMEL-TDP-Data'{}),
patch_GprsCamelTDPDataList_acc(Tail, [NewTdpData|NewList]).
-patch_vlrCamelSubscrInfo(VlrCamel) ->
- case VlrCamel of
- asn1_NOVALUE ->
- % return the original (empty) VlrCamelSubscrInfo
- VlrCamel;
- #'VlrCamelSubscriptionInfo'{} ->
- case VlrCamel of
- #'VlrCamelSubscriptionInfo'{'o-CSI'={#'O-CSI'{'o-BcsmCamelTDPDataList'=TdpList}}} ->
- NewTdpList = patch_oBcsmCamelTDPDataList(TdpList),
- VlrCamel1 = VlrCamel#'VlrCamelSubscriptionInfo'{'o-CSI'={#'O-CSI'{'o-BcsmCamelTDPDataList'=NewTdpList}}};
- _ ->
- VlrCamel1 = VlrCamel
- end,
- case VlrCamel1 of
- #'VlrCamelSubscriptionInfo'{'mo-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=MoSmsTdpList}}} ->
- NewMoSmsTdpList = patch_SmsCamelTDPDataList(MoSmsTdpList),
- VlrCamel2 = VlrCamel1#'VlrCamelSubscriptionInfo'{'mo-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=NewMoSmsTdpList}}};
- _ ->
- VlrCamel2 = VlrCamel1
- end,
- case VlrCamel2 of
- #'VlrCamelSubscriptionInfo'{'mt-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=MtSmsTdpList}}} ->
- NewMtSmsTdpList = patch_SmsCamelTDPDataList(MtSmsTdpList),
- VlrCamel3 = VlrCamel2#'VlrCamelSubscriptionInfo'{'mt-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=NewMtSmsTdpList}}};
- _ ->
- VlrCamel3 = VlrCamel2
- end,
- case VlrCamel3 of
- #'VlrCamelSubscriptionInfo'{'ss-CSI'={#'SS-CSI'{'ss-CamelData'=#'SS-CamelData'{'gsmSCF-Address'=SSgsmSCF}}}} ->
- VlrCamel4 = #'VlrCamelSubscriptionInfo'{'ss-CSI'={#'SS-CSI'{'ss-CamelData'=#'SS-CamelData'{'gsmSCF-Address'=?PATCH_GSMSCF_ADDRESS}}}};
- _ ->
- VlrCamel4 = VlrCamel3
- end,
- % return the VlrCamelSubscrInfo with replaced TdpList
- VlrCamel4;
- _ ->
- % return the original VlrCamelSubscrInfo without TdpList
- VlrCamel
- end.
-
-
-patch_sgsnCamelSubscrInfo(SgsnCamel) ->
- case SgsnCamel of
- asn1_NOVALUE ->
- % return the original (empty) SgsnCamelSubscrInfo
- SgsnCamel;
- #'SGSN-CAMEL-SubscriptionInfo'{} ->
- case SgsnCamel of #'SGSN-CAMEL-SubscriptionInfo'{'gprs-CSI'={#'GPRS-CSI'{'gprs-CamelTDPDataList'=GprsTdpList}}} ->
- NewGprsTdpList = patch_GprsCamelTDPDataList(GprsTdpList),
- SgsnCamel1 = SgsnCamel#'SGSN-CAMEL-SubscriptionInfo'{'gprs-CSI'={#'GPRS-CSI'{'gprs-CamelTDPDataList'=NewGprsTdpList}}};
- _ ->
- SgsnCamel1 = SgsnCamel
- end,
- case SgsnCamel1 of #'SGSN-CAMEL-SubscriptionInfo'{'mo-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=MoSmsTdpList}}} ->
- NewMoSmsTdpList = patch_SmsCamelTDPDataList(MoSmsTdpList),
- SgsnCamel2 = SgsnCamel1#'SGSN-CAMEL-SubscriptionInfo'{'mo-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=NewMoSmsTdpList}}};
- _ ->
- SgsnCamel2 = SgsnCamel1
- end,
- case SgsnCamel1 of #'SGSN-CAMEL-SubscriptionInfo'{'mt-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=MtSmsTdpList}}} ->
- NewMtSmsTdpList = patch_SmsCamelTDPDataList(MtSmsTdpList),
- SgsnCamel3 = SgsnCamel2#'SGSN-CAMEL-SubscriptionInfo'{'mt-sms-CSI'={#'SMS-CSI'{'sms-CAMEL-TDP-DataList'=NewMtSmsTdpList}}};
- _ ->
- SgsnCamel3 = SgsnCamel2
- end,
- SgsnCamel3;
- _ ->
- % return the original VlrCamelSubscrInfo without TdpList
- SgsnCamel
- end.
-
% process the Argument of a particular MAP invocation
process_component_arg(OpCode, Arg) ->
case Arg of
asn1_NOVALUE -> Arg;
- _ -> patch_UpdateGprsLocationArg(Arg)
+ _ -> patch(Arg)
end.
% recurse over all components